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

Namespaces

 constants
 

Classes

struct  ShocEnergyFixerView
 

Enumerations

enum class  InitRunOn { Host , Device }
 

Functions

ShocEnergyFixerView make_energy_fixer_view (ShocColumnData &col, bool include_momentum_energy)
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int diagnose_active_top (const amrex::Array4< const amrex::Real > &tke, int ic, int nlev) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void apply_energy_fix_column (const ShocEnergyFixerView &v, int ic, double dt_d) noexcept
 
InitRunOn default_init_run_on ()
 
void set_fab_val (amrex::FArrayBox &fab, amrex::Real value, InitRunOn run_on)
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real height_agl (amrex::Real z, amrex::Real z_sfc) noexcept
 
void sync_if_needed ()
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real latent_sublimation () noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real condensate_latent_heat (amrex::Real qc, amrex::Real qi) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real theta_from_thetal (amrex::Real thetal, amrex::Real qc, amrex::Real qi, amrex::Real exner) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real temperature_from_thetal (amrex::Real thetal, amrex::Real qc, amrex::Real qi, amrex::Real exner) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real thetal_from_theta (amrex::Real theta, amrex::Real qc, amrex::Real qi, amrex::Real exner) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real moist_energy (amrex::Real tabs, amrex::Real z, amrex::Real qv, amrex::Real qc, amrex::Real qi, amrex::Real u, amrex::Real v, amrex::Real tke) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void reconstruct_pdf_state (amrex::Real thetal, amrex::Real qw, amrex::Real exner, amrex::Real qi_seed, amrex::Real pdf_ql, amrex::Real &tabs, amrex::Real &qv, amrex::Real &qc, amrex::Real &qi) noexcept
 

Enumeration Type Documentation

◆ InitRunOn

enum shoc::InitRunOn
strong
Enumerator
Host 
Device 
10  {
11  Host,
12  Device
13 };

Function Documentation

◆ apply_energy_fix_column()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void shoc::apply_energy_fix_column ( const ShocEnergyFixerView v,
int  ic,
double  dt_d 
)
noexcept
90 {
91  amrex::Real dt = static_cast<amrex::Real>(dt_d);
92 
93  const int shoc_top = diagnose_active_top(v.tke, ic, v.nlev);
94  if (shoc_top < 0) {
95  return;
96  }
97 
98  amrex::Real energy_before = amrex::Real(0.0);
99  amrex::Real energy_after = amrex::Real(0.0);
100  amrex::Real air_mass = amrex::Real(0.0);
101 
102  for (int k = 0; k <= shoc_top; ++k) {
103  const amrex::Real mass = v.rho(ic,k,0) * v.dz(ic,k,0);
104  const amrex::Real tabs_old = shoc::temperature_from_thetal(v.thetal_base(ic,k,0),
105  v.qc_base(ic,k,0),
106  v.qi_base(ic,k,0),
107  v.exner(ic,k,0));
108 
109  amrex::Real tabs_new = amrex::Real(0.0);
110  amrex::Real qv_new = amrex::Real(0.0);
111  amrex::Real qc_new = amrex::Real(0.0);
112  amrex::Real qi_new = amrex::Real(0.0);
113  shoc::reconstruct_pdf_state(v.thetal(ic,k,0), v.qw(ic,k,0), v.exner(ic,k,0),
114  v.qi_base(ic,k,0), v.shoc_ql(ic,k,0),
115  tabs_new, qv_new, qc_new, qi_new);
116 
117  energy_before += mass * moist_energy(tabs_old, v.zt(ic,k,0),
118  v.qv_base(ic,k,0), v.qc_base(ic,k,0), v.qi_base(ic,k,0),
119  v.u_base(ic,k,0), v.v_base(ic,k,0), v.tke_base(ic,k,0));
120  const amrex::Real u_after = v.include_momentum_energy
121  ? v.u(ic,k,0) : v.u_base(ic,k,0);
122  const amrex::Real v_after = v.include_momentum_energy
123  ? v.v(ic,k,0) : v.v_base(ic,k,0);
124  energy_after += mass * moist_energy(tabs_new, v.zt(ic,k,0),
125  qv_new, qc_new, qi_new,
126  u_after, v_after, v.tke(ic,k,0));
127  air_mass += mass;
128  }
129 
130  if (air_mass <= amrex::Real(0.0)) {
131  return;
132  }
133 
134  const amrex::Real latent_flux_coeff = L_v + constants::latent_ice();
135  const amrex::Real energy_target = energy_before
136  + dt * v.rho(ic,0,0)
137  * (Cp_d * v.exner(ic,0,0) * v.surf_sens_flux(ic,0,0)
138  + latent_flux_coeff * v.surf_lat_flux(ic,0,0));
139  const amrex::Real delta_tabs = (energy_target - energy_after) / (Cp_d * air_mass);
140 
141  for (int k = 0; k <= shoc_top; ++k) {
142  v.thetal(ic,k,0) += delta_tabs / amrex::max(v.exner(ic,k,0), amrex::Real(1.0e-12));
143  }
144 }
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:36
constexpr amrex::Real L_v
Definition: ERF_Constants.H:51
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real latent_ice() noexcept
Definition: ERF_ShocConstants.H:38
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int diagnose_active_top(const amrex::Array4< const amrex::Real > &tke, int ic, int nlev) noexcept
Definition: ERF_ShocEnergyFixer.H:71
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void reconstruct_pdf_state(amrex::Real thetal, amrex::Real qw, amrex::Real exner, amrex::Real qi_seed, amrex::Real pdf_ql, amrex::Real &tabs, amrex::Real &qv, amrex::Real &qc, amrex::Real &qi) noexcept
Definition: ERF_ShocThermoUtils.H:86
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real moist_energy(amrex::Real tabs, amrex::Real z, amrex::Real qv, amrex::Real qc, amrex::Real qi, amrex::Real u, amrex::Real v, amrex::Real tke) noexcept
Definition: ERF_ShocThermoUtils.H:64
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real temperature_from_thetal(amrex::Real thetal, amrex::Real qc, amrex::Real qi, amrex::Real exner) noexcept
Definition: ERF_ShocThermoUtils.H:40

Referenced by ShocEnergyFixer::apply_column(), and ShocImplicit::finalize_from_pdf().

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

◆ condensate_latent_heat()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real shoc::condensate_latent_heat ( amrex::Real  qc,
amrex::Real  qi 
)
noexcept
21 {
22  return L_v * amrex::max(amrex::Real(0.0), qc)
23  + latent_sublimation() * amrex::max(amrex::Real(0.0), qi);
24 }
@ qc
Definition: ERF_SatAdj.H:42
@ qi
Definition: ERF_WDM6.H:28
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real latent_sublimation() noexcept
Definition: ERF_ShocThermoUtils.H:12

Referenced by temperature_from_thetal(), theta_from_thetal(), and thetal_from_theta().

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

◆ default_init_run_on()

InitRunOn shoc::default_init_run_on ( )
inline
28 {
29 #ifdef AMREX_USE_GPU
30  return InitRunOn::Device;
31 #else
32  return InitRunOn::Host;
33 #endif
34 }

Referenced by ShocDriver::advance().

Here is the caller graph for this function:

◆ diagnose_active_top()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int shoc::diagnose_active_top ( const amrex::Array4< const amrex::Real > &  tke,
int  ic,
int  nlev 
)
noexcept
74 {
75  int shoc_top = -1;
76  for (int k = nlev - 1; k >= 0; --k) {
77  if (tke(ic,k,0) > constants::active_tke_threshold()) {
78  shoc_top = k;
79  break;
80  }
81  }
82  return shoc_top;
83 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real active_tke_threshold() noexcept
Definition: ERF_ShocConstants.H:32

Referenced by apply_energy_fix_column(), and ShocEnergyFixer::diagnose_active_top().

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

◆ height_agl()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real shoc::height_agl ( amrex::Real  z,
amrex::Real  z_sfc 
)
noexcept
51 {
52  return amrex::max(amrex::Real(0.0), z - z_sfc);
53 }

Referenced by ShocStructure::diagnose_length_and_brunt(), ShocStructure::diagnose_pblh(), ShocStructure::diagnose_surface_layer(), and ShocTKE::diagnose_tke_and_diffusivities().

Here is the caller graph for this function:

◆ latent_sublimation()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real shoc::latent_sublimation ( )
noexcept
13 {
14  return L_v + constants::latent_ice();
15 }

Referenced by condensate_latent_heat(), and moist_energy().

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

◆ make_energy_fixer_view()

ShocEnergyFixerView shoc::make_energy_fixer_view ( ShocColumnData col,
bool  include_momentum_energy 
)
inline
43 {
44  return {
45  col.rho.const_array(),
46  col.dz.const_array(),
47  col.zt.const_array(),
48  col.exner.const_array(),
49  col.surf_sens_flux.const_array(),
50  col.surf_lat_flux.const_array(),
51  col.thetal_base.const_array(),
52  col.qv_base.const_array(),
53  col.qc_base.const_array(),
54  col.qi_base.const_array(),
55  col.u_base.const_array(),
56  col.v_base.const_array(),
57  col.tke_base_state.const_array(),
58  col.thetal.array(),
59  col.qw.const_array(),
60  col.u.const_array(),
61  col.v.const_array(),
62  col.tke.const_array(),
63  col.shoc_ql.const_array(),
64  col.layout.nlev,
65  include_momentum_energy
66  };
67 }
amrex::FArrayBox dz
Definition: ERF_ShocTypes.H:78
amrex::FArrayBox surf_lat_flux
Definition: ERF_ShocTypes.H:145
amrex::FArrayBox v_base
Definition: ERF_ShocTypes.H:134
amrex::FArrayBox rho
Definition: ERF_ShocTypes.H:81
amrex::FArrayBox tke_base_state
Definition: ERF_ShocTypes.H:135
amrex::FArrayBox qv_base
Definition: ERF_ShocTypes.H:130
amrex::FArrayBox shoc_ql
Definition: ERF_ShocTypes.H:111
amrex::FArrayBox tke
Definition: ERF_ShocTypes.H:91
amrex::FArrayBox qi_base
Definition: ERF_ShocTypes.H:132
amrex::FArrayBox exner
Definition: ERF_ShocTypes.H:83
amrex::FArrayBox u_base
Definition: ERF_ShocTypes.H:133
amrex::FArrayBox qc_base
Definition: ERF_ShocTypes.H:131
ShocColumnLayout layout
Definition: ERF_ShocTypes.H:73
amrex::FArrayBox surf_sens_flux
Definition: ERF_ShocTypes.H:144
amrex::FArrayBox qw
Definition: ERF_ShocTypes.H:89
amrex::FArrayBox v
Definition: ERF_ShocTypes.H:93
amrex::FArrayBox zt
Definition: ERF_ShocTypes.H:76
amrex::FArrayBox u
Definition: ERF_ShocTypes.H:92
amrex::FArrayBox thetal_base
Definition: ERF_ShocTypes.H:128
amrex::FArrayBox thetal
Definition: ERF_ShocTypes.H:85
int nlev
Definition: ERF_ShocTypes.H:64

Referenced by ShocEnergyFixer::apply_column(), and ShocImplicit::finalize_from_pdf().

Here is the caller graph for this function:

◆ moist_energy()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real shoc::moist_energy ( amrex::Real  tabs,
amrex::Real  z,
amrex::Real  qv,
amrex::Real  qc,
amrex::Real  qi,
amrex::Real  u,
amrex::Real  v,
amrex::Real  tke 
)
noexcept
72 {
73  // Ice-reference moist energy has no explicit qi term; qi is retained in
74  // the signature so callers pass a complete vapor/liquid/ice state.
75  amrex::ignore_unused(qi);
76  return Cp_d * tabs
77  + CONST_GRAV * z
78  + amrex::Real(0.5) * (u * u + v * v)
79  + tke
81  + constants::latent_ice() * amrex::max(amrex::Real(0.0), qc);
82 }
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:56
@ tabs
Definition: ERF_Kessler.H:27
@ qv
Definition: ERF_Kessler.H:31

Referenced by apply_energy_fix_column().

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

◆ reconstruct_pdf_state()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void shoc::reconstruct_pdf_state ( amrex::Real  thetal,
amrex::Real  qw,
amrex::Real  exner,
amrex::Real  qi_seed,
amrex::Real  pdf_ql,
amrex::Real tabs,
amrex::Real qv,
amrex::Real qc,
amrex::Real qi 
)
noexcept
95 {
96  // Interim native-SHOC contract: preserve any existing ice seed for
97  // phase-aware thermodynamics, but do not create or repartition cloud ice.
98  const amrex::Real qi_total = shoc_clamp(qi_seed, amrex::Real(0.0), amrex::max(amrex::Real(0.0), qw));
99  const amrex::Real ql_total = shoc_clamp(pdf_ql, amrex::Real(0.0), amrex::max(amrex::Real(0.0), qw - qi_total));
100 
101  qc = ql_total;
102  qi = qi_total;
103  tabs = temperature_from_thetal(thetal, qc, qi, exner);
104  qv = amrex::max(amrex::Real(0.0), qw - qc - qi);
105 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE T shoc_clamp(T value, T lo, T hi)
Definition: ERF_ShocTypes.H:234

Referenced by apply_energy_fix_column(), and ShocImplicit::finalize_from_pdf().

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

◆ set_fab_val()

void shoc::set_fab_val ( amrex::FArrayBox &  fab,
amrex::Real  value,
InitRunOn  run_on 
)
inline
40 {
41  if (run_on == InitRunOn::Host) {
42  fab.template setVal<amrex::RunOn::Host>(value);
43  } else {
44  fab.template setVal<amrex::RunOn::Device>(value);
45  }
46 }

Referenced by reset_shoc_column_data().

Here is the caller graph for this function:

◆ sync_if_needed()

void shoc::sync_if_needed ( )
inline
57 {
58  // Test-owned helper for host-side assertions. Production SHOC code should
59  // keep synchronization out of the runtime path and use this only through
60  // shoc_test::run_and_sync or other explicit test utilities.
61 #ifdef AMREX_USE_GPU
62  amrex::Gpu::streamSynchronize();
63 #endif
64 }

◆ temperature_from_thetal()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real shoc::temperature_from_thetal ( amrex::Real  thetal,
amrex::Real  qc,
amrex::Real  qi,
amrex::Real  exner 
)
noexcept
44 {
45  return amrex::max(constants::min_temp(),
46  thetal * amrex::max(exner, amrex::Real(1.0e-12))
48 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real min_temp() noexcept
Definition: ERF_ShocConstants.H:41
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real condensate_latent_heat(amrex::Real qc, amrex::Real qi) noexcept
Definition: ERF_ShocThermoUtils.H:19

Referenced by apply_energy_fix_column(), ShocImplicit::compute_temperature(), and reconstruct_pdf_state().

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

◆ theta_from_thetal()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real shoc::theta_from_thetal ( amrex::Real  thetal,
amrex::Real  qc,
amrex::Real  qi,
amrex::Real  exner 
)
noexcept
32 {
33  return thetal
35  / (Cp_d * amrex::max(exner, amrex::Real(1.0e-12)));
36 }
Here is the call graph for this function:

◆ thetal_from_theta()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real shoc::thetal_from_theta ( amrex::Real  theta,
amrex::Real  qc,
amrex::Real  qi,
amrex::Real  exner 
)
noexcept
56 {
57  return theta
59  / (Cp_d * amrex::max(exner, amrex::Real(1.0e-12)));
60 }
@ theta
Definition: ERF_SLM.H:19

Referenced by ShocPreprocess::fill_columns().

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