ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
erf_resolved_wall_flux Namespace Reference

Functions

template<int DIR, bool HIGH>
AMREX_FORCE_INLINE void apply_face (const amrex::Box &bx, const amrex::Box &domain, const int quantity, const int flux_comp, const amrex::Array4< const amrex::Real > &state, const amrex::Array4< const amrex::Real > &prim, const amrex::Array4< const amrex::Real > &base_state, const amrex::Array4< amrex::Real > &rhs, const amrex::Array4< amrex::Real > &xflux, const amrex::Array4< amrex::Real > &yflux, const amrex::Array4< amrex::Real > &zflux, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dx_inv, const erf_wall_thermodynamics::Boundary &walls, const amrex::Real alpha_T, const amrex::Real alpha_C, const amrex::Real rdOcp)
 
void apply (const amrex::Box &bx, const amrex::Box &domain, const int quantity, const int flux_comp, const amrex::Array4< const amrex::Real > &state, const amrex::Array4< const amrex::Real > &prim, const amrex::Array4< const amrex::Real > &base_state, const amrex::Array4< amrex::Real > &rhs, const amrex::Array4< amrex::Real > &xflux, const amrex::Array4< amrex::Real > &yflux, const amrex::Array4< amrex::Real > &zflux, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &dx_inv, const erf_wall_thermodynamics::Boundary &walls, const amrex::Real alpha_T, const amrex::Real alpha_C, const amrex::Real rdOcp)
 

Function Documentation

◆ apply()

void erf_resolved_wall_flux::apply ( const amrex::Box &  bx,
const amrex::Box &  domain,
const int  quantity,
const int  flux_comp,
const amrex::Array4< const amrex::Real > &  state,
const amrex::Array4< const amrex::Real > &  prim,
const amrex::Array4< const amrex::Real > &  base_state,
const amrex::Array4< amrex::Real > &  rhs,
const amrex::Array4< amrex::Real > &  xflux,
const amrex::Array4< amrex::Real > &  yflux,
const amrex::Array4< amrex::Real > &  zflux,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  dx_inv,
const erf_wall_thermodynamics::Boundary walls,
const amrex::Real  alpha_T,
const amrex::Real  alpha_C,
const amrex::Real  rdOcp 
)
inline
128 {
129  apply_face<0,false>(bx,domain,quantity,flux_comp,state,prim,base_state,rhs,xflux,yflux,zflux,dx_inv,walls,alpha_T,alpha_C,rdOcp);
130  apply_face<0,true >(bx,domain,quantity,flux_comp,state,prim,base_state,rhs,xflux,yflux,zflux,dx_inv,walls,alpha_T,alpha_C,rdOcp);
131  apply_face<1,false>(bx,domain,quantity,flux_comp,state,prim,base_state,rhs,xflux,yflux,zflux,dx_inv,walls,alpha_T,alpha_C,rdOcp);
132  apply_face<1,true >(bx,domain,quantity,flux_comp,state,prim,base_state,rhs,xflux,yflux,zflux,dx_inv,walls,alpha_T,alpha_C,rdOcp);
133  apply_face<2,false>(bx,domain,quantity,flux_comp,state,prim,base_state,rhs,xflux,yflux,zflux,dx_inv,walls,alpha_T,alpha_C,rdOcp);
134  apply_face<2,true >(bx,domain,quantity,flux_comp,state,prim,base_state,rhs,xflux,yflux,zflux,dx_inv,walls,alpha_T,alpha_C,rdOcp);
135 }
const Real rdOcp
Definition: ERF_InitCustomPert_Bomex.H:16

Referenced by erf_slow_rhs_post(), and erf_slow_rhs_pre().

Here is the caller graph for this function:

◆ apply_face()

template<int DIR, bool HIGH>
AMREX_FORCE_INLINE void erf_resolved_wall_flux::apply_face ( const amrex::Box &  bx,
const amrex::Box &  domain,
const int  quantity,
const int  flux_comp,
const amrex::Array4< const amrex::Real > &  state,
const amrex::Array4< const amrex::Real > &  prim,
const amrex::Array4< const amrex::Real > &  base_state,
const amrex::Array4< amrex::Real > &  rhs,
const amrex::Array4< amrex::Real > &  xflux,
const amrex::Array4< amrex::Real > &  yflux,
const amrex::Array4< amrex::Real > &  zflux,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  dx_inv,
const erf_wall_thermodynamics::Boundary walls,
const amrex::Real  alpha_T,
const amrex::Real  alpha_C,
const amrex::Real  rdOcp 
)
35 {
36  // A tile may belong to an interior BoxArray box. Do not relocate that
37  // tile to a global boundary: its Array4 views do not own data there.
38  if constexpr (HIGH) {
39  if (bx.bigEnd(DIR) != domain.bigEnd(DIR)) { return; }
40  } else {
41  if (bx.smallEnd(DIR) != domain.smallEnd(DIR)) { return; }
42  }
43 
44  const int cell_face = HIGH ? domain.bigEnd(DIR) : domain.smallEnd(DIR);
45  amrex::Box face_cells = bx;
46  face_cells.setSmall(DIR, cell_face);
47  face_cells.setBig(DIR, cell_face);
48  face_cells &= domain;
49  if (face_cells.isEmpty()) { return; }
50  AMREX_ALWAYS_ASSERT(bx.contains(face_cells));
51 
52  const auto wall = walls[2*DIR + (HIGH ? 1 : 0)];
53  const bool is_theta = quantity == RhoTheta_comp;
54  const bool is_qv = quantity == RhoQ1_comp;
55  const bool is_qc = quantity == RhoQ2_comp;
56  if (!((is_theta && wall.thermal_mode == erf_wall_thermodynamics::ThermalMode::FixedPhysicalTemperature) ||
57  (is_qv && wall.moisture_mode != erf_wall_thermodynamics::MoistureMode::LegacyNumerical) ||
58  (is_qc && wall.moisture_mode != erf_wall_thermodynamics::MoistureMode::LegacyNumerical))) {
59  return;
60  }
61 
62  const auto& flux = (DIR == 0) ? xflux : ((DIR == 1) ? yflux : zflux);
63  const amrex::Real alpha = is_theta ? alpha_T : alpha_C;
64  const amrex::Real inv_half_cell = amrex::Real(2.0) * dx_inv[DIR];
65 
66  amrex::ParallelFor(face_cells, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
67  {
68  const int fi = HIGH && DIR == 0 ? i + 1 : i;
69  const int fj = HIGH && DIR == 1 ? j + 1 : j;
70  const int fk = HIGH && DIR == 2 ? k + 1 : k;
71  const amrex::Real rho = state(i,j,k,Rho_comp);
72  const amrex::Real p0 = base_state(i,j,k,BaseState::p0_comp);
73  const amrex::Real wall_temperature = wall.physical_temperature_K;
74  amrex::Real wall_value = amrex::Real(0.0);
75  amrex::Real cell_value = prim(i,j,k,quantity-1);
76 
77  if (is_theta) {
78  wall_value = wall_temperature * std::pow(p_0 / p0, rdOcp);
79  } else if (is_qv && wall.moisture_mode == erf_wall_thermodynamics::MoistureMode::WetEquilibrium) {
80  amrex::Real qsat = amrex::Real(0.0);
81  erf_qsatw(wall_temperature, p0 * amrex::Real(0.01), qsat);
82  wall_value = qsat;
83  } else if (is_qc || (is_qv && wall.moisture_mode == erf_wall_thermodynamics::MoistureMode::DryImpermeable)) {
84  wall_value = amrex::Real(0.0);
85  }
86 
87  const amrex::Real old_flux = flux(fi,fj,fk,flux_comp);
88  amrex::Real new_flux = amrex::Real(0.0);
89  if (!(is_qc || (is_qv && wall.moisture_mode == erf_wall_thermodynamics::MoistureMode::DryImpermeable))) {
90  amrex::ignore_unused(alpha, inv_half_cell);
91  if constexpr (HIGH) {
92  new_flux = -rho * alpha * (wall_value - cell_value) * inv_half_cell;
93  } else {
94  new_flux = -rho * alpha * (cell_value - wall_value) * inv_half_cell;
95  }
96  }
97  flux(fi,fj,fk,flux_comp) = new_flux;
98 
99  // DiffusionSrcForState_N has already applied the old boundary flux to
100  // the RHS. Add only the boundary correction so the state update and
101  // the retained flux array use exactly the same physical flux.
102  const amrex::Real correction = (new_flux - old_flux) * dx_inv[DIR];
103  amrex::ignore_unused(rhs);
104  if constexpr (HIGH) {
105  rhs(i,j,k,quantity) -= correction;
106  } else {
107  rhs(i,j,k,quantity) += correction;
108  }
109  });
110 }
constexpr amrex::Real p_0
Definition: ERF_Constants.H:61
#define Rho_comp
Definition: ERF_IndexDefines.H:36
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:37
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:43
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
rho
Definition: ERF_InitCustomPert_Bubble.H:107
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void erf_qsatw(amrex::Real t, amrex::Real p, amrex::Real &qsatw)
Definition: ERF_MicrophysicsUtils.H:228
ParallelFor(fab_box, [=] AMREX_GPU_DEVICE(int i, int j, int k) { qrcuten_arr(i, j, k)=Real(0);qscuten_arr(i, j, k)=Real(0);qicuten_arr(i, j, k)=Real(0);})
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ p0_comp
Definition: ERF_IndexDefines.H:74
@ fi
Definition: ERF_AdvanceMorrison.cpp:107
real(c_double), parameter p0
Definition: ERF_module_model_constants.F90:40
real(kind=kind_phys), parameter, public alpha
Definition: ERF_module_mp_wsm6.F90:44
Here is the call graph for this function: