ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_EBAdvectionSrcForState.cpp File Reference
Include dependency graph for ERF_EBAdvectionSrcForState.cpp:

Functions

void EBAdvectionSrcForScalars (const Box &bx, const int icomp, const int ncomp, const Array4< const Real > &avg_xmom, const Array4< const Real > &avg_ymom, const Array4< const Real > &avg_zmom, const Array4< const Real > &cell_prim, const Array4< Real > &advectionSrc, const Array4< const EBCellFlag > &cfg_arr, const Array4< const Real > &ax_arr, const Array4< const Real > &ay_arr, const Array4< const Real > &az_arr, const Array4< const Real > &detJ, const GpuArray< Real, AMREX_SPACEDIM > &cellSizeInv, const Array4< const Real > &mf_m, const AdvType horiz_adv_type, const AdvType vert_adv_type, const Real horiz_upw_frac, const Real vert_upw_frac, const GpuArray< const Array4< Real >, AMREX_SPACEDIM > &flx_arr, const Box &domain, const BCRec *bc_ptr_h)
 

Function Documentation

◆ EBAdvectionSrcForScalars()

void EBAdvectionSrcForScalars ( const Box &  bx,
const int  icomp,
const int  ncomp,
const Array4< const Real > &  avg_xmom,
const Array4< const Real > &  avg_ymom,
const Array4< const Real > &  avg_zmom,
const Array4< const Real > &  cell_prim,
const Array4< Real > &  advectionSrc,
const Array4< const EBCellFlag > &  cfg_arr,
const Array4< const Real > &  ax_arr,
const Array4< const Real > &  ay_arr,
const Array4< const Real > &  az_arr,
const Array4< const Real > &  detJ,
const GpuArray< Real, AMREX_SPACEDIM > &  cellSizeInv,
const Array4< const Real > &  mf_m,
const AdvType  horiz_adv_type,
const AdvType  vert_adv_type,
const Real  horiz_upw_frac,
const Real  vert_upw_frac,
const GpuArray< const Array4< Real >, AMREX_SPACEDIM > &  flx_arr,
const Box &  domain,
const BCRec *  bc_ptr_h 
)

Function for computing the advective tendency for scalars when terrain_type is EB.

Parameters
[in]bxbox over which the scalars are updated if no external boundary conditions
[in]icompcomponent of first scalar to be updated
[in]ncompnumber of components to be updated
[in]avg_xmomx-component of time-averaged momentum defined in this routine
[in]avg_ymomy-component of time-averaged momentum defined in this routine
[in]avg_zmomz-component of time-averaged momentum defined in this routine
[in]cell_primprimitive form of scalar variables, here only potential temperature theta
[out]advectionSrctendency for the scalar update equation
[in]detJJacobian of the metric transformation (= 1 if use_terrain is false)
[in]cellSizeInvinverse of the mesh spacing
[in]mf_mmap factor at cell centers
[in]horiz_adv_typeadvection scheme to be used in horiz. directions for dry scalars
[in]vert_adv_typeadvection scheme to be used in vert. directions for dry scalars
[in]horiz_upw_fracupwinding fraction to be used in horiz. directions for dry scalars (for Blended schemes only)
[in]vert_upw_fracupwinding fraction to be used in vert. directions for dry scalars (for Blended schemes only)
53 {
54  BL_PROFILE_VAR("EBAdvectionSrcForScalars", EBAdvectionSrcForScalars);
55  auto dxInv = cellSizeInv[0], dyInv = cellSizeInv[1], dzInv = cellSizeInv[2];
56 
57  const Box xbx = surroundingNodes(bx,0);
58  const Box ybx = surroundingNodes(bx,1);
59  const Box zbx = surroundingNodes(bx,2);
60 
61  // Open bc will be imposed upon all vars (we only access cons here for simplicity)
62  const bool xlo_open = (bc_ptr_h[BCVars::cons_bc].lo(0) == ERFBCType::open);
63  const bool xhi_open = (bc_ptr_h[BCVars::cons_bc].hi(0) == ERFBCType::open);
64  const bool ylo_open = (bc_ptr_h[BCVars::cons_bc].lo(1) == ERFBCType::open);
65  const bool yhi_open = (bc_ptr_h[BCVars::cons_bc].hi(1) == ERFBCType::open);
66 
67  // Only advection operations in bndry normal direction with OPEN BC
68  Box bx_xlo, bx_xhi, bx_ylo, bx_yhi;
69  if (xlo_open) {
70  if ( bx.smallEnd(0) == domain.smallEnd(0)) { bx_xlo = makeSlab( bx,0,domain.smallEnd(0));}
71  }
72  if (xhi_open) {
73  if ( bx.bigEnd(0) == domain.bigEnd(0)) { bx_xhi = makeSlab( bx,0,domain.bigEnd(0) );}
74  }
75  if (ylo_open) {
76  if ( bx.smallEnd(1) == domain.smallEnd(1)) { bx_ylo = makeSlab( bx,1,domain.smallEnd(1));}
77  }
78  if (yhi_open) {
79  if ( bx.bigEnd(1) == domain.bigEnd(1)) { bx_yhi = makeSlab( bx,1,domain.bigEnd(1) );}
80  }
81 
82  // Inline with 2nd order for efficiency
83  // NOTE: we don't need to weight avg_xmom, avg_ymom, avg_zmom with terrain metrics
84  // (or with EB area fractions)
85  // because that was done when they were constructed in AdvectionSrcForRhoAndTheta
86  if (horiz_adv_type == AdvType::Centered_2nd && vert_adv_type == AdvType::Centered_2nd)
87  {
88  ParallelFor(xbx, ncomp,[=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept
89  {
90  const int cons_index = icomp + n;
91  const int prim_index = cons_index - 1;
92  const Real prim_on_face = 0.5 * (cell_prim(i,j,k,prim_index) + cell_prim(i-1,j,k,prim_index));
93  (flx_arr[0])(i,j,k,cons_index) = avg_xmom(i,j,k) * prim_on_face;
94  });
95  ParallelFor(ybx, ncomp,[=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept
96  {
97  const int cons_index = icomp + n;
98  const int prim_index = cons_index - 1;
99  const Real prim_on_face = 0.5 * (cell_prim(i,j,k,prim_index) + cell_prim(i,j-1,k,prim_index));
100  (flx_arr[1])(i,j,k,cons_index) = avg_ymom(i,j,k) * prim_on_face;
101  });
102  ParallelFor(zbx, ncomp,[=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept
103  {
104  const int cons_index = icomp + n;
105  const int prim_index = cons_index - 1;
106  const Real prim_on_face = 0.5 * (cell_prim(i,j,k,prim_index) + cell_prim(i,j,k-1,prim_index));
107  (flx_arr[2])(i,j,k,cons_index) = avg_zmom(i,j,k) * prim_on_face;
108  });
109 
110  // Template higher order methods (horizontal first)
111  } else {
112  switch(horiz_adv_type) {
114  EBAdvectionSrcForScalarsVert<CENTERED2>(bx, ncomp, icomp, flx_arr, cell_prim,
115  avg_xmom, avg_ymom, avg_zmom, cfg_arr, ax_arr, ay_arr, az_arr,
116  horiz_upw_frac, vert_upw_frac, vert_adv_type);
117  break;
118  case AdvType::Upwind_3rd:
119  EBAdvectionSrcForScalarsVert<UPWIND3>(bx, ncomp, icomp, flx_arr, cell_prim,
120  avg_xmom, avg_ymom, avg_zmom, cfg_arr, ax_arr, ay_arr, az_arr,
121  horiz_upw_frac, vert_upw_frac, vert_adv_type);
122  break;
124  EBAdvectionSrcForScalarsVert<CENTERED4>(bx, ncomp, icomp, flx_arr, cell_prim,
125  avg_xmom, avg_ymom, avg_zmom, cfg_arr, ax_arr, ay_arr, az_arr,
126  horiz_upw_frac, vert_upw_frac, vert_adv_type);
127  break;
128  case AdvType::Upwind_5th:
129  EBAdvectionSrcForScalarsVert<UPWIND5>(bx, ncomp, icomp, flx_arr, cell_prim,
130  avg_xmom, avg_ymom, avg_zmom, cfg_arr, ax_arr, ay_arr, az_arr,
131  horiz_upw_frac, vert_upw_frac, vert_adv_type);
132  break;
134  EBAdvectionSrcForScalarsVert<CENTERED6>(bx, ncomp, icomp, flx_arr, cell_prim,
135  avg_xmom, avg_ymom, avg_zmom, cfg_arr, ax_arr, ay_arr, az_arr,
136  horiz_upw_frac, vert_upw_frac, vert_adv_type);
137  break;
138  default:
139  AMREX_ASSERT_WITH_MESSAGE(false, "Unknown advection scheme! WENO is currently not supported for EB.");
140  }
141  }
142 
143  ParallelFor(bx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept
144  {
145  const int cons_index = icomp + n;
146  if (detJ(i,j,k) > 0.)
147  {
148  Real invdetJ = 1.0 / detJ(i,j,k);
149  Real mfsq = mf_m(i,j,0) * mf_m(i,j,0);
150 
151  advectionSrc(i,j,k,cons_index) = - invdetJ * mfsq * (
152  ( (flx_arr[0])(i+1,j,k,cons_index) - (flx_arr[0])(i ,j,k,cons_index) ) * dxInv +
153  ( (flx_arr[1])(i,j+1,k,cons_index) - (flx_arr[1])(i,j ,k,cons_index) ) * dyInv +
154  ( (flx_arr[2])(i,j,k+1,cons_index) - (flx_arr[2])(i,j,k ,cons_index) ) * dzInv );
155  } else {
156  advectionSrc(i,j,k,cons_index) = 0.;
157  }
158  });
159 
160  // Special advection operator for open BC (bndry tangent operations)
161  if (xlo_open) {
162  bool do_lo = true;
163  AdvectionSrcForOpenBC_Tangent_Cons(bx_xlo, 0, icomp, ncomp, advectionSrc, cell_prim,
164  avg_xmom, avg_ymom, avg_zmom,
165  detJ, cellSizeInv, do_lo);
166  }
167  if (xhi_open) {
168  AdvectionSrcForOpenBC_Tangent_Cons(bx_xhi, 0, icomp, ncomp, advectionSrc, cell_prim,
169  avg_xmom, avg_ymom, avg_zmom,
170  detJ, cellSizeInv);
171  }
172  if (ylo_open) {
173  bool do_lo = true;
174  AdvectionSrcForOpenBC_Tangent_Cons(bx_ylo, 1, icomp, ncomp, advectionSrc, cell_prim,
175  avg_xmom, avg_ymom, avg_zmom,
176  detJ, cellSizeInv, do_lo);
177  }
178  if (yhi_open) {
179  AdvectionSrcForOpenBC_Tangent_Cons(bx_yhi, 1, icomp, ncomp, advectionSrc, cell_prim,
180  avg_xmom, avg_ymom, avg_zmom,
181  detJ, cellSizeInv);
182  }
183 }
void AdvectionSrcForOpenBC_Tangent_Cons(const amrex::Box &bx, const int &dir, const int &icomp, const int &ncomp, const amrex::Array4< amrex::Real > &cell_rhs, const amrex::Array4< const amrex::Real > &cell_prim, const amrex::Array4< const amrex::Real > &avg_xmom, const amrex::Array4< const amrex::Real > &avg_ymom, const amrex::Array4< const amrex::Real > &avg_zmom, const amrex::Array4< const amrex::Real > &detJ, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &cellSizeInv, const bool do_lo=false)
void EBAdvectionSrcForScalars(const Box &bx, const int icomp, const int ncomp, const Array4< const Real > &avg_xmom, const Array4< const Real > &avg_ymom, const Array4< const Real > &avg_zmom, const Array4< const Real > &cell_prim, const Array4< Real > &advectionSrc, const Array4< const EBCellFlag > &cfg_arr, const Array4< const Real > &ax_arr, const Array4< const Real > &ay_arr, const Array4< const Real > &az_arr, const Array4< const Real > &detJ, const GpuArray< Real, AMREX_SPACEDIM > &cellSizeInv, const Array4< const Real > &mf_m, const AdvType horiz_adv_type, const AdvType vert_adv_type, const Real horiz_upw_frac, const Real vert_upw_frac, const GpuArray< const Array4< Real >, AMREX_SPACEDIM > &flx_arr, const Box &domain, const BCRec *bc_ptr_h)
Definition: ERF_EBAdvectionSrcForState.cpp:31
@ Centered_4th
@ Centered_6th
@ Centered_2nd
@ cons_bc
Definition: ERF_IndexDefines.H:76
@ open
Definition: ERF_IndexDefines.H:186
Here is the call graph for this function: