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

Classes

struct  WallFlux
 
struct  FaceRuntimeCoefficients
 
struct  MostStabilityResult
 
struct  ScalarWallSample
 
struct  NeutralLogMomentumState
 
struct  MomentumWallSample
 
struct  ScalarFluxReplacement
 

Enumerations

enum  OwnedChannel : unsigned char {
  OwnNone = 0 , OwnMomentum = 1 << 0 , OwnHeat = 1 << 1 , OwnVapor = 1 << 2 ,
  OwnCloudWater = 1 << 3
}
 
enum class  ScalarChannel : unsigned char { None , Heat , Vapor , CloudWater }
 

Functions

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool wall_uses_most_vapor (const erf_wall_thermodynamics::FaceWall &wall) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool wall_uses_most (const erf_wall_thermodynamics::FaceWall &wall) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE ScalarChannel scalar_channel_from_quantity (int quantity) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int primitive_component (ScalarChannel channel) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool wall_owns_scalar_channel (const erf_wall_thermodynamics::FaceWall &wall, ScalarChannel channel) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE unsigned char scalar_channel_mask (ScalarChannel channel) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool owns (const WallFlux &flux, ScalarChannel channel) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE NeutralLogMomentumState neutral_log_momentum_state (amrex::Real U_t, amrex::Real wall_distance, amrex::Real z0_m) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real neutral_log_scalar_coefficient (amrex::Real wall_distance, amrex::Real z0_m, amrex::Real z0_scalar) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE MostStabilityResult most_stability_coordinate (amrex::Real Ri, amrex::Real D_m, amrex::Real D_s) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE FaceRuntimeCoefficients most_wall_coefficients (const erf_wall_thermodynamics::FaceWall &wall, amrex::Real theta_air, amrex::Real qv_air, amrex::Real p_hse, amrex::Real rdOcp, amrex::Real U_t, amrex::Real wall_distance, int gravity_sign) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > neutral_log_traction_on_fluid (const MomentumWallSample &sample, const NeutralLogMomentumState &neutral) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real neutral_scalar_rate (amrex::Real coefficient, amrex::Real U_t, amrex::Real dx_inv) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real momentum_infinity_row_sum_factor () noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real momentum_row_sum_rate (int component, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &low_rate, const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &high_rate) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real momentum_rate_for_face (const erf_wall_thermodynamics::FaceWall &wall, amrex::Real U_t, amrex::Real dx_inv, const FaceRuntimeCoefficients &runtime=FaceRuntimeCoefficients{}) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool requires_tangential_speed (const erf_wall_thermodynamics::FaceWall &wall, ScalarChannel channel) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool requires_tangential_momentum (const erf_wall_thermodynamics::FaceWall &wall) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool wall_rate_requires_tangential_speed (const erf_wall_thermodynamics::FaceWall &wall) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real wall_rate_for_face (const erf_wall_thermodynamics::FaceWall &wall, amrex::Real U_t, amrex::Real dx_inv, const FaceRuntimeCoefficients &runtime) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real wall_rate_for_face (const erf_wall_thermodynamics::FaceWall &wall, amrex::Real U_t, amrex::Real dx_inv) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real wall_rate_for_face (const erf_wall_thermodynamics::FaceWall &wall, amrex::Real theta_air, amrex::Real qv_air, amrex::Real p_hse, amrex::Real rdOcp, amrex::Real U_t, amrex::Real dx_inv, int gravity_sign) noexcept
 
template<int DIR, bool HIGH>
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real to_coordinate_flux (amrex::Real inward) noexcept
 
template<int DIR, bool HIGH>
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > traction_from_local_inward (amrex::Real normal_in, amrex::Real tangent_a, amrex::Real tangent_b) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real bulk_theta_flux_in (amrex::Real rho, amrex::Real C_H, amrex::Real U_t, amrex::Real wall_temperature_K, amrex::Real theta_air, amrex::Real p_hse, amrex::Real rdOcp) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real bulk_vapor_flux_in (amrex::Real rho, amrex::Real C_E, amrex::Real U_t, amrex::Real wall_temperature_K, amrex::Real qv_air, amrex::Real p_hse) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > relative_tangential_velocity_cell_centered (int dir, int i, int j, int k, const amrex::Array4< const amrex::Real > &u, const amrex::Array4< const amrex::Real > &v, const amrex::Array4< const amrex::Real > &w, const erf_wall_thermodynamics::FaceWall &wall) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real tangential_magnitude (const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &u_t) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real tangential_speed (int dir, int i, int j, int k, const amrex::Array4< const amrex::Real > &u, const amrex::Array4< const amrex::Real > &v, const amrex::Array4< const amrex::Real > &w, const erf_wall_thermodynamics::FaceWall &wall) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real tangential_speed_cell_centered (int dir, int i, int j, int k, const amrex::Array4< const amrex::Real > &velocity, const erf_wall_thermodynamics::FaceWall &wall) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real resolved_theta_flux_in (amrex::Real rho, amrex::Real alpha_T, amrex::Real wall_temperature_K, amrex::Real theta_air, amrex::Real p_hse, amrex::Real dx_inv, amrex::Real rdOcp) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real resolved_vapor_flux_in (amrex::Real rho, amrex::Real alpha_C, amrex::Real wall_temperature_K, amrex::Real qv_air, amrex::Real p_hse, amrex::Real dx_inv) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE WallFlux evaluate_momentum_traction (const erf_wall_thermodynamics::FaceWall &wall, const MomentumWallSample &sample) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE WallFlux evaluate_scalar_flux_in (const erf_wall_thermodynamics::FaceWall &wall, ScalarChannel channel, const ScalarWallSample &sample) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real scalar_flux_in (const WallFlux &flux, ScalarChannel channel) noexcept
 
template<int DIR, bool HIGH>
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE ScalarFluxReplacement scalar_flux_replacement (amrex::Real old_flux, amrex::Real inward_flux, amrex::Real dx_inv) noexcept
 
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< const amrex::Real > &u, const amrex::Array4< const amrex::Real > &v, const amrex::Array4< const amrex::Real > &w, 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, const bool cloudy)
 
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< const amrex::Real > &u, const amrex::Array4< const amrex::Real > &v, const amrex::Array4< const amrex::Real > &w, 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, const bool cloudy=false)
 
bool has_velocity_dependent_scalar_wall (const erf_wall_thermodynamics::Boundary &walls) noexcept
 
AMREX_FORCE_INLINE amrex::Real wall_dt_from_max_rate (amrex::Real max_rate, amrex::Real wall_cfl=amrex::Real(0.5)) noexcept
 

Enumeration Type Documentation

◆ OwnedChannel

Enumerator
OwnNone 
OwnMomentum 
OwnHeat 
OwnVapor 
OwnCloudWater 
23  : unsigned char {
24  OwnNone = 0,
25  OwnMomentum = 1 << 0,
26  OwnHeat = 1 << 1,
27  OwnVapor = 1 << 2,
28  OwnCloudWater = 1 << 3
29 };
@ OwnVapor
Definition: ERF_CloudChamberWallFlux.H:27
@ OwnNone
Definition: ERF_CloudChamberWallFlux.H:24
@ OwnHeat
Definition: ERF_CloudChamberWallFlux.H:26
@ OwnCloudWater
Definition: ERF_CloudChamberWallFlux.H:28
@ OwnMomentum
Definition: ERF_CloudChamberWallFlux.H:25

◆ ScalarChannel

Function Documentation

◆ apply()

void erf_cloud_chamber_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< const amrex::Real > &  u,
const amrex::Array4< const amrex::Real > &  v,
const amrex::Array4< const amrex::Real > &  w,
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,
const bool  cloudy = false 
)
inline
1054 {
1055  apply_face<0,false>(bx,domain,quantity,flux_comp,state,prim,base_state,u,v,w,rhs,xflux,yflux,zflux,dx_inv,walls,alpha_T,alpha_C,rdOcp,cloudy);
1056  apply_face<0,true >(bx,domain,quantity,flux_comp,state,prim,base_state,u,v,w,rhs,xflux,yflux,zflux,dx_inv,walls,alpha_T,alpha_C,rdOcp,cloudy);
1057  apply_face<1,false>(bx,domain,quantity,flux_comp,state,prim,base_state,u,v,w,rhs,xflux,yflux,zflux,dx_inv,walls,alpha_T,alpha_C,rdOcp,cloudy);
1058  apply_face<1,true >(bx,domain,quantity,flux_comp,state,prim,base_state,u,v,w,rhs,xflux,yflux,zflux,dx_inv,walls,alpha_T,alpha_C,rdOcp,cloudy);
1059  apply_face<2,false>(bx,domain,quantity,flux_comp,state,prim,base_state,u,v,w,rhs,xflux,yflux,zflux,dx_inv,walls,alpha_T,alpha_C,rdOcp,cloudy);
1060  apply_face<2,true >(bx,domain,quantity,flux_comp,state,prim,base_state,u,v,w,rhs,xflux,yflux,zflux,dx_inv,walls,alpha_T,alpha_C,rdOcp,cloudy);
1061 }
const Real rdOcp
Definition: ERF_InitCustomPert_ABL.H:72
Real w
Definition: ERF_Plotfile2DInterpolator.cpp:22

Referenced by erf_resolved_wall_flux::apply(), 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_cloud_chamber_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< const amrex::Real > &  u,
const amrex::Array4< const amrex::Real > &  v,
const amrex::Array4< const amrex::Real > &  w,
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,
const bool  cloudy 
)
966 {
967  // A tile may belong to an interior BoxArray box. Do not relocate that
968  // tile to a global boundary: its Array4 views do not own data there.
969  if constexpr (HIGH) {
970  if (bx.bigEnd(DIR) != domain.bigEnd(DIR)) { return; }
971  } else {
972  if (bx.smallEnd(DIR) != domain.smallEnd(DIR)) { return; }
973  }
974 
975  const ScalarChannel channel =
977  if (channel == ScalarChannel::None) { return; }
978 
979  const auto wall = walls[2*DIR + (HIGH ? 1 : 0)];
980  if (!wall_owns_scalar_channel(wall, channel)) { return; }
981 
982  const int prim_comp = primitive_component(channel);
983  AMREX_ALWAYS_ASSERT(prim_comp >= 0);
984 
985  const int cell_face = HIGH ? domain.bigEnd(DIR) : domain.smallEnd(DIR);
986  amrex::Box face_cells = bx;
987  face_cells.setSmall(DIR, cell_face);
988  face_cells.setBig(DIR, cell_face);
989  face_cells &= domain;
990  if (face_cells.isEmpty()) { return; }
991  AMREX_ALWAYS_ASSERT(bx.contains(face_cells));
992 
993  const bool needs_speed = requires_tangential_speed(wall, channel);
994  const auto& flux =
995  (DIR == 0) ? xflux : ((DIR == 1) ? yflux : zflux);
996 
997  amrex::ParallelFor(face_cells,
998  [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept
999  {
1000  const int fi = HIGH && DIR == 0 ? i + 1 : i;
1001  const int fj = HIGH && DIR == 1 ? j + 1 : j;
1002  const int fk = HIGH && DIR == 2 ? k + 1 : k;
1003 
1004  const amrex::Real old_flux = flux(fi,fj,fk,flux_comp);
1005  const ScalarWallSample sample{
1006  state(i,j,k,Rho_comp),
1007  prim(i,j,k,prim_comp),
1008  base_state(i,j,k,BaseState::p0_comp),
1009  needs_speed ?
1010  tangential_speed(DIR, i, j, k, u, v, w, wall) :
1011  amrex::Real(0.0),
1012  alpha_T,
1013  alpha_C,
1014  dx_inv[DIR],
1015  rdOcp,
1016  amrex::Real(0.5) / dx_inv[DIR],
1017  prim(i,j,k,PrimTheta_comp),
1018  cloudy ? prim(i,j,k,PrimQ1_comp) : amrex::Real(0.0),
1019  DIR == 2 ? (HIGH ? -1 : 1) : 0
1020  };
1021 
1022  const WallFlux physical =
1023  evaluate_scalar_flux_in(wall, channel, sample);
1024  if (!owns(physical, channel)) { return; }
1025 
1026  const ScalarFluxReplacement update =
1027  scalar_flux_replacement<DIR,HIGH>(
1028  old_flux,
1029  scalar_flux_in(physical, channel),
1030  dx_inv[DIR]);
1031 
1032  flux(fi,fj,fk,flux_comp) = update.coordinate_flux;
1033  rhs(i,j,k,quantity) += update.rhs_delta;
1034  });
1035 }
#define PrimQ1_comp
Definition: ERF_IndexDefines.H:61
#define Rho_comp
Definition: ERF_IndexDefines.H:39
#define PrimTheta_comp
Definition: ERF_IndexDefines.H:58
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
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:77
@ fi
Definition: ERF_AdvanceMorrison.cpp:107
Definition: ERF_ConsoleIO.cpp:15
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool owns(const WallFlux &flux, ScalarChannel channel) noexcept
Definition: ERF_CloudChamberWallFlux.H:211
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE WallFlux evaluate_scalar_flux_in(const erf_wall_thermodynamics::FaceWall &wall, ScalarChannel channel, const ScalarWallSample &sample) noexcept
Definition: ERF_CloudChamberWallFlux.H:773
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool requires_tangential_speed(const erf_wall_thermodynamics::FaceWall &wall, ScalarChannel channel) noexcept
Definition: ERF_CloudChamberWallFlux.H:439
ScalarChannel
Definition: ERF_CloudChamberWallFlux.H:53
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE ScalarChannel scalar_channel_from_quantity(int quantity) noexcept
Definition: ERF_CloudChamberWallFlux.H:141
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real scalar_flux_in(const WallFlux &flux, ScalarChannel channel) noexcept
Definition: ERF_CloudChamberWallFlux.H:909
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool wall_owns_scalar_channel(const erf_wall_thermodynamics::FaceWall &wall, ScalarChannel channel) noexcept
Definition: ERF_CloudChamberWallFlux.H:170
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int primitive_component(ScalarChannel channel) noexcept
Definition: ERF_CloudChamberWallFlux.H:152
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real tangential_speed(int dir, int i, int j, int k, const amrex::Array4< const amrex::Real > &u, const amrex::Array4< const amrex::Real > &v, const amrex::Array4< const amrex::Real > &w, const erf_wall_thermodynamics::FaceWall &wall) noexcept
Definition: ERF_CloudChamberWallFlux.H:660
Here is the call graph for this function:

◆ bulk_theta_flux_in()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::bulk_theta_flux_in ( amrex::Real  rho,
amrex::Real  C_H,
amrex::Real  U_t,
amrex::Real  wall_temperature_K,
amrex::Real  theta_air,
amrex::Real  p_hse,
amrex::Real  rdOcp 
)
noexcept
606 {
607  const amrex::Real theta_wall =
608  wall_temperature_K * std::pow(p_0 / p_hse, rdOcp);
609  return rho * C_H * U_t * (theta_wall - theta_air);
610 }
constexpr amrex::Real p_0
Definition: ERF_Constants.H:53
@ rho
Definition: ERF_Kessler.H:25

Referenced by evaluate_scalar_flux_in().

Here is the caller graph for this function:

◆ bulk_vapor_flux_in()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::bulk_vapor_flux_in ( amrex::Real  rho,
amrex::Real  C_E,
amrex::Real  U_t,
amrex::Real  wall_temperature_K,
amrex::Real  qv_air,
amrex::Real  p_hse 
)
noexcept
621 {
622  amrex::Real qv_wall = amrex::Real(0.0);
623  erf_qsatw(wall_temperature_K, p_hse * amrex::Real(0.01), qv_wall);
624  return rho * C_E * U_t * (qv_wall - qv_air);
625 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void erf_qsatw(amrex::Real t, amrex::Real p, amrex::Real &qsatw)
Definition: ERF_MicrophysicsUtils.H:264

Referenced by evaluate_scalar_flux_in().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ evaluate_momentum_traction()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE WallFlux erf_cloud_chamber_wall_flux::evaluate_momentum_traction ( const erf_wall_thermodynamics::FaceWall wall,
const MomentumWallSample sample 
)
noexcept
733 {
734  using namespace erf_wall_thermodynamics;
735 
736  WallFlux result{};
737  switch (wall.momentum.model) {
739  return result;
741  result.owned_channels = OwnMomentum;
742  const auto neutral = neutral_log_momentum_state(
743  sample.U_t, sample.wall_distance, wall.momentum.z0_m);
744  result.traction_on_fluid =
745  neutral_log_traction_on_fluid(sample, neutral);
746  return result;
747  }
749  result.owned_channels = OwnMomentum;
750  if (sample.U_t == amrex::Real(0.0)) { return result; }
751  amrex::Real C_D = wall.momentum.C_D;
753  const auto runtime = most_wall_coefficients(
754  wall, sample.theta_air, sample.qv_air, sample.p_hse,
755  sample.rdOcp, sample.U_t, sample.wall_distance,
756  sample.gravity_sign);
757  AMREX_ALWAYS_ASSERT(runtime.valid != 0);
758  C_D = runtime.C_D;
759  }
760  const amrex::Real factor = -sample.rho * C_D * sample.U_t;
761  result.traction_on_fluid = {
762  factor * sample.u_t[0], factor * sample.u_t[1], factor * sample.u_t[2]};
763  return result;
764  }
765  }
766  AMREX_ALWAYS_ASSERT(false);
767  return result;
768 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE NeutralLogMomentumState neutral_log_momentum_state(amrex::Real U_t, amrex::Real wall_distance, amrex::Real z0_m) noexcept
Definition: ERF_CloudChamberWallFlux.H:219
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE FaceRuntimeCoefficients most_wall_coefficients(const erf_wall_thermodynamics::FaceWall &wall, amrex::Real theta_air, amrex::Real qv_air, amrex::Real p_hse, amrex::Real rdOcp, amrex::Real U_t, amrex::Real wall_distance, int gravity_sign) noexcept
Definition: ERF_CloudChamberWallFlux.H:278
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > neutral_log_traction_on_fluid(const MomentumWallSample &sample, const NeutralLogMomentumState &neutral) noexcept
Definition: ERF_CloudChamberWallFlux.H:358
Definition: ERF_WallThermodynamics.H:9
MomentumTransfer momentum
Definition: ERF_WallThermodynamics.H:64
amrex::Real z0_m
Definition: ERF_WallThermodynamics.H:51
CoefficientProvider provider
Definition: ERF_WallThermodynamics.H:49
amrex::Real C_D
Definition: ERF_WallThermodynamics.H:50
MomentumModel model
Definition: ERF_WallThermodynamics.H:48

Referenced by erf_cloud_chamber_wall_stress::wall_traction_at_cell().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ evaluate_scalar_flux_in()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE WallFlux erf_cloud_chamber_wall_flux::evaluate_scalar_flux_in ( const erf_wall_thermodynamics::FaceWall wall,
ScalarChannel  channel,
const ScalarWallSample sample 
)
noexcept
777 {
778  using namespace erf_wall_thermodynamics;
779 
780  WallFlux result{};
781  if (!wall_owns_scalar_channel(wall, channel)) {
782  return result;
783  }
784 
785  result.owned_channels = scalar_channel_mask(channel);
786 
787  switch (channel) {
788  case ScalarChannel::Heat:
789  if (sample.U_t == amrex::Real(0.0) &&
791  return result;
792  }
793  switch (wall.heat.model) {
795  result.rhoTheta_in = resolved_theta_flux_in(
796  sample.rho,
797  sample.alpha_T,
798  wall.thermal.temperature_K,
799  sample.scalar_air,
800  sample.p_hse,
801  sample.dx_inv,
802  sample.rdOcp);
803  return result;
804 
805  case ScalarModel::BulkAero: {
806  amrex::Real C_H = wall.heat.coefficient;
808  const auto runtime = most_wall_coefficients(
809  wall, sample.theta_air, sample.qv_air, sample.p_hse,
810  sample.rdOcp, sample.U_t, sample.wall_distance,
811  sample.gravity_sign);
812  AMREX_ALWAYS_ASSERT(runtime.valid != 0);
813  C_H = runtime.C_H;
814  }
815  result.rhoTheta_in = bulk_theta_flux_in(
816  sample.rho,
817  C_H,
818  sample.U_t,
819  wall.thermal.temperature_K,
820  sample.scalar_air,
821  sample.p_hse,
822  sample.rdOcp);
823  return result;
824  }
826  result.rhoTheta_in = bulk_theta_flux_in(
827  sample.rho,
829  sample.wall_distance,
830  wall.momentum.z0_m,
831  wall.heat.z0),
832  sample.U_t,
833  wall.thermal.temperature_K,
834  sample.scalar_air,
835  sample.p_hse,
836  sample.rdOcp);
837  return result;
838  }
839  AMREX_ALWAYS_ASSERT(false);
840  return result;
841 
842  case ScalarChannel::Vapor:
844  return result;
845  }
846  if (sample.U_t == amrex::Real(0.0) &&
848  return result;
849  }
850  switch (wall.vapor.model) {
852  result.rhoQv_in = resolved_vapor_flux_in(
853  sample.rho,
854  sample.alpha_C,
855  wall.thermal.temperature_K,
856  sample.scalar_air,
857  sample.p_hse,
858  sample.dx_inv);
859  return result;
860 
861  case ScalarModel::BulkAero: {
862  amrex::Real C_E = wall.vapor.coefficient;
864  const auto runtime = most_wall_coefficients(
865  wall, sample.theta_air, sample.qv_air, sample.p_hse,
866  sample.rdOcp, sample.U_t, sample.wall_distance,
867  sample.gravity_sign);
868  AMREX_ALWAYS_ASSERT(runtime.valid != 0);
869  C_E = runtime.C_E;
870  }
871  result.rhoQv_in = bulk_vapor_flux_in(
872  sample.rho,
873  C_E,
874  sample.U_t,
875  wall.thermal.temperature_K,
876  sample.scalar_air,
877  sample.p_hse);
878  return result;
879  }
881  result.rhoQv_in = bulk_vapor_flux_in(
882  sample.rho,
884  sample.wall_distance,
885  wall.momentum.z0_m,
886  wall.vapor.z0),
887  sample.U_t,
888  wall.thermal.temperature_K,
889  sample.scalar_air,
890  sample.p_hse);
891  return result;
892  }
893  AMREX_ALWAYS_ASSERT(false);
894  return result;
895 
896  case ScalarChannel::CloudWater:
897  return result;
898 
899  case ScalarChannel::None:
900  return result;
901  }
902 
903  return result;
904 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real bulk_vapor_flux_in(amrex::Real rho, amrex::Real C_E, amrex::Real U_t, amrex::Real wall_temperature_K, amrex::Real qv_air, amrex::Real p_hse) noexcept
Definition: ERF_CloudChamberWallFlux.H:615
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real bulk_theta_flux_in(amrex::Real rho, amrex::Real C_H, amrex::Real U_t, amrex::Real wall_temperature_K, amrex::Real theta_air, amrex::Real p_hse, amrex::Real rdOcp) noexcept
Definition: ERF_CloudChamberWallFlux.H:599
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real neutral_log_scalar_coefficient(amrex::Real wall_distance, amrex::Real z0_m, amrex::Real z0_scalar) noexcept
Definition: ERF_CloudChamberWallFlux.H:231
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real resolved_vapor_flux_in(amrex::Real rho, amrex::Real alpha_C, amrex::Real wall_temperature_K, amrex::Real qv_air, amrex::Real p_hse, amrex::Real dx_inv) noexcept
Definition: ERF_CloudChamberWallFlux.H:710
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real resolved_theta_flux_in(amrex::Real rho, amrex::Real alpha_T, amrex::Real wall_temperature_K, amrex::Real theta_air, amrex::Real p_hse, amrex::Real dx_inv, amrex::Real rdOcp) noexcept
Definition: ERF_CloudChamberWallFlux.H:692
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE unsigned char scalar_channel_mask(ScalarChannel channel) noexcept
Definition: ERF_CloudChamberWallFlux.H:192
ScalarTransfer vapor
Definition: ERF_WallThermodynamics.H:66
ScalarTransfer heat
Definition: ERF_WallThermodynamics.H:65
MoistureMode moisture
Definition: ERF_WallThermodynamics.H:63
ThermalBoundary thermal
Definition: ERF_WallThermodynamics.H:62
amrex::Real coefficient
Definition: ERF_WallThermodynamics.H:57
CoefficientProvider provider
Definition: ERF_WallThermodynamics.H:56
amrex::Real z0
Definition: ERF_WallThermodynamics.H:58
ScalarModel model
Definition: ERF_WallThermodynamics.H:55
amrex::Real temperature_K
Definition: ERF_WallThermodynamics.H:44

Referenced by apply_face().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_velocity_dependent_scalar_wall()

bool erf_cloud_chamber_wall_flux::has_velocity_dependent_scalar_wall ( const erf_wall_thermodynamics::Boundary walls)
inlinenoexcept
1065 {
1066  for (const auto& wall : walls) {
1067  if (requires_tangential_speed(wall, ScalarChannel::Heat) ||
1068  requires_tangential_speed(wall, ScalarChannel::Vapor)) {
1069  return true;
1070  }
1071  }
1072  return false;
1073 }

Referenced by erf_resolved_wall_flux::apply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ momentum_infinity_row_sum_factor()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::momentum_infinity_row_sum_factor ( )
noexcept
383 {
384  // For a fixed C_D, the maximum absolute row sum of the two-component
385  // tangential Jacobian of C_D |u_t| u_t is (3 + sqrt(2))/2 * C_D |u_t|.
386  // Cloud Chamber MOST applies this factor to its frozen current C_D.
387  return (amrex::Real(3.0) + std::sqrt(amrex::Real(2.0))) / amrex::Real(2.0);
388 }

◆ momentum_rate_for_face()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::momentum_rate_for_face ( const erf_wall_thermodynamics::FaceWall wall,
amrex::Real  U_t,
amrex::Real  dx_inv,
const FaceRuntimeCoefficients runtime = FaceRuntimeCoefficients{} 
)
noexcept
414  {}) noexcept
415 {
416  using namespace erf_wall_thermodynamics;
417  amrex::Real C_D = amrex::Real(0.0);
418  const amrex::Real wall_distance = amrex::Real(0.5) / dx_inv;
419  if (wall.momentum.model !=
423  U_t, wall_distance, wall.momentum.z0_m).C_D;
424  } else if (wall.momentum.model == MomentumModel::BulkAero) {
426  AMREX_ALWAYS_ASSERT(runtime.valid != 0);
427  C_D = runtime.C_D;
428  } else {
429  C_D = wall.momentum.C_D;
430  }
431  }
432  }
433  return momentum_infinity_row_sum_factor() * C_D * U_t * dx_inv;
434 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real momentum_infinity_row_sum_factor() noexcept
Definition: ERF_CloudChamberWallFlux.H:382
amrex::Real C_D
Definition: ERF_CloudChamberWallFlux.H:78

Referenced by ERF::estTimeStep(), and wall_rate_for_face().

Here is the caller graph for this function:

◆ momentum_row_sum_rate()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::momentum_row_sum_rate ( int  component,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  low_rate,
const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  high_rate 
)
noexcept
397 {
398  amrex::Real result = amrex::Real(0.0);
399  for (int dir = 0; dir < AMREX_SPACEDIM; ++dir) {
400  if (dir != component) {
401  result += low_rate[dir] + high_rate[dir];
402  }
403  }
404  return result;
405 }

Referenced by ERF::estTimeStep().

Here is the caller graph for this function:

◆ most_stability_coordinate()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE MostStabilityResult erf_cloud_chamber_wall_flux::most_stability_coordinate ( amrex::Real  Ri,
amrex::Real  D_m,
amrex::Real  D_s 
)
noexcept
246 {
247  similarity_funs sfuns;
248  amrex::Real zeta = amrex::Real(0.0);
249  bool converged = false;
250  int iterations = 0;
251  constexpr int max_iters = 100;
252  for (int iter = 0; iter < max_iters; ++iter) {
253  const amrex::Real zeta_old = zeta;
254  const amrex::Real psi_m = sfuns.calc_psi_m2(zeta_old);
255  const amrex::Real psi_s = sfuns.calc_psi_h2(zeta_old);
256  const amrex::Real A_m = amrex::max(D_m - psi_m, amrex::Real(1.0));
257  const amrex::Real A_s = amrex::max(D_s - psi_s, amrex::Real(1.0));
258  const amrex::Real zeta_new = amrex::Real(0.5) * zeta_old +
259  amrex::Real(0.5) * Ri * A_m * A_m / A_s;
261  amrex::Math::isfinite(static_cast<double>(zeta_new)),
262  "Cloud Chamber MOST produced a nonfinite stability coordinate");
263  zeta = zeta_new;
264  iterations = iter + 1;
265  if (std::abs(zeta - zeta_old) <= amrex::Real(1.0e-3)) {
266  converged = true;
267  break;
268  }
269  }
271  converged, "Cloud Chamber MOST fixed-point iteration did not converge");
272  return {zeta, iterations};
273 }
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_cloud_chamber_config.active, "Cloud Chamber: initializer reached without a parsed configuration")
Definition: ERF_MOSTUtils.H:37
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real calc_psi_h2(amrex::Real zeta) const
Definition: ERF_MOSTUtils.H:74
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real calc_psi_m2(amrex::Real zeta) const
Definition: ERF_MOSTUtils.H:49

Referenced by most_wall_coefficients().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ most_wall_coefficients()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE FaceRuntimeCoefficients erf_cloud_chamber_wall_flux::most_wall_coefficients ( const erf_wall_thermodynamics::FaceWall wall,
amrex::Real  theta_air,
amrex::Real  qv_air,
amrex::Real  p_hse,
amrex::Real  rdOcp,
amrex::Real  U_t,
amrex::Real  wall_distance,
int  gravity_sign 
)
noexcept
287 {
288  using namespace erf_wall_thermodynamics;
289  FaceRuntimeCoefficients result{};
290  const bool most_momentum =
293  const bool most_heat =
294  wall.heat.model == ScalarModel::BulkAero &&
296  const bool most_vapor = wall_uses_most_vapor(wall);
297  if (!(most_momentum || most_heat || most_vapor)) {
298  result.valid = 1;
299  return result;
300  }
301 
302  const amrex::Real theta_wall = wall.thermal.temperature_K *
303  std::pow(p_0 / p_hse, rdOcp);
304  amrex::Real qv_wall = qv_air;
306  erf_qsatw(wall.thermal.temperature_K, p_hse * amrex::Real(0.01), qv_wall);
307  }
308  const amrex::Real theta_v_air = theta_air * (amrex::Real(1.0) + epsv * qv_air);
309  const amrex::Real theta_v_wall = theta_wall * (amrex::Real(1.0) + epsv * qv_wall);
310  const amrex::Real U_most = amrex::max(U_t, amrex::Real(0.01));
311  const amrex::Real Ri_b = gravity_sign == 0 ? amrex::Real(0.0) :
312  amrex::Real(gravity_sign) * CONST_GRAV * wall_distance / theta_air *
313  (theta_v_air - theta_v_wall) / (U_most * U_most);
314  const amrex::Real Ri = amrex::max(amrex::Real(-4.0),
315  amrex::min(amrex::Real(4.0), Ri_b));
316 
317  const amrex::Real z0_m = wall.momentum.z0_m;
318  const amrex::Real z0_h = wall.heat.z0 > amrex::Real(0.0) ?
319  wall.heat.z0 : z0_m;
320  const amrex::Real z0_q = wall.vapor.z0 > amrex::Real(0.0) ?
321  wall.vapor.z0 : z0_m;
322  const amrex::Real D_m = std::log(wall_distance / z0_m);
323  const amrex::Real D_h = std::log(wall_distance / z0_h);
324  const amrex::Real D_q = std::log(wall_distance / z0_q);
325 
326  // A coupled MOST heat/vapor face is host-constrained to have equal scalar
327  // roughness. For a single active scalar channel, that channel supplies
328  // the scalar resistance used by the bulk-Richardson fixed point.
329  const amrex::Real z0_stability = most_heat ? z0_h :
330  (most_vapor ? z0_q : z0_m);
331  const amrex::Real D_stability = std::log(wall_distance / z0_stability);
332  const auto stability = most_stability_coordinate(Ri, D_m, D_stability);
333  const amrex::Real zeta = stability.zeta;
334 
335  similarity_funs sfuns;
336  const amrex::Real psi_m = sfuns.calc_psi_m2(zeta);
337  const amrex::Real psi_h = sfuns.calc_psi_h2(zeta);
338  const amrex::Real A_m = amrex::max(D_m - psi_m, amrex::Real(1.0));
339  const amrex::Real A_h = amrex::max(D_h - psi_h, amrex::Real(1.0));
340  const amrex::Real A_q = amrex::max(D_q - psi_h, amrex::Real(1.0));
341  result.C_D = (KAPPA / A_m) * (KAPPA / A_m);
342  result.C_H = KAPPA * KAPPA / (A_m * A_h);
343  result.C_E = KAPPA * KAPPA / (A_m * A_q);
344  result.u_star = KAPPA * U_most / A_m;
345  result.zeta = zeta;
346  result.valid = 1;
348  amrex::Math::isfinite(static_cast<double>(result.C_D)) &&
349  amrex::Math::isfinite(static_cast<double>(result.C_H)) &&
350  amrex::Math::isfinite(static_cast<double>(result.C_E)),
351  "Cloud Chamber MOST produced nonfinite transfer coefficients");
352  return result;
353 }
constexpr amrex::Real epsv
Definition: ERF_Constants.H:40
constexpr amrex::Real KAPPA
Definition: ERF_Constants.H:55
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:56
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE MostStabilityResult most_stability_coordinate(amrex::Real Ri, amrex::Real D_m, amrex::Real D_s) noexcept
Definition: ERF_CloudChamberWallFlux.H:243
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool wall_uses_most_vapor(const erf_wall_thermodynamics::FaceWall &wall) noexcept
Definition: ERF_CloudChamberWallFlux.H:117

Referenced by ERF::estTimeStep(), evaluate_momentum_traction(), evaluate_scalar_flux_in(), and wall_rate_for_face().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ neutral_log_momentum_state()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE NeutralLogMomentumState erf_cloud_chamber_wall_flux::neutral_log_momentum_state ( amrex::Real  U_t,
amrex::Real  wall_distance,
amrex::Real  z0_m 
)
noexcept
222 {
223  const amrex::Real log_m = std::log(wall_distance / z0_m);
224  const amrex::Real k_over_log = KAPPA / log_m;
225  return {log_m, k_over_log * k_over_log, k_over_log * U_t};
226 }

Referenced by evaluate_momentum_traction().

Here is the caller graph for this function:

◆ neutral_log_scalar_coefficient()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::neutral_log_scalar_coefficient ( amrex::Real  wall_distance,
amrex::Real  z0_m,
amrex::Real  z0_scalar 
)
noexcept
234 {
235  const amrex::Real log_m = std::log(wall_distance / z0_m);
236  const amrex::Real log_s = std::log(wall_distance / z0_scalar);
237  return (KAPPA * KAPPA) / (log_m * log_s);
238 }

Referenced by evaluate_scalar_flux_in(), and wall_rate_for_face().

Here is the caller graph for this function:

◆ neutral_log_traction_on_fluid()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::GpuArray<amrex::Real, AMREX_SPACEDIM> erf_cloud_chamber_wall_flux::neutral_log_traction_on_fluid ( const MomentumWallSample sample,
const NeutralLogMomentumState neutral 
)
noexcept
360 {
361  const amrex::Real factor =
362  -sample.rho * neutral.C_D * sample.U_t;
363  return {factor * sample.u_t[0],
364  factor * sample.u_t[1],
365  factor * sample.u_t[2]};
366 }

Referenced by evaluate_momentum_traction().

Here is the caller graph for this function:

◆ neutral_scalar_rate()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::neutral_scalar_rate ( amrex::Real  coefficient,
amrex::Real  U_t,
amrex::Real  dx_inv 
)
noexcept
374 {
375  return coefficient * U_t * dx_inv;
376 }

Referenced by wall_rate_for_face().

Here is the caller graph for this function:

◆ owns()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool erf_cloud_chamber_wall_flux::owns ( const WallFlux flux,
ScalarChannel  channel 
)
noexcept
212 {
213  return (flux.owned_channels & scalar_channel_mask(channel)) != 0;
214 }

Referenced by apply_face().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ primitive_component()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int erf_cloud_chamber_wall_flux::primitive_component ( ScalarChannel  channel)
noexcept
153 {
154  switch (channel) {
155  case ScalarChannel::Heat:
156  return PrimTheta_comp;
157  case ScalarChannel::Vapor:
158  return PrimQ1_comp;
159  case ScalarChannel::CloudWater:
160  return PrimQ2_comp;
161  case ScalarChannel::None:
162  break;
163  }
164  return -1;
165 }
#define PrimQ2_comp
Definition: ERF_IndexDefines.H:62

Referenced by apply_face().

Here is the caller graph for this function:

◆ relative_tangential_velocity_cell_centered()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::GpuArray<amrex::Real, AMREX_SPACEDIM> erf_cloud_chamber_wall_flux::relative_tangential_velocity_cell_centered ( int  dir,
int  i,
int  j,
int  k,
const amrex::Array4< const amrex::Real > &  u,
const amrex::Array4< const amrex::Real > &  v,
const amrex::Array4< const amrex::Real > &  w,
const erf_wall_thermodynamics::FaceWall wall 
)
noexcept
636 {
637  const amrex::Real uc =
638  amrex::Real(0.5) * (u(i,j,k) + u(i+1,j,k)) - wall.wall_velocity[0];
639  const amrex::Real vc =
640  amrex::Real(0.5) * (v(i,j,k) + v(i,j+1,k)) - wall.wall_velocity[1];
641  const amrex::Real wc =
642  amrex::Real(0.5) * (w(i,j,k) + w(i,j,k+1)) - wall.wall_velocity[2];
643  amrex::GpuArray<amrex::Real, AMREX_SPACEDIM> result{uc, vc, wc};
644  result[dir] = amrex::Real(0.0);
645  return result;
646 }
amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > wall_velocity
Definition: ERF_WallThermodynamics.H:67

Referenced by tangential_speed(), and erf_cloud_chamber_wall_stress::wall_traction_at_cell().

Here is the caller graph for this function:

◆ requires_tangential_momentum()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool erf_cloud_chamber_wall_flux::requires_tangential_momentum ( const erf_wall_thermodynamics::FaceWall wall)
noexcept

◆ requires_tangential_speed()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool erf_cloud_chamber_wall_flux::requires_tangential_speed ( const erf_wall_thermodynamics::FaceWall wall,
ScalarChannel  channel 
)
noexcept
442 {
443  using namespace erf_wall_thermodynamics;
444 
445  switch (channel) {
446  case ScalarChannel::Heat:
448  (wall.heat.model == ScalarModel::BulkAero ||
450  case ScalarChannel::Vapor:
451  return wall.moisture == MoistureMode::WetEquilibrium &&
452  (wall.vapor.model == ScalarModel::BulkAero ||
454  case ScalarChannel::CloudWater:
455  case ScalarChannel::None:
456  return false;
457  }
458 
459  return false;
460 }
ThermalMode mode
Definition: ERF_WallThermodynamics.H:43

Referenced by apply_face(), has_velocity_dependent_scalar_wall(), and wall_rate_requires_tangential_speed().

Here is the caller graph for this function:

◆ resolved_theta_flux_in()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::resolved_theta_flux_in ( amrex::Real  rho,
amrex::Real  alpha_T,
amrex::Real  wall_temperature_K,
amrex::Real  theta_air,
amrex::Real  p_hse,
amrex::Real  dx_inv,
amrex::Real  rdOcp 
)
noexcept
700 {
701  const amrex::Real theta_wall =
702  wall_temperature_K * std::pow(p_0 / p_hse, rdOcp);
703  return rho * alpha_T * (theta_wall - theta_air) *
704  amrex::Real(2.0) * dx_inv;
705 }

Referenced by evaluate_scalar_flux_in().

Here is the caller graph for this function:

◆ resolved_vapor_flux_in()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::resolved_vapor_flux_in ( amrex::Real  rho,
amrex::Real  alpha_C,
amrex::Real  wall_temperature_K,
amrex::Real  qv_air,
amrex::Real  p_hse,
amrex::Real  dx_inv 
)
noexcept
717 {
718  amrex::Real qv_wall = amrex::Real(0.0);
719  erf_qsatw(
720  wall_temperature_K,
721  p_hse * amrex::Real(0.01),
722  qv_wall);
723  return rho * alpha_C * (qv_wall - qv_air) *
724  amrex::Real(2.0) * dx_inv;
725 }

Referenced by evaluate_scalar_flux_in().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ scalar_channel_from_quantity()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE ScalarChannel erf_cloud_chamber_wall_flux::scalar_channel_from_quantity ( int  quantity)
noexcept
142 {
143  if (quantity == RhoTheta_comp) { return ScalarChannel::Heat; }
144  if (quantity == RhoQ1_comp) { return ScalarChannel::Vapor; }
145  if (quantity == RhoQ2_comp) { return ScalarChannel::CloudWater; }
146  return ScalarChannel::None;
147 }
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:40
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:46
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:45

Referenced by apply_face().

Here is the caller graph for this function:

◆ scalar_channel_mask()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE unsigned char erf_cloud_chamber_wall_flux::scalar_channel_mask ( ScalarChannel  channel)
noexcept
193 {
194  switch (channel) {
195  case ScalarChannel::Heat:
196  return OwnHeat;
197  case ScalarChannel::Vapor:
198  return OwnVapor;
199  case ScalarChannel::CloudWater:
200  return OwnCloudWater;
201  case ScalarChannel::None:
202  return OwnNone;
203  }
204 
205  return OwnNone;
206 }

Referenced by evaluate_scalar_flux_in(), and owns().

Here is the caller graph for this function:

◆ scalar_flux_in()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::scalar_flux_in ( const WallFlux flux,
ScalarChannel  channel 
)
noexcept
910 {
911  switch (channel) {
912  case ScalarChannel::Heat:
913  return flux.rhoTheta_in;
914  case ScalarChannel::Vapor:
915  return flux.rhoQv_in;
916  case ScalarChannel::CloudWater:
917  return flux.rhoQc_in;
918  case ScalarChannel::None:
919  return amrex::Real(0.0);
920  }
921 
922  return amrex::Real(0.0);
923 }

Referenced by apply_face().

Here is the caller graph for this function:

◆ scalar_flux_replacement()

template<int DIR, bool HIGH>
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE ScalarFluxReplacement erf_cloud_chamber_wall_flux::scalar_flux_replacement ( amrex::Real  old_flux,
amrex::Real  inward_flux,
amrex::Real  dx_inv 
)
noexcept
933 {
934  const amrex::Real new_flux =
935  to_coordinate_flux<DIR,HIGH>(inward_flux);
936  const amrex::Real correction =
937  (new_flux - old_flux) * dx_inv;
938  return {
939  new_flux,
940  HIGH ? -correction : correction
941  };
942 }

◆ tangential_magnitude()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::tangential_magnitude ( const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &  u_t)
noexcept
653 {
654  return std::sqrt(u_t[0]*u_t[0] + u_t[1]*u_t[1] + u_t[2]*u_t[2]);
655 }

Referenced by tangential_speed(), and erf_cloud_chamber_wall_stress::wall_traction_at_cell().

Here is the caller graph for this function:

◆ tangential_speed()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::tangential_speed ( int  dir,
int  i,
int  j,
int  k,
const amrex::Array4< const amrex::Real > &  u,
const amrex::Array4< const amrex::Real > &  v,
const amrex::Array4< const amrex::Real > &  w,
const erf_wall_thermodynamics::FaceWall wall 
)
noexcept
666 {
667  return tangential_magnitude(
668  relative_tangential_velocity_cell_centered(dir, i, j, k, u, v, w, wall));
669 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real tangential_magnitude(const amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > &u_t) noexcept
Definition: ERF_CloudChamberWallFlux.H:651
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > relative_tangential_velocity_cell_centered(int dir, int i, int j, int k, const amrex::Array4< const amrex::Real > &u, const amrex::Array4< const amrex::Real > &v, const amrex::Array4< const amrex::Real > &w, const erf_wall_thermodynamics::FaceWall &wall) noexcept
Definition: ERF_CloudChamberWallFlux.H:630

Referenced by apply_face().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ tangential_speed_cell_centered()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::tangential_speed_cell_centered ( int  dir,
int  i,
int  j,
int  k,
const amrex::Array4< const amrex::Real > &  velocity,
const erf_wall_thermodynamics::FaceWall wall 
)
noexcept
678 {
679  const amrex::Real uc = velocity(i,j,k,0) - wall.wall_velocity[0];
680  const amrex::Real vc = velocity(i,j,k,1) - wall.wall_velocity[1];
681  const amrex::Real wc = velocity(i,j,k,2) - wall.wall_velocity[2];
682  const amrex::Real normal = (dir == 0) ? uc : ((dir == 1) ? vc : wc);
683  const amrex::Real t0 = uc - ((dir == 0) ? normal : amrex::Real(0.0));
684  const amrex::Real t1 = vc - ((dir == 1) ? normal : amrex::Real(0.0));
685  const amrex::Real t2 = wc - ((dir == 2) ? normal : amrex::Real(0.0));
686  return std::sqrt(t0*t0 + t1*t1 + t2*t2);
687 }
real(c_double), parameter t0
Definition: ERF_module_model_constants.F90:39

Referenced by ERF::estTimeStep().

Here is the caller graph for this function:

◆ to_coordinate_flux()

template<int DIR, bool HIGH>
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::to_coordinate_flux ( amrex::Real  inward)
noexcept
564 {
565  // Wall evaluators are inward-positive. ERF stores coordinate-positive
566  // face fluxes, so this is the one low/high sign adapter for every scalar.
567  amrex::ignore_unused(DIR);
568  return HIGH ? -inward : inward;
569 }

◆ traction_from_local_inward()

template<int DIR, bool HIGH>
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::GpuArray<amrex::Real, AMREX_SPACEDIM> erf_cloud_chamber_wall_flux::traction_from_local_inward ( amrex::Real  normal_in,
amrex::Real  tangent_a,
amrex::Real  tangent_b 
)
noexcept
578 {
579  // Physical traction result/orientation support. The stress adapter maps
580  // this pure result into ERF tau_ij arrays for active wall models.
581  amrex::GpuArray<amrex::Real, AMREX_SPACEDIM> result{};
582  result[DIR] = to_coordinate_flux<DIR,HIGH>(normal_in);
583  if constexpr (DIR == 0) {
584  result[1] = tangent_a;
585  result[2] = tangent_b;
586  } else if constexpr (DIR == 1) {
587  result[0] = tangent_a;
588  result[2] = tangent_b;
589  } else {
590  result[0] = tangent_a;
591  result[1] = tangent_b;
592  }
593  return result;
594 }

◆ wall_dt_from_max_rate()

AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::wall_dt_from_max_rate ( amrex::Real  max_rate,
amrex::Real  wall_cfl = amrex::Real(0.5) 
)
noexcept
1079 {
1080  return max_rate > amrex::Real(0.0) ?
1081  wall_cfl / max_rate : amrex::Real(1.0e30);
1082 }

Referenced by ERF::estTimeStep().

Here is the caller graph for this function:

◆ wall_owns_scalar_channel()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool erf_cloud_chamber_wall_flux::wall_owns_scalar_channel ( const erf_wall_thermodynamics::FaceWall wall,
ScalarChannel  channel 
)
noexcept
173 {
174  using namespace erf_wall_thermodynamics;
175 
176  switch (channel) {
177  case ScalarChannel::Heat:
179  case ScalarChannel::Vapor:
180  case ScalarChannel::CloudWater:
182  case ScalarChannel::None:
183  return false;
184  }
185 
186  return false;
187 }

Referenced by apply_face(), and evaluate_scalar_flux_in().

Here is the caller graph for this function:

◆ wall_rate_for_face() [1/3]

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::wall_rate_for_face ( const erf_wall_thermodynamics::FaceWall wall,
amrex::Real  theta_air,
amrex::Real  qv_air,
amrex::Real  p_hse,
amrex::Real  rdOcp,
amrex::Real  U_t,
amrex::Real  dx_inv,
int  gravity_sign 
)
noexcept
552 {
553  const FaceRuntimeCoefficients runtime = most_wall_coefficients(
554  wall, theta_air, qv_air, p_hse, rdOcp, U_t,
555  amrex::Real(0.5) / dx_inv, gravity_sign);
556  return wall_rate_for_face(wall, U_t, dx_inv, runtime);
557 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real wall_rate_for_face(const erf_wall_thermodynamics::FaceWall &wall, amrex::Real theta_air, amrex::Real qv_air, amrex::Real p_hse, amrex::Real rdOcp, amrex::Real U_t, amrex::Real dx_inv, int gravity_sign) noexcept
Definition: ERF_CloudChamberWallFlux.H:543
Here is the call graph for this function:

◆ wall_rate_for_face() [2/3]

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::wall_rate_for_face ( const erf_wall_thermodynamics::FaceWall wall,
amrex::Real  U_t,
amrex::Real  dx_inv 
)
noexcept
536 {
537  return wall_rate_for_face(wall, U_t, dx_inv, FaceRuntimeCoefficients{});
538 }
Here is the call graph for this function:

◆ wall_rate_for_face() [3/3]

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_cloud_chamber_wall_flux::wall_rate_for_face ( const erf_wall_thermodynamics::FaceWall wall,
amrex::Real  U_t,
amrex::Real  dx_inv,
const FaceRuntimeCoefficients runtime 
)
noexcept
491 {
492  using namespace erf_wall_thermodynamics;
494  return amrex::Real(0.0);
495  }
496  if (wall_uses_most(wall)) {
497  AMREX_ALWAYS_ASSERT(runtime.valid != 0);
498  }
499  const amrex::Real wall_distance = amrex::Real(0.5) / dx_inv;
500  amrex::Real rate = momentum_rate_for_face(wall, U_t, dx_inv, runtime);
501 
503  if (wall.heat.model == ScalarModel::BulkAero) {
504  const amrex::Real C_H = wall.heat.provider == CoefficientProvider::MOST ?
505  runtime.C_H : wall.heat.coefficient;
506  rate = amrex::max(rate, neutral_scalar_rate(C_H, U_t, dx_inv));
507  } else if (wall.heat.model == ScalarModel::NeutralRoughnessLog) {
508  rate = amrex::max(rate, neutral_scalar_rate(
510  wall_distance, wall.momentum.z0_m, wall.heat.z0),
511  U_t, dx_inv));
512  }
513  }
515  if (wall.vapor.model == ScalarModel::BulkAero) {
517  runtime.C_E : wall.vapor.coefficient;
518  rate = amrex::max(rate, neutral_scalar_rate(C_E, U_t, dx_inv));
519  } else if (wall.vapor.model == ScalarModel::NeutralRoughnessLog) {
520  rate = amrex::max(rate, neutral_scalar_rate(
522  wall_distance, wall.momentum.z0_m, wall.vapor.z0),
523  U_t, dx_inv));
524  }
525  }
526  return rate;
527 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool wall_rate_requires_tangential_speed(const erf_wall_thermodynamics::FaceWall &wall) noexcept
Definition: ERF_CloudChamberWallFlux.H:475
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real momentum_rate_for_face(const erf_wall_thermodynamics::FaceWall &wall, amrex::Real U_t, amrex::Real dx_inv, const FaceRuntimeCoefficients &runtime=FaceRuntimeCoefficients{}) noexcept
Definition: ERF_CloudChamberWallFlux.H:410
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real neutral_scalar_rate(amrex::Real coefficient, amrex::Real U_t, amrex::Real dx_inv) noexcept
Definition: ERF_CloudChamberWallFlux.H:371
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool wall_uses_most(const erf_wall_thermodynamics::FaceWall &wall) noexcept
Definition: ERF_CloudChamberWallFlux.H:128

Referenced by ERF::estTimeStep(), and wall_rate_for_face().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wall_rate_requires_tangential_speed()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool erf_cloud_chamber_wall_flux::wall_rate_requires_tangential_speed ( const erf_wall_thermodynamics::FaceWall wall)
noexcept
477 {
478  return requires_tangential_momentum(wall) ||
479  requires_tangential_speed(wall, ScalarChannel::Heat) ||
480  requires_tangential_speed(wall, ScalarChannel::Vapor);
481 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool requires_tangential_momentum(const erf_wall_thermodynamics::FaceWall &wall) noexcept
Definition: ERF_CloudChamberWallFlux.H:465

Referenced by ERF::estTimeStep(), and wall_rate_for_face().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wall_uses_most()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool erf_cloud_chamber_wall_flux::wall_uses_most ( const erf_wall_thermodynamics::FaceWall wall)
noexcept
129 {
130  using namespace erf_wall_thermodynamics;
131  return (wall.momentum.model == MomentumModel::BulkAero &&
133  (wall.heat.model == ScalarModel::BulkAero &&
135  wall_uses_most_vapor(wall);
136 }

Referenced by wall_rate_for_face().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ wall_uses_most_vapor()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool erf_cloud_chamber_wall_flux::wall_uses_most_vapor ( const erf_wall_thermodynamics::FaceWall wall)
noexcept
118 {
119  using namespace erf_wall_thermodynamics;
120  return wall.moisture == MoistureMode::WetEquilibrium &&
123 }

Referenced by most_wall_coefficients(), and wall_uses_most().

Here is the caller graph for this function: