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.

329 {}

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.

348  {
349  amrex::Real rho = cons_arr(i,j,k,Rho_comp);
350  amrex::Real qv = cons_arr(i,j,k,RhoQ1_comp) / rho;
351 
352  // Volume-weighted average of x-face velocities to cell center
353  amrex::Real u_vfrac_sum = u_vfrac_arr(i,j,k) + u_vfrac_arr(i+1,j,k);
354  amrex::Real velx = (u_vfrac_sum > eps) ?
355  (velx_arr(i,j,k) * u_vfrac_arr(i,j,k) + velx_arr(i+1,j,k) * u_vfrac_arr(i+1,j,k))
356  / u_vfrac_sum : zero;
357 
358  // Volume-weighted average of y-face velocities to cell center
359  amrex::Real v_vfrac_sum = v_vfrac_arr(i,j,k) + v_vfrac_arr(i,j+1,k);
360  amrex::Real vely = (v_vfrac_sum > eps) ?
361  (vely_arr(i,j,k) * v_vfrac_arr(i,j,k) + vely_arr(i,j+1,k) * v_vfrac_arr(i,j+1,k))
362  / v_vfrac_sum : zero;
363 
364  amrex::Real qv_mean = qvm_arr(i,j,0);
365  amrex::Real ustar = u_star_arr(i,j,k);
366  amrex::Real qstar = q_star_arr(i,j,k);
367  amrex::Real qv_surf = q_surf_arr(i,j,k);
368  amrex::Real wsp_mean = umm_arr(i,j,0);
369  wsp_mean = std::max(wsp_mean, WSMIN);
370 
371  amrex::Real wsp = std::sqrt(velx*velx+vely*vely);
372  amrex::Real num1 = wsp * (qv_mean-qv_surf);
373  amrex::Real num2 = wsp_mean * (qv-qv_mean);
374 
375  // NOTE: this is rho*<Qv'w'> = -K dQvdz
376  amrex::Real moflux = (std::abs(qstar) > eps) ?
377  -rho*qstar*ustar*(num1+num2)/((qv_mean-qv_surf)*wsp_mean) : zero;
378 
379  return moflux;
380  }
#define Rho_comp
Definition: ERF_IndexDefines.H:53
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:66
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ ustar
Definition: ERF_SLM.H:28
@ qstar
Definition: ERF_SLM.H:30
@ rho
Definition: ERF_Kessler.H:25
@ qv
Definition: ERF_Kessler.H:31
const amrex::Real WSMIN
Definition: ERF_EBMOSTStress.H:871
const amrex::Real eps
Definition: ERF_EBMOSTStress.H:869

◆ 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.

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

◆ 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.

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

◆ 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.

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

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: