ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
moeng_flux_eb Struct Reference

EB implementation of the Moeng surface-flux formulation. More...

#include <ERF_EBMOSTStress.H>

Collaboration diagram for moeng_flux_eb:

Public Member Functions

 moeng_flux_eb ()
 Construct a Moeng EB flux functor. More...
 
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_q_flux (const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &qvm_arr, const amrex::Array4< const amrex::Real > &u_star_arr, const amrex::Array4< const amrex::Real > &q_star_arr, const amrex::Array4< const amrex::Real > &q_surf_arr, const amrex::Array4< const amrex::Real > &u_vfrac_arr, const amrex::Array4< const amrex::Real > &v_vfrac_arr) const
 Compute the EB moisture flux at a cell-centered cut-cell surface. More...
 
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_t_flux (const int &i, const int &j, const int &k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &velz_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &tm_arr, const amrex::Array4< const amrex::Real > &u_star_arr, const amrex::Array4< const amrex::Real > &t_star_arr, const amrex::Array4< const amrex::Real > &t_surf_arr, const amrex::Array4< const amrex::Real > &u_vfrac_arr, const amrex::Array4< const amrex::Real > &v_vfrac_arr, const amrex::Array4< const amrex::Real > &w_vfrac_arr, const amrex::Array4< const amrex::Real > &bnorm_arr) const
 Compute the EB temperature flux at a cell-centered cut-cell surface. More...
 
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_u_flux (int i, int j, int k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &velz_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &um_arr, const amrex::Array4< const amrex::Real > &u_star_arr, const amrex::Array4< const amrex::Real > &u_vfrac_arr, const amrex::Array4< const amrex::Real > &v_vfrac_arr, const amrex::Array4< const amrex::Real > &w_vfrac_arr, const amrex::Array4< const amrex::Real > &cc_vfrac_arr, const amrex::Array4< const amrex::EBCellFlag > &cc_flag_arr, const amrex::Array4< const amrex::Real > &bnorm_arr, int idir=0) const
 Compute the EB x-momentum stress on a staggered face. More...
 
AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real compute_v_flux (int i, int j, int k, const amrex::Array4< const amrex::Real > &cons_arr, const amrex::Array4< const amrex::Real > &velx_arr, const amrex::Array4< const amrex::Real > &vely_arr, const amrex::Array4< const amrex::Real > &velz_arr, const amrex::Array4< const amrex::Real > &umm_arr, const amrex::Array4< const amrex::Real > &vm_arr, const amrex::Array4< const amrex::Real > &u_star_arr, const amrex::Array4< const amrex::Real > &u_vfrac_arr, const amrex::Array4< const amrex::Real > &v_vfrac_arr, const amrex::Array4< const amrex::Real > &w_vfrac_arr, const amrex::Array4< const amrex::Real > &cc_vfrac_arr, const amrex::Array4< const amrex::EBCellFlag > &cc_flag_arr, const amrex::Array4< const amrex::Real > &bnorm_arr, int idir=0) const
 Compute the EB y-momentum stress on a staggered face. More...
 

Private Attributes

const amrex::Real eps = amrex::Real(1e-12)
 
const amrex::Real WSMIN = amrex::Real(0.1)
 

Detailed Description

EB implementation of the Moeng surface-flux formulation.

Constructor & Destructor Documentation

◆ moeng_flux_eb()

moeng_flux_eb::moeng_flux_eb ( )
inline

Construct a Moeng EB flux functor.

318 {}

Member Function Documentation

◆ compute_q_flux()

AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real moeng_flux_eb::compute_q_flux ( const int &  i,
const int &  j,
const int &  k,
const amrex::Array4< const amrex::Real > &  cons_arr,
const amrex::Array4< const amrex::Real > &  velx_arr,
const amrex::Array4< const amrex::Real > &  vely_arr,
const amrex::Array4< const amrex::Real > &  umm_arr,
const amrex::Array4< const amrex::Real > &  qvm_arr,
const amrex::Array4< const amrex::Real > &  u_star_arr,
const amrex::Array4< const amrex::Real > &  q_star_arr,
const amrex::Array4< const amrex::Real > &  q_surf_arr,
const amrex::Array4< const amrex::Real > &  u_vfrac_arr,
const amrex::Array4< const amrex::Real > &  v_vfrac_arr 
) const
inline

Compute the EB moisture flux at a cell-centered cut-cell surface.

337  {
338  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
339  amrex::Real qv = cons_arr(i,j,k,RhoQ1_comp) / rho;
340 
341  // Volume-weighted average of x-face velocities to cell center
342  amrex::Real u_vfrac_sum = u_vfrac_arr(i,j,k) + u_vfrac_arr(i+1,j,k);
343  amrex::Real velx = (u_vfrac_sum > eps) ?
344  (velx_arr(i,j,k) * u_vfrac_arr(i,j,k) + velx_arr(i+1,j,k) * u_vfrac_arr(i+1,j,k))
345  / u_vfrac_sum : zero;
346 
347  // Volume-weighted average of y-face velocities to cell center
348  amrex::Real v_vfrac_sum = v_vfrac_arr(i,j,k) + v_vfrac_arr(i,j+1,k);
349  amrex::Real vely = (v_vfrac_sum > eps) ?
350  (vely_arr(i,j,k) * v_vfrac_arr(i,j,k) + vely_arr(i,j+1,k) * v_vfrac_arr(i,j+1,k))
351  / v_vfrac_sum : zero;
352 
353  amrex::Real qv_mean = qvm_arr(i,j,0);
354  amrex::Real ustar = u_star_arr(i,j,k);
355  amrex::Real qstar = q_star_arr(i,j,k);
356  amrex::Real qv_surf = q_surf_arr(i,j,k);
357  amrex::Real wsp_mean = umm_arr(i,j,0);
358  wsp_mean = std::max(wsp_mean, WSMIN);
359 
360  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
361  amrex::Real num1 = wsp * (qv_mean-qv_surf);
362  amrex::Real num2 = wsp_mean * (qv-qv_mean);
363 
364  // NOTE: this is rho*<Qv'w'> = -K dQvdz
365  amrex::Real moflux = (std::abs(qstar) > eps) ?
366  -rho*qstar*ustar*(num1+num2)/((qv_mean-qv_surf)*wsp_mean) : zero;
367 
368  return moflux;
369  }
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
rho
Definition: ERF_InitCustomPert_Bubble.H:107
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ qv
Definition: ERF_Kessler.H:30
const amrex::Real WSMIN
Definition: ERF_EBMOSTStress.H:860
const amrex::Real eps
Definition: ERF_EBMOSTStress.H:858

◆ compute_t_flux()

AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real moeng_flux_eb::compute_t_flux ( const int &  i,
const int &  j,
const int &  k,
const amrex::Array4< const amrex::Real > &  cons_arr,
const amrex::Array4< const amrex::Real > &  velx_arr,
const amrex::Array4< const amrex::Real > &  vely_arr,
const amrex::Array4< const amrex::Real > &  velz_arr,
const amrex::Array4< const amrex::Real > &  umm_arr,
const amrex::Array4< const amrex::Real > &  tm_arr,
const amrex::Array4< const amrex::Real > &  u_star_arr,
const amrex::Array4< const amrex::Real > &  t_star_arr,
const amrex::Array4< const amrex::Real > &  t_surf_arr,
const amrex::Array4< const amrex::Real > &  u_vfrac_arr,
const amrex::Array4< const amrex::Real > &  v_vfrac_arr,
const amrex::Array4< const amrex::Real > &  w_vfrac_arr,
const amrex::Array4< const amrex::Real > &  bnorm_arr 
) const
inline

Compute the EB temperature flux at a cell-centered cut-cell surface.

391  {
392  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
393  amrex::Real theta = cons_arr(i,j,k,RhoTheta_comp) / rho;
394 
395  // Volume-weighted average of x-face velocities to cell center
396  amrex::Real u_vfrac_sum = u_vfrac_arr(i,j,k) + u_vfrac_arr(i+1,j,k);
397  amrex::Real velx = (u_vfrac_sum > eps) ?
398  (velx_arr(i,j,k) * u_vfrac_arr(i,j,k) + velx_arr(i+1,j,k) * u_vfrac_arr(i+1,j,k))
399  / u_vfrac_sum : zero;
400 
401  // Volume-weighted average of y-face velocities to cell center
402  amrex::Real v_vfrac_sum = v_vfrac_arr(i,j,k) + v_vfrac_arr(i,j+1,k);
403  amrex::Real vely = (v_vfrac_sum > eps) ?
404  (vely_arr(i,j,k) * v_vfrac_arr(i,j,k) + vely_arr(i,j+1,k) * v_vfrac_arr(i,j+1,k))
405  / v_vfrac_sum : zero;
406 
407  // Volume-weighted average of z-face velocities to cell center
408  amrex::Real w_vfrac_sum = w_vfrac_arr(i,j,k) + w_vfrac_arr(i,j,k+1);
409  amrex::Real velz = (w_vfrac_sum > eps) ?
410  (velz_arr(i,j,k) * w_vfrac_arr(i,j,k) + velz_arr(i,j,k+1) * w_vfrac_arr(i,j,k+1))
411  / w_vfrac_sum : zero;
412 
413  // Get boundary normal components
414  amrex::Real nx = bnorm_arr(i,j,k,0);
415  amrex::Real ny = bnorm_arr(i,j,k,1);
416  amrex::Real nz = bnorm_arr(i,j,k,2);
417 
418  // Project velocity onto tangent plane (remove normal component)
419  amrex::Real v_dot_n = velx*nx + vely*ny + velz*nz;
420  amrex::Real velx_tangent = velx - v_dot_n * nx;
421  amrex::Real vely_tangent = vely - v_dot_n * ny;
422 
423  amrex::Real theta_mean = tm_arr(i,j,0);
424  amrex::Real ustar = u_star_arr(i,j,k);
425  amrex::Real tstar = t_star_arr(i,j,k);
426  amrex::Real theta_surf = t_surf_arr(i,j,k);
427  amrex::Real wsp_mean = umm_arr(i,j,0);
428  wsp_mean = std::max(wsp_mean, WSMIN);
429 
430  // Use tangential velocity magnitude instead of Cartesian
431  amrex::Real wsp = std::sqrt(velx_tangent*velx_tangent+vely_tangent*vely_tangent);
432  amrex::Real num1 = wsp * (theta_mean-theta_surf);
433  amrex::Real num2 = wsp_mean * (theta-theta_mean);
434 
435  // NOTE: this is rho*<T'w'> = -K dTdz
436  amrex::Real moflux = (std::abs(tstar) > eps) ?
437  -rho*tstar*ustar*(num1+num2)/((theta_mean-theta_surf)*wsp_mean) : zero;
438 
439  return moflux;
440  }
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
@ theta
Definition: ERF_SLM.H:20

◆ compute_u_flux()

AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real moeng_flux_eb::compute_u_flux ( int  i,
int  j,
int  k,
const amrex::Array4< const amrex::Real > &  cons_arr,
const amrex::Array4< const amrex::Real > &  velx_arr,
const amrex::Array4< const amrex::Real > &  vely_arr,
const amrex::Array4< const amrex::Real > &  velz_arr,
const amrex::Array4< const amrex::Real > &  umm_arr,
const amrex::Array4< const amrex::Real > &  um_arr,
const amrex::Array4< const amrex::Real > &  u_star_arr,
const amrex::Array4< const amrex::Real > &  u_vfrac_arr,
const amrex::Array4< const amrex::Real > &  v_vfrac_arr,
const amrex::Array4< const amrex::Real > &  w_vfrac_arr,
const amrex::Array4< const amrex::Real > &  cc_vfrac_arr,
const amrex::Array4< const amrex::EBCellFlag > &  cc_flag_arr,
const amrex::Array4< const amrex::Real > &  bnorm_arr,
int  idir = 0 
) const
inline

Compute the EB x-momentum stress on a staggered face.

463  {
464  amrex::Real velx, vely, rho, ustar, wsp_mean;
465  amrex::Real velx_tangent, vely_tangent;
466 
467  if (idir == 0) {
468  // x-face: average to x-face
469  velx = velx_arr(i,j,k);
470 
471  // Volume-weighted average of y-face velocities to x-face
472  amrex::Real v_vfrac_sum = v_vfrac_arr(i,j,k) + v_vfrac_arr(i,j+1,k) +
473  v_vfrac_arr(i-1,j,k) + v_vfrac_arr(i-1,j+1,k);
474  vely = (v_vfrac_sum > eps) ?
475  (vely_arr(i,j,k) * v_vfrac_arr(i,j,k) + vely_arr(i,j+1,k) * v_vfrac_arr(i,j+1,k) +
476  vely_arr(i-1,j,k) * v_vfrac_arr(i-1,j,k) + vely_arr(i-1,j+1,k) * v_vfrac_arr(i-1,j+1,k))
477  / v_vfrac_sum : zero;
478 
479  // Volume-weighted average of z-face velocities to x-face
480  amrex::Real w_vfrac_sum = w_vfrac_arr(i,j,k) + w_vfrac_arr(i,j,k+1) +
481  w_vfrac_arr(i-1,j,k) + w_vfrac_arr(i-1,j,k+1);
482  amrex::Real velz = (w_vfrac_sum > eps) ?
483  (velz_arr(i,j,k) * w_vfrac_arr(i,j,k) + velz_arr(i,j,k+1) * w_vfrac_arr(i,j,k+1) +
484  velz_arr(i-1,j,k) * w_vfrac_arr(i-1,j,k) + velz_arr(i-1,j,k+1) * w_vfrac_arr(i-1,j,k+1))
485  / w_vfrac_sum : zero;
486 
487  // Get boundary normal at x-face (already at correct staggered location)
488  amrex::Real nx = bnorm_arr(i,j,k,0);
489  amrex::Real ny = bnorm_arr(i,j,k,1);
490  amrex::Real nz = bnorm_arr(i,j,k,2);
491 
492  // Project velocity onto tangent plane
493  amrex::Real v_dot_n = velx*nx + vely*ny + velz*nz;
494  velx_tangent = velx - v_dot_n * nx;
495  vely_tangent = vely - v_dot_n * ny;
496 
497  // Volume-weighted average of cell-centered density to x-face
498  amrex::Real cc_vfrac_sum = cc_vfrac_arr(i-1,j,k) + cc_vfrac_arr(i,j,k);
499  rho = (cc_vfrac_sum > eps) ?
500  (cons_arr(i-1,j,k,Rho_comp) * cc_vfrac_arr(i-1,j,k) + cons_arr(i,j,k,Rho_comp) * cc_vfrac_arr(i,j,k))
501  / cc_vfrac_sum : zero;
502 
503  // Average cell-centered u_star and wsp_mean to x-face, using only valid (SingleValued) cells
504  bool low_valid = cc_flag_arr(i-1,j,k).isSingleValued();
505  bool high_valid = cc_flag_arr(i,j,k).isSingleValued();
506 
507  if (low_valid && high_valid) {
508  ustar = myhalf * (u_star_arr(i-1,j,k) + u_star_arr(i,j,k));
509  wsp_mean = myhalf * (umm_arr(i-1,j,0) + umm_arr(i,j,0));
510  } else if (low_valid) {
511  ustar = u_star_arr(i-1,j,k);
512  wsp_mean = umm_arr(i-1,j,0);
513  } else if (high_valid) {
514  ustar = u_star_arr(i,j,k);
515  wsp_mean = umm_arr(i,j,0);
516  } else {
517  ustar = zero;
518  wsp_mean = WSMIN;
519  }
520 
521  } else if (idir == 1) {
522  // y-face: average to y-face
523  vely = vely_arr(i,j,k);
524 
525  // Volume-weighted average of x-face velocities to y-face
526  amrex::Real u_vfrac_sum = u_vfrac_arr(i,j,k) + u_vfrac_arr(i+1,j,k) +
527  u_vfrac_arr(i,j-1,k) + u_vfrac_arr(i+1,j-1,k);
528  velx = (u_vfrac_sum > eps) ?
529  (velx_arr(i,j,k) * u_vfrac_arr(i,j,k) + velx_arr(i+1,j,k) * u_vfrac_arr(i+1,j,k) +
530  velx_arr(i,j-1,k) * u_vfrac_arr(i,j-1,k) + velx_arr(i+1,j-1,k) * u_vfrac_arr(i+1,j-1,k))
531  / u_vfrac_sum : zero;
532 
533  // Volume-weighted average of z-face velocities to y-face
534  amrex::Real w_vfrac_sum = w_vfrac_arr(i,j,k) + w_vfrac_arr(i,j,k+1) +
535  w_vfrac_arr(i,j-1,k) + w_vfrac_arr(i,j-1,k+1);
536  amrex::Real velz = (w_vfrac_sum > eps) ?
537  (velz_arr(i,j,k) * w_vfrac_arr(i,j,k) + velz_arr(i,j,k+1) * w_vfrac_arr(i,j,k+1) +
538  velz_arr(i,j-1,k) * w_vfrac_arr(i,j-1,k) + velz_arr(i,j-1,k+1) * w_vfrac_arr(i,j-1,k+1))
539  / w_vfrac_sum : zero;
540 
541  // Get boundary normal at y-face (already at correct staggered location)
542  amrex::Real nx = bnorm_arr(i,j,k,0);
543  amrex::Real ny = bnorm_arr(i,j,k,1);
544  amrex::Real nz = bnorm_arr(i,j,k,2);
545 
546  // Project velocity onto tangent plane
547  amrex::Real v_dot_n = velx*nx + vely*ny + velz*nz;
548  velx_tangent = velx - v_dot_n * nx;
549  vely_tangent = vely - v_dot_n * ny;
550 
551  // Volume-weighted average of cell-centered density to y-face
552  amrex::Real cc_vfrac_sum = cc_vfrac_arr(i,j-1,k) + cc_vfrac_arr(i,j,k);
553  rho = (cc_vfrac_sum > eps) ?
554  (cons_arr(i,j-1,k,Rho_comp) * cc_vfrac_arr(i,j-1,k) + cons_arr(i,j,k,Rho_comp) * cc_vfrac_arr(i,j,k))
555  / cc_vfrac_sum : zero;
556 
557  // Average cell-centered u_star and wsp_mean to y-face, using only valid (SingleValued) cells
558  bool low_valid = cc_flag_arr(i,j-1,k).isSingleValued();
559  bool high_valid = cc_flag_arr(i,j,k).isSingleValued();
560 
561  if (low_valid && high_valid) {
562  ustar = myhalf * (u_star_arr(i,j-1,k) + u_star_arr(i,j,k));
563  wsp_mean = myhalf * (umm_arr(i,j-1,0) + umm_arr(i,j,0));
564  } else if (low_valid) {
565  ustar = u_star_arr(i,j-1,k);
566  wsp_mean = umm_arr(i,j-1,0);
567  } else if (high_valid) {
568  ustar = u_star_arr(i,j,k);
569  wsp_mean = umm_arr(i,j,0);
570  } else {
571  ustar = zero;
572  wsp_mean = WSMIN;
573  }
574 
575  } else {
576  // z-face: average to z-face
577  // Volume-weighted average of x-face velocities to z-face
578  amrex::Real u_vfrac_sum = u_vfrac_arr(i,j,k-1) + u_vfrac_arr(i+1,j,k-1) +
579  u_vfrac_arr(i,j,k) + u_vfrac_arr(i+1,j,k);
580  velx = (u_vfrac_sum > eps) ?
581  (velx_arr(i,j,k-1) * u_vfrac_arr(i,j,k-1) + velx_arr(i+1,j,k-1) * u_vfrac_arr(i+1,j,k-1) +
582  velx_arr(i,j,k) * u_vfrac_arr(i,j,k) + velx_arr(i+1,j,k) * u_vfrac_arr(i+1,j,k))
583  / u_vfrac_sum : zero;
584 
585  // Volume-weighted average of y-face velocities to z-face
586  amrex::Real v_vfrac_sum = v_vfrac_arr(i,j,k-1) + v_vfrac_arr(i,j+1,k-1) +
587  v_vfrac_arr(i,j,k) + v_vfrac_arr(i,j+1,k);
588  vely = (v_vfrac_sum > eps) ?
589  (vely_arr(i,j,k-1) * v_vfrac_arr(i,j,k-1) + vely_arr(i,j+1,k-1) * v_vfrac_arr(i,j+1,k-1) +
590  vely_arr(i,j,k) * v_vfrac_arr(i,j,k) + vely_arr(i,j+1,k) * v_vfrac_arr(i,j+1,k))
591  / v_vfrac_sum : zero;
592 
593  // z-velocity is already at z-face
594  amrex::Real velz = velz_arr(i,j,k);
595 
596  // Get boundary normal at z-face (already at correct staggered location)
597  amrex::Real nx = bnorm_arr(i,j,k,0);
598  amrex::Real ny = bnorm_arr(i,j,k,1);
599  amrex::Real nz = bnorm_arr(i,j,k,2);
600 
601  // Project velocity onto tangent plane
602  amrex::Real v_dot_n = velx*nx + vely*ny + velz*nz;
603  velx_tangent = velx - v_dot_n * nx;
604  vely_tangent = vely - v_dot_n * ny;
605 
606  // Volume-weighted average of cell-centered density to z-face
607  amrex::Real cc_vfrac_sum = cc_vfrac_arr(i,j,k-1) + cc_vfrac_arr(i,j,k);
608  rho = (cc_vfrac_sum > eps) ?
609  (cons_arr(i,j,k-1,Rho_comp) * cc_vfrac_arr(i,j,k-1) + cons_arr(i,j,k,Rho_comp) * cc_vfrac_arr(i,j,k))
610  / cc_vfrac_sum : zero;
611 
612  // Average cell-centered u_star and wsp_mean to z-face, using only valid (SingleValued) cells
613  bool low_valid = cc_flag_arr(i,j,k-1).isSingleValued();
614  bool high_valid = cc_flag_arr(i,j,k).isSingleValued();
615 
616  if (low_valid && high_valid) {
617  ustar = myhalf * (u_star_arr(i,j,k-1) + u_star_arr(i,j,k));
618  wsp_mean = myhalf * (umm_arr(i,j,0) + umm_arr(i,j,0));
619  } else if (low_valid) {
620  ustar = u_star_arr(i,j,k-1);
621  wsp_mean = umm_arr(i,j,0);
622  } else if (high_valid) {
623  ustar = u_star_arr(i,j,k);
624  wsp_mean = umm_arr(i,j,0);
625  } else {
626  ustar = zero;
627  wsp_mean = WSMIN;
628  }
629  }
630 
631  wsp_mean = std::max(wsp_mean, WSMIN);
632  amrex::Real umean = um_arr(i,j,0);
633 
634  // Note: The surface mean shear stress is decomposed into tau_xz by
635  // multiplying the modeled shear stress (rho*ustar^2) with
636  // a factor of umean/wsp_mean for directionality; this factor
637  // modifies the denominator from what is in Moeng amrex::Real(1984.)
638  amrex::Real wsp = std::sqrt(velx_tangent*velx_tangent+vely_tangent*vely_tangent);
639  amrex::Real num1 = wsp * umean;
640  amrex::Real num2 = wsp_mean * (velx_tangent-umean);
641 
642  // NOTE: this is rho*<u'w'> = -K dudz
643  amrex::Real stressx = -rho*ustar*ustar * (num1+num2)/(wsp_mean*wsp_mean);
644 
645  return stressx;
646  }
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13

◆ compute_v_flux()

AMREX_GPU_DEVICE AMREX_FORCE_INLINE amrex::Real moeng_flux_eb::compute_v_flux ( int  i,
int  j,
int  k,
const amrex::Array4< const amrex::Real > &  cons_arr,
const amrex::Array4< const amrex::Real > &  velx_arr,
const amrex::Array4< const amrex::Real > &  vely_arr,
const amrex::Array4< const amrex::Real > &  velz_arr,
const amrex::Array4< const amrex::Real > &  umm_arr,
const amrex::Array4< const amrex::Real > &  vm_arr,
const amrex::Array4< const amrex::Real > &  u_star_arr,
const amrex::Array4< const amrex::Real > &  u_vfrac_arr,
const amrex::Array4< const amrex::Real > &  v_vfrac_arr,
const amrex::Array4< const amrex::Real > &  w_vfrac_arr,
const amrex::Array4< const amrex::Real > &  cc_vfrac_arr,
const amrex::Array4< const amrex::EBCellFlag > &  cc_flag_arr,
const amrex::Array4< const amrex::Real > &  bnorm_arr,
int  idir = 0 
) const
inline

Compute the EB y-momentum stress on a staggered face.

669  {
670  amrex::Real velx, vely, rho, ustar, wsp_mean;
671  amrex::Real velx_tangent, vely_tangent;
672 
673  if (idir == 0) {
674  // x-face: average from cells (i-1) and (i)
675  // Volume-weighted average of y-face velocities to x-face
676  amrex::Real v_vfrac_sum = v_vfrac_arr(i,j,k) + v_vfrac_arr(i,j+1,k) +
677  v_vfrac_arr(i-1,j,k) + v_vfrac_arr(i-1,j+1,k);
678  vely = (v_vfrac_sum > eps) ?
679  (vely_arr(i,j,k) * v_vfrac_arr(i,j,k) + vely_arr(i,j+1,k) * v_vfrac_arr(i,j+1,k) +
680  vely_arr(i-1,j,k) * v_vfrac_arr(i-1,j,k) + vely_arr(i-1,j+1,k) * v_vfrac_arr(i-1,j+1,k))
681  / v_vfrac_sum : zero;
682 
683  velx = velx_arr(i,j,k);
684 
685  // Volume-weighted average of z-face velocities to x-face
686  amrex::Real w_vfrac_sum = w_vfrac_arr(i,j,k) + w_vfrac_arr(i,j,k+1) +
687  w_vfrac_arr(i-1,j,k) + w_vfrac_arr(i-1,j,k+1);
688  amrex::Real velz = (w_vfrac_sum > eps) ?
689  (velz_arr(i,j,k) * w_vfrac_arr(i,j,k) + velz_arr(i,j,k+1) * w_vfrac_arr(i,j,k+1) +
690  velz_arr(i-1,j,k) * w_vfrac_arr(i-1,j,k) + velz_arr(i-1,j,k+1) * w_vfrac_arr(i-1,j,k+1))
691  / w_vfrac_sum : zero;
692 
693  // Get boundary normal at x-face (already at correct staggered location)
694  amrex::Real nx = bnorm_arr(i,j,k,0);
695  amrex::Real ny = bnorm_arr(i,j,k,1);
696  amrex::Real nz = bnorm_arr(i,j,k,2);
697 
698  // Project velocity onto tangent plane
699  amrex::Real v_dot_n = velx*nx + vely*ny + velz*nz;
700  velx_tangent = velx - v_dot_n * nx;
701  vely_tangent = vely - v_dot_n * ny;
702 
703  // Volume-weighted average of cell-centered density to x-face
704  amrex::Real cc_vfrac_sum = cc_vfrac_arr(i-1,j,k) + cc_vfrac_arr(i,j,k);
705  rho = (cc_vfrac_sum > eps) ?
706  (cons_arr(i-1,j,k,Rho_comp) * cc_vfrac_arr(i-1,j,k) + cons_arr(i,j,k,Rho_comp) * cc_vfrac_arr(i,j,k))
707  / cc_vfrac_sum : zero;
708 
709  // Average cell-centered u_star and wsp_mean to x-face, using only valid (SingleValued) cells
710  bool low_valid = cc_flag_arr(i-1,j,k).isSingleValued();
711  bool high_valid = cc_flag_arr(i,j,k).isSingleValued();
712 
713  if (low_valid && high_valid) {
714  ustar = myhalf * (u_star_arr(i-1,j,k) + u_star_arr(i,j,k));
715  wsp_mean = myhalf * (umm_arr(i-1,j,0) + umm_arr(i,j,0));
716  } else if (low_valid) {
717  ustar = u_star_arr(i-1,j,k);
718  wsp_mean = umm_arr(i-1,j,0);
719  } else if (high_valid) {
720  ustar = u_star_arr(i,j,k);
721  wsp_mean = umm_arr(i,j,0);
722  } else {
723  ustar = zero;
724  wsp_mean = WSMIN;
725  }
726 
727  } else if (idir == 1) {
728  // y-face: average from cells (j-1) and (j)
729  // Volume-weighted average of x-face velocities to y-face
730  amrex::Real u_vfrac_sum = u_vfrac_arr(i,j,k) + u_vfrac_arr(i+1,j,k) +
731  u_vfrac_arr(i,j-1,k) + u_vfrac_arr(i+1,j-1,k);
732  velx = (u_vfrac_sum > eps) ?
733  (velx_arr(i,j,k) * u_vfrac_arr(i,j,k) + velx_arr(i+1,j,k) * u_vfrac_arr(i+1,j,k) +
734  velx_arr(i,j-1,k) * u_vfrac_arr(i,j-1,k) + velx_arr(i+1,j-1,k) * u_vfrac_arr(i+1,j-1,k))
735  / u_vfrac_sum : zero;
736 
737  vely = vely_arr(i,j,k);
738 
739  // Volume-weighted average of z-face velocities to y-face
740  amrex::Real w_vfrac_sum = w_vfrac_arr(i,j,k) + w_vfrac_arr(i,j,k+1) +
741  w_vfrac_arr(i,j-1,k) + w_vfrac_arr(i,j-1,k+1);
742  amrex::Real velz = (w_vfrac_sum > eps) ?
743  (velz_arr(i,j,k) * w_vfrac_arr(i,j,k) + velz_arr(i,j,k+1) * w_vfrac_arr(i,j,k+1) +
744  velz_arr(i,j-1,k) * w_vfrac_arr(i,j-1,k) + velz_arr(i,j-1,k+1) * w_vfrac_arr(i,j-1,k+1))
745  / w_vfrac_sum : zero;
746 
747  // Get boundary normal at y-face (already at correct staggered location)
748  amrex::Real nx = bnorm_arr(i,j,k,0);
749  amrex::Real ny = bnorm_arr(i,j,k,1);
750  amrex::Real nz = bnorm_arr(i,j,k,2);
751 
752  // Project velocity onto tangent plane
753  amrex::Real v_dot_n = velx*nx + vely*ny + velz*nz;
754  velx_tangent = velx - v_dot_n * nx;
755  vely_tangent = vely - v_dot_n * ny;
756 
757  // Volume-weighted average of cell-centered density to y-face
758  amrex::Real cc_vfrac_sum = cc_vfrac_arr(i,j-1,k) + cc_vfrac_arr(i,j,k);
759  rho = (cc_vfrac_sum > eps) ?
760  (cons_arr(i,j-1,k,Rho_comp) * cc_vfrac_arr(i,j-1,k) + cons_arr(i,j,k,Rho_comp) * cc_vfrac_arr(i,j,k))
761  / cc_vfrac_sum : zero;
762 
763  // Average cell-centered u_star and wsp_mean to y-face, using only valid (SingleValued) cells
764  bool low_valid = cc_flag_arr(i,j-1,k).isSingleValued();
765  bool high_valid = cc_flag_arr(i,j,k).isSingleValued();
766 
767  if (low_valid && high_valid) {
768  ustar = myhalf * (u_star_arr(i,j-1,k) + u_star_arr(i,j,k));
769  wsp_mean = myhalf * (umm_arr(i,j-1,0) + umm_arr(i,j,0));
770  } else if (low_valid) {
771  ustar = u_star_arr(i,j-1,k);
772  wsp_mean = umm_arr(i,j-1,0);
773  } else if (high_valid) {
774  ustar = u_star_arr(i,j,k);
775  wsp_mean = umm_arr(i,j,0);
776  } else {
777  ustar = zero;
778  wsp_mean = WSMIN;
779  }
780 
781  } else {
782  // z-face: average from cells (k-1) and (k)
783  // Volume-weighted average of x-face velocities to z-face
784  amrex::Real u_vfrac_sum = u_vfrac_arr(i,j,k-1) + u_vfrac_arr(i+1,j,k-1) +
785  u_vfrac_arr(i,j,k) + u_vfrac_arr(i+1,j,k);
786  velx = (u_vfrac_sum > eps) ?
787  (velx_arr(i,j,k-1) * u_vfrac_arr(i,j,k-1) + velx_arr(i+1,j,k-1) * u_vfrac_arr(i+1,j,k-1) +
788  velx_arr(i,j,k) * u_vfrac_arr(i,j,k) + velx_arr(i+1,j,k) * u_vfrac_arr(i+1,j,k))
789  / u_vfrac_sum : zero;
790 
791  // Volume-weighted average of y-face velocities to z-face
792  amrex::Real v_vfrac_sum = v_vfrac_arr(i,j,k-1) + v_vfrac_arr(i,j+1,k-1) +
793  v_vfrac_arr(i,j,k) + v_vfrac_arr(i,j+1,k);
794  vely = (v_vfrac_sum > eps) ?
795  (vely_arr(i,j,k-1) * v_vfrac_arr(i,j,k-1) + vely_arr(i,j+1,k-1) * v_vfrac_arr(i,j+1,k-1) +
796  vely_arr(i,j,k) * v_vfrac_arr(i,j,k) + vely_arr(i,j+1,k) * v_vfrac_arr(i,j+1,k))
797  / v_vfrac_sum : zero;
798 
799  // z-velocity is already at z-face
800  amrex::Real velz = velz_arr(i,j,k);
801 
802  // Get boundary normal at z-face (already at correct staggered location)
803  amrex::Real nx = bnorm_arr(i,j,k,0);
804  amrex::Real ny = bnorm_arr(i,j,k,1);
805  amrex::Real nz = bnorm_arr(i,j,k,2);
806 
807  // Project velocity onto tangent plane
808  amrex::Real v_dot_n = velx*nx + vely*ny + velz*nz;
809  velx_tangent = velx - v_dot_n * nx;
810  vely_tangent = vely - v_dot_n * ny;
811 
812  // Volume-weighted average of cell-centered density to z-face
813  amrex::Real cc_vfrac_sum = cc_vfrac_arr(i,j,k-1) + cc_vfrac_arr(i,j,k);
814  rho = (cc_vfrac_sum > eps) ?
815  (cons_arr(i,j,k-1,Rho_comp) * cc_vfrac_arr(i,j,k-1) + cons_arr(i,j,k,Rho_comp) * cc_vfrac_arr(i,j,k))
816  / cc_vfrac_sum : zero;
817 
818  // Average cell-centered u_star and wsp_mean to z-face, using only valid (SingleValued) cells
819  bool low_valid = cc_flag_arr(i,j,k-1).isSingleValued();
820  bool high_valid = cc_flag_arr(i,j,k).isSingleValued();
821 
822  if (low_valid && high_valid) {
823  ustar = myhalf * (u_star_arr(i,j,k-1) + u_star_arr(i,j,k));
824  wsp_mean = myhalf * (umm_arr(i,j,0) + umm_arr(i,j,0));
825  } else if (low_valid) {
826  ustar = u_star_arr(i,j,k-1);
827  wsp_mean = umm_arr(i,j,0);
828  } else if (high_valid) {
829  ustar = u_star_arr(i,j,k);
830  wsp_mean = umm_arr(i,j,0);
831  } else {
832  ustar = zero;
833  wsp_mean = WSMIN;
834  }
835  }
836 
837  wsp_mean = std::max(wsp_mean, WSMIN);
838  amrex::Real vmean = vm_arr(i,j,0);
839 
840  // Note: The surface mean shear stress is decomposed into tau_yz by
841  // multiplying the modeled shear stress (rho*ustar^2) with
842  // a factor of vmean/wsp_mean for directionality; this factor
843  // modifies the denominator from what is in Moeng amrex::Real(1984.)
844  amrex::Real wsp = std::sqrt(velx_tangent*velx_tangent+vely_tangent*vely_tangent);
845  amrex::Real num1 = wsp * vmean;
846  amrex::Real num2 = wsp_mean * (vely_tangent-vmean);
847 
848  // NOTE: this is rho*<v'w'> = -K dvdz
849  amrex::Real stressy = -rho*ustar*ustar * (num1+num2)/(wsp_mean*wsp_mean);
850 
851  return stressy;
852  }

Member Data Documentation

◆ eps

const amrex::Real moeng_flux_eb::eps = amrex::Real(1e-12)
private

◆ WSMIN

const amrex::Real moeng_flux_eb::WSMIN = amrex::Real(0.1)
private

The documentation for this struct was generated from the following file: