ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
SolverChoice Struct Reference

#include <ERF_DataStruct.H>

Collaboration diagram for SolverChoice:

Public Member Functions

void init_params (int max_level, std::string pp_prefix)
 Read solver-wide algorithmic options from the input parameter database. More...
 
void check_params (int max_level, const amrex::Vector< amrex::Geometry > &geom_vect, amrex::GpuArray< ERF_BC, AMREX_SPACEDIM *2 > phys_bc_type)
 Validate solver options after geometry and boundary conditions are known. More...
 
void display (int max_level, std::string pp_prefix)
 Print the configured solver, physics, and transport options. More...
 
void build_coriolis_forcings_const_lat (std::string pp_prefix)
 Build constant-latitude Coriolis forcing parameters. More...
 
bool read_int_string (int max_level, const char *string_to_read, amrex::Vector< int > &vec_to_fill, int default_int)
 Read one integer value or one value per AMR level. More...
 
bool use_perturbation (int lev) const
 Query whether any turbulent perturbation mode is enabled on a level. More...
 
bool use_direct_perturbation (int lev) const
 Query whether direct turbulent perturbations are enabled on a level. More...
 
bool use_source_perturbation (int lev) const
 Query whether source-term turbulent perturbations are enabled on a level. More...
 
bool use_wvel_perturbation (int lev) const
 Query whether vertical-velocity CPM perturbations are enabled on a level. More...
 
bool uses_shoc_family () const noexcept
 Query whether any SHOC-family PBL scheme is active. More...
 
bool host_owns_vertical_momentum_diffusion () const noexcept
 Test whether the host owns momentum diffusion. More...
 
bool host_owns_vertical_scalar_diffusion () const noexcept
 Test whether the host owns scalar diffusion. More...
 
bool pbl_suppresses_microphysics_condensation () const noexcept
 Query whether the active PBL scheme suppresses microphysics condensation. More...
 
bool any_perturbation () const
 Query whether any level uses a turbulent perturbation mode. More...
 
bool rad_uses_interface () const
 True for the models that run through the IRadiation interface (RRTMGP, Simple); the two-stream model has its own class. More...
 
bool rad_feeds_lsm () const
 True when the radiation model's outputs feed the land model (downwelling shortwave, downwelling longwave, solar zenith angle). RRTMGP writes them for any land model through lsm_output_ptrs; the two-stream model writes the broadband three for Noah-MP only (TwoStreamRadiation::write_land_forcing), since SLM wants the visible / near-infrared direct / diffuse split it does not compute. Both register the outputs in ERF::init_stuff and write them in ERF::advance_radiation; every site that encodes that rule must use this predicate so wiring another model in (e.g. Simple, which already runs through the interface) is one edit. More...
 

Static Public Member Functions

static void set_mesh_type (MeshType new_mesh_type)
 Override the globally selected mesh type. More...
 

Public Attributes

AdvChoice advChoice
 Advection-related options. More...
 
DiffChoice diffChoice
 Diffusion-related options. More...
 
DampingChoice dampingChoice
 Damping-related options. More...
 
SpongeChoice spongeChoice
 Sponge-layer options. More...
 
amrex::Vector< TurbChoice > turbChoice
 Turbulence options for each AMR level. More...
 
EBChoice ebChoice
 Embedded-boundary options. More...
 
RadChoice radChoice
 
int force_stage1_single_substep = 1
 Flag forcing a single substep in the first RK stage. More...
 
amrex::Vector< SubsteppingType > substepping_type
 Acoustic substepping type for each AMR level. More...
 
amrex::Vector< int > anelastic
 Per-level flag selecting anelastic dynamics. More...
 
amrex::Vector< AnelasticType > anelastic_type
 Per-level two-stage scheme used by the anelastic integrator. More...
 
amrex::Vector< int > fixed_density
 Per-level flag selecting fixed-density treatment; always 1 at an anelastic level. More...
 
amrex::Vector< int > project_initial_velocity
 Per-level flag for projecting the initial velocity. More...
 
amrex::Vector< int > buoyancy_type
 Per-level buoyancy formulation selector. More...
 
amrex::Vector< int > is_land
 Per-level land/water selector. More...
 
bool substepping_diag = false
 Whether to emit extra CFL diagnostics for compressible substepping. More...
 
amrex::Real beta_s = amrex::Real(0.1)
 Time off-centering coefficient for forward weighting. More...
 
amrex::Vector< amrex::Vector< amrex::Real > > vert_implicit_fac
 Per-level, per-stage implicit vertical diffusion factors. More...
 
bool implicit_thermal_diffusion = true
 Whether implicit vertical thermal diffusion is included. More...
 
bool implicit_moisture_diffusion = true
 Whether implicit vertical moisture diffusion is included. More...
 
bool implicit_ke_diffusion = true
 Whether implicit vertical TKE diffusion is included. More...
 
bool implicit_momentum_diffusion = true
 Whether implicit vertical momentum diffusion is included. More...
 
bool implicit_before_substep = true
 Whether implicit diffusion is applied before acoustic substepping. More...
 
bool implicit_terrain_metric = false
 Whether the compact terrain-metric part of the vertical diffusion is solved implicitly. More...
 
int ncorr = 1
 Number of projection correction iterations. More...
 
std::string wall_dist_type = "poisson"
 
amrex::Real poisson_abstol = amrex::Real(1e-8)
 Absolute tolerance for the Poisson solve. More...
 
amrex::Real poisson_reltol = amrex::Real(1e-8)
 Relative tolerance for the Poisson solve. More...
 
bool test_mapfactor = false
 Whether to use test map scale factors. More...
 
int gradp_type = 0
 Terrain-fitted horizontal pressure-gradient formulation. More...
 
bool use_pert_pres_gradient = true
 Whether momentum equations use perturbational pressure gradients. More...
 
bool use_gravity = false
 Whether gravitational forcing is enabled. More...
 
bool use_coriolis = false
 Whether Coriolis forcing is enabled. More...
 
bool coriolis_3d = true
 Whether the three-dimensional Coriolis terms are included. More...
 
bool four_stream_radiation = false
 Whether the four-stream radiation approximation is enabled. More...
 
bool immersed_forcing_substep = false
 Whether immersed-forcing source terms are applied only during substeps. More...
 
bool forest_substep = false
 Whether canopy source terms are applied only during substeps. More...
 
amrex::Real if_Cd_momentum = amrex::Real(50.0)
 Immersed-forcing drag coefficient for momentum. More...
 
amrex::Real if_Cd_scalar = amrex::Real(10.0)
 Immersed-forcing drag coefficient for scalars. More...
 
bool if_implicit_drag = false
 
amrex::Real if_z0 = amrex::Real(0.1)
 Immersed-forcing roughness length [m]. More...
 
amrex::Real if_surf_temp_flux = amrex::Real(1e-8)
 Immersed-forcing surface temperature flux [K m/s]. More...
 
amrex::Real if_init_surf_temp = zero
 Initial immersed-forcing surface temperature [K]. More...
 
amrex::Real if_surf_heating_rate = zero
 Immersed-forcing surface heating rate [K/hr]. More...
 
amrex::Real if_Olen_in = amrex::Real(1e-8)
 Input Obukhov length for immersed-forcing MOST [m]. More...
 
bool if_use_most = false
 Whether immersed-forcing MOST is enabled. More...
 
bool if_snap_partial_cells = false
 
bool if_stability_correction = false
 Whether immersed-forcing stability corrections are enabled. More...
 
amrex::Real if_ws_floor = 0.001
 Wind-speed floor [m/s] in the per-step change limit of the building wall-law forcing. More...
 
amrex::Real if_damp_alpha = 0.5
 Immersed-forcing damping coefficient. More...
 
amrex::Real if_stability_wind_floor = amrex::Real(0.0)
 Wind-speed floor [m/s] behind the friction velocity of the wall law's stability estimate (0: none). More...
 
amrex::Real if_psi_cap_factor = amrex::Real(1.0)
 Cap on psi_m in the immersed momentum wall law as a fraction of ln(z/z0) (1: none). More...
 
bool use_lagged_delta_rt = true
 Whether to use lagged delta terms for moving terrain. More...
 
bool rebalance_wrf_input = true
 Whether to rebalance states from wrfinput and wrfbdy data. More...
 
amrex::Real gravity
 Effective gravitational acceleration. More...
 
amrex::Real c_p = Cp_d
 Specific heat at constant pressure for dry air [J/(kg-K)]. More...
 
amrex::Real rdOcp
 Ratio of dry-air gas constant to c_p. More...
 
amrex::Real grid_stretching_ratio = 0
 Vertical grid stretching ratio. More...
 
amrex::Real zsurf = zero
 Nominal surface height for stretched-grid setup. More...
 
amrex::Real dz0 = zero
 Initial vertical grid spacing for stretched-grid setup. More...
 
amrex::Real coriolis_factor = zero
 Twice the planetary rotation rate used for Coriolis forcing. More...
 
amrex::Real cosphi = zero
 Cosine of the latitude used for Coriolis forcing. More...
 
amrex::Real sinphi = zero
 Sine of the latitude used for Coriolis forcing. More...
 
bool custom_rhotheta_forcing = false
 Whether custom rho-theta forcing is enabled. More...
 
bool custom_moisture_forcing = false
 Whether custom moisture forcing is enabled. More...
 
bool custom_w_subsidence = false
 Whether custom vertical subsidence is enabled. More...
 
bool do_theta_advection = true
 Whether custom vertical subsidence is applied to rho-theta. More...
 
bool do_mom_advection = true
 Whether custom vertical subsidence is applied to momentum. More...
 
bool custom_geostrophic_profile = false
 Whether a custom geostrophic wind profile is used. More...
 
bool custom_forcing_prim_vars = false
 Whether custom forcing operates on primitive variables. More...
 
bool spatial_rhotheta_forcing = false
 Whether spatially varying rho-theta forcing is enabled. More...
 
bool spatial_moisture_forcing = false
 Whether spatially varying moisture forcing is enabled. More...
 
bool nudging_from_input_sounding = false
 Whether solution fields are nudged toward input sounding data. More...
 
bool nudging_from_observations = false
 Whether solution fields are nudged toward observations at stations. More...
 
amrex::Real nudging_u_z1 = amrex::Real(-1.0e36)
 
amrex::Real nudging_u_z2 = amrex::Real(1.0e36)
 
amrex::Real nudging_t_z1 = zero
 
amrex::Real nudging_t_z2 = amrex::Real(10000.0)
 
amrex::Real nudging_q_z1 = zero
 
amrex::Real nudging_q_z2 = amrex::Real(10000.0)
 
bool nudging_u = true
 
bool nudging_t = true
 
bool nudging_q = true
 
bool large_scale_forcing = false
 
std::string lsf_file = ""
 
amrex::Real lsf_timescale = zero
 
bool use_rotate_surface_flux = false
 Whether MOST surface fluxes are rotated with terrain. More...
 
bool use_eamxx_shoc = false
 Whether any level uses the EAMxx SHOC PBL scheme. More...
 
bool use_native_shoc = false
 Whether any level uses the native SHOC PBL scheme. More...
 
ShocTransportMode shoc_transport_mode = ShocTransportMode::StateUpdate
 
ShocMomentumTransport shoc_momentum_transport = ShocMomentumTransport::StateUpdate
 
bool transport_scalar = true
 Whether the passive scalar component is transported. More...
 
bool time_avg_vel = false
 Whether time-averaged velocity fields are output. More...
 
bool compute_mean_vars = false
 
std::string mean_vars_reset_mode = "plotfile"
 
amrex::Real mean_vars_reset_time = -one
 
amrex::Vector< PerturbationType > pert_type
 Turbulent perturbation type for each AMR level. More...
 
bool use_num_diff {false}
 Whether sixth-order numerical diffusion is enabled. More...
 
amrex::Real num_diff_coeff {zero}
 Numerical diffusion coefficient after input scaling. More...
 
CouplingType coupling_type
 Multilevel coupling strategy. More...
 
MoistureType moisture_type
 Moisture or microphysics model. More...
 
int sbm_nbins {4}
 
int sbm_moment_mode {1}
 
int sbm_cloud_rain_split {-1}
 
bool sbm_test_native_qc_write_fault {false}
 
bool sbm_test_donor_cfl_fault {false}
 
amrex::Vector< amrex::Real > sbm_edges
 
amrex::Vector< amrex::Real > sbm_pivots
 
amrex::Vector< amrex::Real > sbm_fixture_initial_state
 
WindFarmType windfarm_type
 Wind-farm model. More...
 
WindFarmLocType windfarm_loc_type
 Coordinate system for wind-farm turbine locations. More...
 
LandSurfaceType lsm_type
 Land-surface model. More...
 
UrbanType urban_type
 
amrex::Vector< int > urban_enabled_lev
 
RadiationType rad_type
 Radiation model. More...
 
bool use_coupled_sst = false
 
ABLDriverType abl_driver_type
 Atmospheric boundary-layer driver type. More...
 
amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > abl_pressure_grad
 Applied ABL pressure-gradient forcing vector. More...
 
amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > abl_geo_forcing
 Applied geostrophic-wind forcing vector. More...
 
std::string abl_geo_wind_table
 Path to a time-varying geostrophic wind table. More...
 
bool have_geo_wind_profile {false}
 Whether a geostrophic wind profile has been configured. More...
 
bool variable_coriolis {false}
 Whether spatially varying Coriolis forcing is enabled. More...
 
int ave_plane {2}
 Averaging plane index used by diagnostics. More...
 
MoistureComponentIndices moisture_indices
 Index map of the moisture data carried by the active scheme: conserved-state components for the species and qmoist slots for the moist diagnostics. More...
 
bool moisture_tight_coupling {false}
 Whether moisture updates use tight coupling. More...
 
std::string windfarm_loc_table
 Wind-farm location table path. More...
 
std::string windfarm_spec_table
 Wind-farm turbine specification table path. More...
 
std::string windfarm_spec_table_extra
 Additional wind-farm turbine specification table path. More...
 
std::string windfarm_blade_table
 Wind-farm blade table path. More...
 
std::string windfarm_airfoil_tables
 Wind-farm airfoil table paths. More...
 
amrex::Real sampling_distance_by_D = -one
 Turbine inflow sampling distance normalized by rotor diameter. More...
 
amrex::Real turb_disk_angle = -one
 Turbine disk angle from the x axis [deg]. More...
 
amrex::Real windfarm_x_shift = -one
 Wind-farm x-coordinate shift. More...
 
amrex::Real windfarm_y_shift = -one
 Wind-farm y-coordinate shift. More...
 
amrex::Real bdy_nudge_factor = amrex::Real(10.0)
 Boundary sponge nudging factor. More...
 
bool use_wrf_bdy_density = true
 
bool use_wrf_bdy_qc_qi = false
 Whether WRF cloud water and active cloud ice are ingested at real boundaries. More...
 
amrex::Real bdy_rho_nudge_factor = amrex::Real(-1.0)
 
int bdy_moist_nudge_type = 1
 Moist-variable nudging strategy in boundary regions. More...
 
bool avg_grid_faces_to_nodes {false}
 
bool wrfinput_zlevels_from_file {true}
 
bool interp_atmos_from_coarse {false}
 
bool do_forest_drag {false}
 Whether forest canopy drag is enabled. More...
 
bool forest_biophysics {false}
 
bool forest_biophysics_heat {false}
 
amrex::Real forest_leaf_theta_fixed {-one}
 
amrex::Real const_massflux_u = zero
 Target constant mass flux in the x direction. More...
 
amrex::Real const_massflux_v = zero
 Target constant mass flux in the y direction. More...
 
amrex::Real const_massflux_tau = one
 Relaxation time scale for constant-mass-flux forcing. More...
 
amrex::Real const_massflux_layer_lo = amrex::Real(-bogus_large_value)
 Lower height of the constant-mass-flux forcing layer. More...
 
amrex::Real const_massflux_layer_hi = amrex::Real( bogus_large_value)
 Upper height of the constant-mass-flux forcing layer. More...
 
int massflux_klo {0}
 Lower vertical index for constant-mass-flux forcing. More...
 
int massflux_khi {0}
 Upper vertical index for constant-mass-flux forcing. More...
 
std::string hindcast_boundary_data_dir
 Directory containing hindcast lateral boundary data. More...
 
std::string hindcast_surface_data_dir
 Directory containing hindcast surface boundary data. More...
 
amrex::Real hindcast_data_interval_in_hrs = -one
 Time interval between hindcast data files [hr]. More...
 
bool hindcast_lateral_forcing = false
 Whether hindcast lateral forcing is enabled. More...
 
bool hindcast_surface_bcs = false
 Whether hindcast surface boundary conditions are enabled. More...
 
amrex::Real hindcast_lateral_sponge_strength = -one
 Strength of the hindcast lateral sponge layer. More...
 
amrex::Real hindcast_lateral_sponge_length = -one
 Length of the hindcast lateral sponge layer. More...
 
amrex::Real hindcast_zhi_sponge_strength = -one
 Strength of the upper hindcast sponge layer. More...
 
amrex::Real hindcast_zhi_sponge_length = -one
 Length of the upper hindcast sponge layer. More...
 
bool hindcast_zhi_sponge_damping = false
 Whether upper-boundary hindcast sponge damping is enabled. More...
 
bool io_hurricane_eye_tracker = false
 Whether hurricane-eye tracking output is enabled. More...
 
amrex::Real hurricane_eye_latitude = -1e10
 Initial hurricane-eye latitude. More...
 
amrex::Real hurricane_eye_longitude = -1e10
 Initial hurricane-eye longitude. More...
 
bool is_init_for_ensemble = false
 Whether initialization is for an ensemble simulation. More...
 
int n_ensemble = -1
 Number of ensemble members. More...
 
amrex::Real ens_pert_correlated_radius = -1.0
 Spatial correlation radius for ensemble perturbations. More...
 
amrex::Real ens_pert_amplitude = -1.0
 Amplitude of ensemble initialization perturbations. More...
 
std::string coarse_bckgnd_data_file
 Coarse background data file used for ensemble initialization. More...
 

Static Public Attributes

static InitType init_type = InitType::None
 Initial-condition source selected for the run. More...
 
static SoundingType sounding_type = SoundingType::Ideal
 Interpretation used for input sounding profiles. More...
 
static TerrainType terrain_type = TerrainType::None
 Terrain or immersed-boundary representation. More...
 
static bool flat_terrain = false
 Permit fixed-index planar averages after validating a flat fitted mesh. More...
 
static BuildingsType buildings_type = BuildingsType::None
 Building representation. More...
 
static bool use_real_bcs = false
 Whether real-data lateral boundary conditions are used. More...
 
static MeshType mesh_type = MeshType::ConstantDz
 Vertical mesh representation. More...
 

Detailed Description

Container holding many of the algorithmic options and parameters

Member Function Documentation

◆ any_perturbation()

bool SolverChoice::any_perturbation ( ) const
inline

Query whether any level uses a turbulent perturbation mode.

Returns
True if at least one configured level has source, direct, or CPM perturbations.
2505  {
2506  for (const auto& type : pert_type) {
2507  if (type == PerturbationType::Source ||
2508  type == PerturbationType::Direct ||
2509  type == PerturbationType::CPM) {
2510  return true;
2511  }
2512  }
2513  return false;
2514  }
amrex::Vector< PerturbationType > pert_type
Turbulent perturbation type for each AMR level.
Definition: ERF_DataStruct.H:2517

◆ build_coriolis_forcings_const_lat()

void SolverChoice::build_coriolis_forcings_const_lat ( std::string  pp_prefix)
inline

Build constant-latitude Coriolis forcing parameters.

Parameters
pp_prefixParmParse prefix for the ERF input namespace.
2144  {
2145  amrex::ParmParse pp(pp_prefix);
2146 
2147  // Read the rotational time period (in seconds)
2148  double rot_time_period = 86400.0;
2149  pp.queryAdd("rotational_time_period", rot_time_period);
2150 
2151  coriolis_factor = static_cast<amrex::Real>(4.0 * PI / rot_time_period);
2152 
2153  pp.queryAdd("coriolis_3d", coriolis_3d);
2154 
2155  // Convert to radians
2156  amrex::Real latitude_for_coriolis = amrex::Real(90.0);
2157  pp.queryAdd("latitude", latitude_for_coriolis);
2158  latitude_for_coriolis *= (PI/amrex::Real(180.));
2159  sinphi = std::sin(latitude_for_coriolis);
2160 
2161  // Note: cosphi defaults to 0
2162  if (coriolis_3d) {
2163  cosphi = std::cos(latitude_for_coriolis);
2164  }
2165 
2166  amrex::Print() << "Coriolis frequency, f = " << coriolis_factor * sinphi << " 1/s" << std::endl;
2167 
2168  if (abl_driver_type == ABLDriverType::GeostrophicWind) {
2169  // Read in the geostrophic wind -- we only use this to construct
2170  // the forcing term so no need to keep it
2171  amrex::Vector<amrex::Real> abl_geo_wind(3);
2172  pp.queryarr("abl_geo_wind",abl_geo_wind);
2173 
2174  if(!pp.queryAdd("abl_geo_wind_table",abl_geo_wind_table)) {
2175  abl_geo_forcing = {
2176  -coriolis_factor * (abl_geo_wind[1]*sinphi - abl_geo_wind[2]*cosphi),
2177  coriolis_factor * abl_geo_wind[0]*sinphi,
2178  -coriolis_factor * abl_geo_wind[0]*cosphi
2179  };
2180  } else {
2181  amrex::Print() << "NOTE: abl_geo_wind_table provided, ignoring input abl_geo_wind" << std::endl;
2182  }
2183  }
2184  }
ParmParse pp("prob")
constexpr amrex::Real PI
Definition: ERF_NumericalConstants.H:46
amrex::Real Real
Definition: ERF_ShocInterface.H:19
amrex::Real coriolis_factor
Twice the planetary rotation rate used for Coriolis forcing.
Definition: ERF_DataStruct.H:2353
std::string abl_geo_wind_table
Path to a time-varying geostrophic wind table.
Definition: ERF_DataStruct.H:2567
amrex::Real cosphi
Cosine of the latitude used for Coriolis forcing.
Definition: ERF_DataStruct.H:2354
amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > abl_geo_forcing
Applied geostrophic-wind forcing vector.
Definition: ERF_DataStruct.H:2566
ABLDriverType abl_driver_type
Atmospheric boundary-layer driver type.
Definition: ERF_DataStruct.H:2564
amrex::Real sinphi
Sine of the latitude used for Coriolis forcing.
Definition: ERF_DataStruct.H:2355
bool coriolis_3d
Whether the three-dimensional Coriolis terms are included.
Definition: ERF_DataStruct.H:2308

Referenced by init_params().

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

◆ check_params()

void SolverChoice::check_params ( int  max_level,
const amrex::Vector< amrex::Geometry > &  geom_vect,
amrex::GpuArray< ERF_BC, AMREX_SPACEDIM *2 >  phys_bc_type 
)
inline

Validate solver options after geometry and boundary conditions are known.

Parameters
max_levelMaximum AMR level configured for the run.
geom_vectGeometry for each AMR level.
phys_bc_typePhysical boundary-condition types.
1809  {
1810 #if 0
1811  // Warn for PBL models and moisture - these may not yet be compatible
1812  for (int lev = 0; lev <= max_level; lev++) {
1813  if ((moisture_type != MoistureType::None) && (turbChoice[lev].pbl_type != PBLType::None)) {
1814  amrex::Warning("\n*** WARNING: Moisture may not yet be compatible with PBL models, \n proceed with caution ***");
1815  }
1816  }
1817 #endif
1818  //
1819  // Buoyancy type check
1820  //
1821  for (int lev = 0; lev <= max_level; lev++) {
1822  if (buoyancy_type[lev] != 1 && buoyancy_type[lev] != 2 && buoyancy_type[lev] != 3 && buoyancy_type[lev] != 4) {
1823  amrex::Error("buoyancy_type must be 1, 2, 3 or 4");
1824  }
1825  }
1826 
1827  if (!use_lagged_delta_rt && !(terrain_type == TerrainType::MovingFittedMesh)) {
1828  amrex::Error("Can't turn off lagged_delta_rt when terrain not moving");
1829  }
1830 
1831  //
1832  // Wind farm checks
1833  //
1834  if (windfarm_type==WindFarmType::SimpleAD and sampling_distance_by_D < zero) {
1835  amrex::Error("To use simplified actuator disks, you need to provide a variable"
1836  " erf.sampling_distance_by_D in the inputs which specifies the upstream"
1837  " distance as a factor of the turbine diameter at which the incoming free stream"
1838  " velocity will be computed at.");
1839  }
1840  if ( (windfarm_type==WindFarmType::SimpleAD ||
1841  windfarm_type==WindFarmType::GeneralAD ) && turb_disk_angle < zero) {
1842  amrex::Error("To use simplified actuator disks, you need to provide a variable"
1843  " erf.turb_disk_angle_from_x in the inputs which is the angle of the face of the"
1844  " turbine disk from the x-axis. A turbine facing an oncoming flow in the x-direction"
1845  " will have turb_disk_angle value of 90 deg.");
1846  }
1847  if (windfarm_loc_type == WindFarmLocType::lat_lon and (windfarm_x_shift < zero or windfarm_y_shift < zero)) {
1848  amrex::Error("You are using windfarms with latitude-logitude option to position the turbines."
1849  " For this you should provide the inputs erf.windfarm_x_shift and"
1850  " erf.windfarm_y_shift which are the values by which the bounding box of the"
1851  " windfarm is shifted from the x and the y axes.");
1852  }
1853 
1854 
1855  if ( (const_massflux_u != 0) && !(geom_vect[0].isPeriodic(0)) ) {
1856  amrex::Error("Constant mass flux (in x) should be used with periodic boundaries");
1857  }
1858 
1859  if ( (const_massflux_v != 0) && !(geom_vect[0].isPeriodic(1)) ) {
1860  amrex::Error("Constant mass flux (in y) should be used with periodic boundaries");
1861  }
1862 
1863  // Mesoscale diffusion -- test if LES appropriate with this dx,dy
1864  for (int lev = 0; lev <= max_level; lev++) {
1865  if ((geom_vect[lev].CellSize(0) > amrex::Real(2000.)) || (geom_vect[lev].CellSize(1) > amrex::Real(2000.)))
1866  {
1867  if ( (turbChoice[lev].les_type == LESType::Smagorinsky) && !turbChoice[lev].smag2d ) {
1868  amrex::Warning("Should use 2-D Smagorinsky for mesoscale resolution");
1869  } else if (turbChoice[lev].les_type == LESType::Deardorff) {
1870  amrex::Warning("Should not use Deardorff LES for mesoscale resolution");
1871  }
1872  }
1873  }
1874 
1875  // Turn off implicit solve if we have no diffusion
1876  bool l_use_kturb = turbChoice[0].use_kturb;
1877  for (int lev = 1; lev <= max_level; lev++) {
1878  l_use_kturb = (l_use_kturb || turbChoice[lev].use_kturb);
1879  }
1880  bool l_use_diff = ( (diffChoice.molec_diff_type != MolecDiffType::None) || l_use_kturb );
1881 
1882  for (int lev = 0; lev <= max_level; lev++) {
1883  bool l_implicit_diff = (vert_implicit_fac[lev][0] > zero ||
1884  vert_implicit_fac[lev][1] > zero ||
1885  vert_implicit_fac[lev][2] > zero);
1886  if (l_implicit_diff && !l_use_diff) {
1887  amrex:: Print() << "No molecular or turbulent diffusion, turning off implicit solve at level " << lev << std::endl;
1888  vert_implicit_fac[lev][0] = zero;
1889  vert_implicit_fac[lev][1] = zero;
1890  vert_implicit_fac[lev][2] = zero;
1891  }
1892  }
1893 
1894  // The implicit terrain metric is a change to the vertical implicit solves on a
1895  // terrain-fitted mesh; refuse it where it could not do anything. This comes after
1896  // every block that can turn the implicit solve off.
1898  if (mesh_type != MeshType::VariableDz) {
1899  amrex::Abort("erf.implicit_terrain_metric = true requires a terrain-fitted mesh with "
1900  "non-flat terrain (erf.terrain_type = StaticFittedMesh or MovingFittedMesh); "
1901  "on a flat or a purely stretched mesh there are no terrain-metric terms");
1902  }
1903  // In a stage without the implicit solve the whole averaged metric term is explicit
1904  // for that stage. On the steep ridge test the option gained little with 1 1 0
1905  // and ran worse than without it with anelastic MidPoint (measured before the exact
1906  // split: 15 s instead of 30 s), while 1 1 1 recovered the full time step. The rule
1907  // is measured, not derived: every stage must solve implicitly.
1908  for (int lev = 0; lev <= max_level; lev++) {
1909  for (int i = 0; i < 3; ++i) {
1910  if (vert_implicit_fac[lev][i] <= zero) {
1911  amrex::Abort("erf.implicit_terrain_metric = true needs the vertical implicit solve "
1912  "in every Runge-Kutta stage at every level, but erf.vert_implicit_fac "
1913  "is not positive in stage " + std::to_string(i+1) + " at level " +
1914  std::to_string(lev) + ". Set erf.vert_implicit_fac = 1 1 1; the "
1915  "option cannot be used where the implicit solve is turned off "
1916  "(erf.vert_implicit = false, every erf.implicit_*_diffusion = false, "
1917  "no molecular or turbulent diffusion, or anelastic, which solves in "
1918  "its first stage only or not at all)");
1919  }
1920  }
1921  }
1922  // The momentum solves carry most of the stiffness; with them explicit the option
1923  // treats only the scalar metric terms implicitly
1925  amrex::Print() << "WARNING: erf.implicit_terrain_metric = true with "
1926  << "erf.implicit_momentum_diffusion = false: the momentum terrain-metric "
1927  << "terms stay explicit; only the scalars are treated implicitly" << std::endl;
1928  }
1929  } else if (mesh_type == MeshType::VariableDz) {
1930  // On a terrain-fitted mesh the projected horizontal stresses carry K_h, and their
1931  // terrain-metric part K_h h^2 d2/dz2 is explicit in any stage without the implicit
1932  // solve. On steep slopes that limits the time step (steep test ridge: 45 s before
1933  // #4214 was fixed, 15 s after, at the default 1 1 0). Say so once at start-up.
1934  bool explicit_stage_with_kh = false;
1935  for (int lev = 0; lev <= max_level; lev++) {
1936  if (turbChoice[lev].les_type == LESType::None) { continue; }
1937  for (int i = 0; i < 3; ++i) {
1938  if (vert_implicit_fac[lev][i] <= zero) { explicit_stage_with_kh = true; }
1939  }
1940  }
1941  if (explicit_stage_with_kh) {
1942  amrex::Print() << "NOTE: terrain-fitted mesh with an LES closure (horizontal eddy "
1943  << "viscosity K_h) and an explicit vertical-diffusion stage "
1944  << "(erf.vert_implicit_fac has a zero): the terrain-metric term "
1945  << "K_h h^2 d2/dz2 stays explicit there and limits the time step on "
1946  << "steep slopes. To relax it, use erf.vert_implicit_fac = 1 1 1 with "
1947  << "erf.implicit_terrain_metric = true, or erf.smag2d_slope_limiter = true "
1948  << "for Smagorinsky2D; erf.diffusive_dt_check reports the limit."
1949  << std::endl;
1950  }
1951  }
1952 
1953  // Countergradient validation: ensure required implicit diffusion is enabled
1954  for (int lev = 0; lev <= max_level; lev++) {
1955  if (turbChoice[lev].enable_mrf_countergradient) {
1957  vert_implicit_fac[lev][0] > zero ||
1958  vert_implicit_fac[lev][1] > zero ||
1959  vert_implicit_fac[lev][2] > zero,
1960  "enable_mrf_countergradient requires vert_implicit_fac > 0");
1963  "enable_mrf_countergradient requires implicit_thermal_diffusion = true");
1967  "enable_mrf_countergradient with moisture requires implicit_moisture_diffusion = true");
1968  }
1969  }
1970  }
1971 
1972  for (int lev = 0; lev <= max_level; lev++) {
1973  turbChoice[lev].check_params(phys_bc_type);
1974  }
1975  }
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_cloud_chamber_config.active, "Cloud Chamber: initializer reached without a parsed configuration")
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
@ None
Definition: ERF_LSM_Types.H:6
MolecDiffType molec_diff_type
Selected molecular transport model.
Definition: ERF_DiffStruct.H:94
WindFarmLocType windfarm_loc_type
Coordinate system for wind-farm turbine locations.
Definition: ERF_DataStruct.H:2534
amrex::Real const_massflux_v
Target constant mass flux in the y direction.
Definition: ERF_DataStruct.H:2624
amrex::Vector< TurbChoice > turbChoice
Turbulence options for each AMR level.
Definition: ERF_DataStruct.H:2252
bool implicit_moisture_diffusion
Whether implicit vertical moisture diffusion is included.
Definition: ERF_DataStruct.H:2281
MoistureType moisture_type
Moisture or microphysics model.
Definition: ERF_DataStruct.H:2524
amrex::Vector< int > buoyancy_type
Per-level buoyancy formulation selector.
Definition: ERF_DataStruct.H:2263
amrex::Real const_massflux_u
Target constant mass flux in the x direction.
Definition: ERF_DataStruct.H:2623
amrex::Real sampling_distance_by_D
Turbine inflow sampling distance normalized by rotor diameter.
Definition: ERF_DataStruct.H:2581
amrex::Real windfarm_y_shift
Wind-farm y-coordinate shift.
Definition: ERF_DataStruct.H:2584
bool implicit_thermal_diffusion
Whether implicit vertical thermal diffusion is included.
Definition: ERF_DataStruct.H:2280
static MeshType mesh_type
Vertical mesh representation.
Definition: ERF_DataStruct.H:2236
amrex::Real turb_disk_angle
Turbine disk angle from the x axis [deg].
Definition: ERF_DataStruct.H:2582
amrex::Real windfarm_x_shift
Wind-farm x-coordinate shift.
Definition: ERF_DataStruct.H:2583
bool use_lagged_delta_rt
Whether to use lagged delta terms for moving terrain.
Definition: ERF_DataStruct.H:2337
amrex::Vector< amrex::Vector< amrex::Real > > vert_implicit_fac
Per-level, per-stage implicit vertical diffusion factors.
Definition: ERF_DataStruct.H:2277
bool implicit_terrain_metric
Whether the compact terrain-metric part of the vertical diffusion is solved implicitly.
Definition: ERF_DataStruct.H:2287
static TerrainType terrain_type
Terrain or immersed-boundary representation.
Definition: ERF_DataStruct.H:2224
DiffChoice diffChoice
Diffusion-related options.
Definition: ERF_DataStruct.H:2249
WindFarmType windfarm_type
Wind-farm model.
Definition: ERF_DataStruct.H:2533
bool implicit_momentum_diffusion
Whether implicit vertical momentum diffusion is included.
Definition: ERF_DataStruct.H:2283
Here is the call graph for this function:

◆ display()

void SolverChoice::display ( int  max_level,
std::string  pp_prefix 
)
inline

Print the configured solver, physics, and transport options.

Parameters
max_levelMaximum AMR level configured for the run.
pp_prefixParmParse prefix used to display nested choices.
1983  {
1984  amrex::Print() << "SOLVER CHOICE: " << std::endl;
1985  for (int lev = 0; lev <= max_level; lev++) {
1986  amrex::Print() << "At level " << lev << " : " << std::endl;
1987  if (anelastic[lev]) {
1988  amrex::Print() << " anelastic with no substepping, using the "
1989  << ((anelastic_type[lev] == AnelasticType::MidPoint) ? "MidPoint" : "RK2")
1990  << " integrator" << std::endl;
1991  } else {
1993  amrex::Print() << " compressible with no substepping" << std::endl;
1994  } else if (substepping_type[lev] == SubsteppingType::Implicit) {
1995  amrex::Print() << " compressible with implicit substepping" << std::endl;
1996  }
1997  }
1998  if (fixed_density[lev]) {
1999  amrex::Print() << " and fixed density" << std::endl;
2000  }
2001  }
2002 
2003  for (int lev = 0; lev <= max_level; lev++) {
2004  amrex::Print() << "vert_implicit_fac at level " << lev << " : "
2005  << vert_implicit_fac[lev][0] << " "
2006  << vert_implicit_fac[lev][1] << " "
2007  << vert_implicit_fac[lev][2];
2008  if (vert_implicit_fac[lev][0] > zero ||
2009  vert_implicit_fac[lev][1] > zero ||
2010  vert_implicit_fac[lev][2] > zero)
2011  {
2012  amrex::Print() << " (theta = " << implicit_thermal_diffusion
2013  << ", moisture = " << implicit_moisture_diffusion
2014  << ", tke = " << implicit_ke_diffusion
2015  << ", momenta = " << implicit_momentum_diffusion;
2016 #ifdef ERF_IMPLICIT_W
2017  amrex::Print() << ", including w";
2018 #endif
2020  amrex::Print() << "; terrain metric implicit";
2021  }
2022  amrex::Print() << ")";
2023  }
2024  }
2025  amrex::Print() << std::endl;
2026  amrex::Print() << "use_coriolis : " << use_coriolis << std::endl;
2027  amrex::Print() << "use_gravity : " << use_gravity << std::endl;
2028 
2029  if (moisture_type == MoistureType::SAM) {
2030  amrex::Print() << "Moisture Model: SAM" << std::endl;
2031  } else if (moisture_type == MoistureType::SAM_NoIce) {
2032  amrex::Print() << "Moisture Model: SAM No Ice" << std::endl;
2033  } else if (moisture_type == MoistureType::SAM_NoPrecip_NoIce) {
2034  amrex::Print() << "Moisture Model: SAM No Precip No Ice" << std::endl;
2035  } else if (moisture_type == MoistureType::Morrison) {
2036  amrex::Print() << "Moisture Model: Morrison" << std::endl;
2037  } else if (moisture_type == MoistureType::Morrison_NoIce) {
2038  amrex::Print() << "Moisture Model: Morrison_NoIce" << std::endl;
2039  } else if (moisture_type == MoistureType::WSM6) {
2040  amrex::Print() << "Moisture Model: WSM6" << std::endl;
2041  } else if (moisture_type == MoistureType::WDM6) {
2042  amrex::Print() << "Moisture Model: WDM6" << std::endl;
2043  } else if (moisture_type == MoistureType::Kessler) {
2044  amrex::Print() << "Moisture Model: Kessler" << std::endl;
2045  } else if (moisture_type == MoistureType::Kessler_NoRain) {
2046  amrex::Print() << "Moisture Model: Kessler No Rain" << std::endl;
2047  } else if (moisture_type == MoistureType::SatAdj) {
2048  amrex::Print() << "Moisture Model: Saturation Adjustment" << std::endl;
2049  } else if (moisture_type == MoistureType::SuperDroplets) {
2050  amrex::Print() << "Moisture Model: SuperDroplets" << std::endl;
2051  } else if (moisture_type == MoistureType::MoistNoCondensation) {
2052  amrex::Print() << "Moisture Model: MoistNoCondensation" << std::endl;
2053  } else if (moisture_type == MoistureType::SBM) {
2054  amrex::Print() << "Moisture Model: SBM mapped spectral advection (M3)" << std::endl;
2055  } else {
2056  amrex::Print() << "Moisture Model: None" << std::endl;
2057  }
2058 
2059  if (terrain_type == TerrainType::StaticFittedMesh) {
2060  amrex::Print() << "Terrain Type: StaticFittedMesh" << std::endl;
2061  } else if (terrain_type == TerrainType::MovingFittedMesh) {
2062  amrex::Print() << "Terrain Type: MovingFittedMesh" << std::endl;
2063  } else if (terrain_type == TerrainType::EB) {
2064  amrex::Print() << "Terrain Type: EB" << std::endl;
2065  ebChoice.display();
2066  } else if (terrain_type == TerrainType::ImmersedForcing) {
2067  amrex::Print() << "Terrain Type: ImmersedForcing" << std::endl;
2068  } else {
2069  amrex::Print() << "Terrain Type: None" << std::endl;
2070  }
2071 
2072  amrex::Print() << "Flat fitted terrain: "
2073  << (flat_terrain ? "true" : "false") << std::endl;
2074 
2075  if (buildings_type == BuildingsType::ImmersedForcing) {
2076  amrex::Print() << "Buildings Type: ImmersedForcing" << std::endl;
2077  } else {
2078  amrex::Print() << "Buildings Type: None" << std::endl;
2079  }
2080 
2081  if (mesh_type == MeshType::ConstantDz) {
2082  amrex::Print() << " Mesh Type: ConstantDz" << std::endl;
2083  } else if (mesh_type == MeshType::StretchedDz) {
2084  amrex::Print() << " Mesh Type: StretchedDz" << std::endl;
2085  } else if (mesh_type == MeshType::VariableDz) {
2086  amrex::Print() << " Mesh Type: VariableDz" << std::endl;
2087  } else {
2088  amrex::Error("No mesh_type set!");
2089  }
2090 
2091  amrex::Print() << "ABL Driver Type: " << std::endl;
2093  amrex::Print() << " None" << std::endl;
2094  } else if (abl_driver_type == ABLDriverType::PressureGradient) {
2095  amrex::Print() << " Pressure Gradient "
2096  << amrex::RealVect(abl_pressure_grad[0],abl_pressure_grad[1],abl_pressure_grad[2])
2097  << std::endl;
2098  } else if (abl_driver_type == ABLDriverType::GeostrophicWind) {
2099  amrex::Print() << " Geostrophic Wind "
2100  << amrex::RealVect(abl_geo_forcing[0],abl_geo_forcing[1],abl_geo_forcing[2])
2101  << std::endl;
2102  }
2103 
2104  if (max_level > 0) {
2105  amrex::Print() << "Coupling Type: " << std::endl;
2106  if (coupling_type == CouplingType::TwoWay) {
2107  amrex::Print() << " Two-way" << std::endl;
2108  } else if (coupling_type == CouplingType::OneWay) {
2109  amrex::Print() << " One-way" << std::endl;
2110  }
2111  }
2112 
2113  if (rad_type == RadiationType::RRTMGP) {
2114  amrex::Print() << "Radiation Model: RRTMGP" << std::endl;
2115  } else if (rad_type == RadiationType::Simple) {
2116  amrex::Print() << "Radiation Model: Simple" << std::endl;
2117  } else if (rad_type == RadiationType::TwoStream) {
2118  amrex::Print() << "Radiation Model: TwoStream" << std::endl;
2119  } else {
2120  amrex::Print() << "Radiation Model: None" << std::endl;
2121  }
2122 
2123  amrex::Print() << "Gradp_type : " << gradp_type << std::endl;
2124 
2125  for (int lev = 0; lev <= max_level; lev++) {
2126  amrex::Print() << "Buoyancy_type at level " << lev << " : " << buoyancy_type[lev] << std::endl;
2127  }
2128 
2129  advChoice.display(pp_prefix);
2130  diffChoice.display();
2133 
2134  for (int lev = 0; lev <= max_level; lev++) {
2135  turbChoice[lev].display(lev);
2136  }
2137  }
void display(std::string &pp_prefix)
Print the configured advection choices.
Definition: ERF_AdvStruct.H:243
void display()
Print the configured damping options.
Definition: ERF_DampingStruct.H:71
void display()
Print the configured diffusion options.
Definition: ERF_DiffStruct.H:77
void display()
Print the configured embedded-boundary options.
Definition: ERF_EBStruct.H:63
static bool flat_terrain
Permit fixed-index planar averages after validating a flat fitted mesh.
Definition: ERF_DataStruct.H:2227
amrex::Vector< int > fixed_density
Per-level flag selecting fixed-density treatment; always 1 at an anelastic level.
Definition: ERF_DataStruct.H:2261
CouplingType coupling_type
Multilevel coupling strategy.
Definition: ERF_DataStruct.H:2523
EBChoice ebChoice
Embedded-boundary options.
Definition: ERF_DataStruct.H:2253
bool implicit_ke_diffusion
Whether implicit vertical TKE diffusion is included.
Definition: ERF_DataStruct.H:2282
bool use_gravity
Whether gravitational forcing is enabled.
Definition: ERF_DataStruct.H:2306
amrex::Vector< SubsteppingType > substepping_type
Acoustic substepping type for each AMR level.
Definition: ERF_DataStruct.H:2258
bool use_coriolis
Whether Coriolis forcing is enabled.
Definition: ERF_DataStruct.H:2307
AdvChoice advChoice
Advection-related options.
Definition: ERF_DataStruct.H:2248
SpongeChoice spongeChoice
Sponge-layer options.
Definition: ERF_DataStruct.H:2251
amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > abl_pressure_grad
Applied ABL pressure-gradient forcing vector.
Definition: ERF_DataStruct.H:2565
amrex::Vector< int > anelastic
Per-level flag selecting anelastic dynamics.
Definition: ERF_DataStruct.H:2259
int gradp_type
Terrain-fitted horizontal pressure-gradient formulation.
Definition: ERF_DataStruct.H:2301
DampingChoice dampingChoice
Damping-related options.
Definition: ERF_DataStruct.H:2250
amrex::Vector< AnelasticType > anelastic_type
Per-level two-stage scheme used by the anelastic integrator.
Definition: ERF_DataStruct.H:2260
static BuildingsType buildings_type
Building representation.
Definition: ERF_DataStruct.H:2230
RadiationType rad_type
Radiation model.
Definition: ERF_DataStruct.H:2538
void display()
Print the configured sponge-layer options.
Definition: ERF_SpongeStruct.H:85
Here is the call graph for this function:

◆ host_owns_vertical_momentum_diffusion()

bool SolverChoice::host_owns_vertical_momentum_diffusion ( ) const
inlinenoexcept

Test whether the host owns momentum diffusion.

Returns
True if ERF dycore does vertical diffusion of momentum.
2474  {
2475  if (use_eamxx_shoc) { return false; }
2476  if (!use_native_shoc) { return true; }
2478  }
bool shoc_disables_momentum_transport(ShocMomentumTransport mode)
Definition: ERF_ShocTransportStruct.H:47
bool use_native_shoc
Whether any level uses the native SHOC PBL scheme.
Definition: ERF_DataStruct.H:2396
ShocMomentumTransport shoc_momentum_transport
Definition: ERF_DataStruct.H:2400
bool use_eamxx_shoc
Whether any level uses the EAMxx SHOC PBL scheme.
Definition: ERF_DataStruct.H:2395

Referenced by init_params().

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

◆ host_owns_vertical_scalar_diffusion()

bool SolverChoice::host_owns_vertical_scalar_diffusion ( ) const
inlinenoexcept

Test whether the host owns scalar diffusion.

Returns
True if ERF dycore does vertical diffusion of scalars.
2485  {
2486  if (use_eamxx_shoc) { return false; }
2487  if (!use_native_shoc) { return true; }
2488  return false;
2489  }

Referenced by init_params().

Here is the caller graph for this function:

◆ init_params()

void SolverChoice::init_params ( int  max_level,
std::string  pp_prefix 
)
inline

Read solver-wide algorithmic options from the input parameter database.

Parameters
max_levelMaximum AMR level configured for the run.
pp_prefixParmParse prefix for the ERF input namespace.
693  {
694  amrex::ParmParse pp(pp_prefix);
695 
696  bool bogus_bool;
697  if (pp.query("use_terrain",bogus_bool) > 0) {
698  amrex::Error("The input use_terrain is deprecated. Set terrain_type instead.");
699  }
700 
701  if (pp.query("use_moist_background",bogus_bool) > 0) {
702  amrex::Error("The input use_moist_background is deprecated. Set init_type = MoistBaseState instead.");
703  }
704 
705  // Do we set map scale factors to myhalf instead of 1 for testing?
706  pp.queryAdd("test_mapfactor", test_mapfactor);
707 
708  // Which horizontal pressure gradient formulation to use with terrain fitted coords?
709  // 0: dp/dx with dp/dz correction (default)
710  // 1: gradient of vertically interpolated p, see Klemp 2011
711  pp.queryAdd("gradp_type", gradp_type);
713 
714  // For the lateral pressure gradient to be used in the momentum equation, should we
715  // take the x- and y-derivatives of the perturbational pressure or the full pressure?
716  pp.queryAdd("use_pert_pres_gradient", use_pert_pres_gradient);
717 
718  // What type of moisture model to use?
719  moisture_type = MoistureType::None; // Default
720  if (pp.query("moisture_type",moisture_type) > 0) {
721  amrex::Error("The input moisture_type is deprecated. Set moisture_model instead.");
722  }
723 
724  pp.query_enum_case_insensitive("moisture_model",moisture_type);
725 
726  // Test-only SBM failure injections. They remain disabled unless an
727  // integration test explicitly enables the corresponding option.
728  pp.queryAdd("sbm_test_native_qc_write_fault", sbm_test_native_qc_write_fault);
729  pp.queryAdd("sbm_test_donor_cfl_fault", sbm_test_donor_cfl_fault);
730  if (moisture_type != MoistureType::SBM &&
732  amrex::Error("SBM test fault-injection options require moisture_model=SBM");
733  }
734 
735  // Register the moisture data this scheme carries: conserved-state
736  // components and qmoist diagnostic slots alike. MoistureComponentIndices
737  // is the one place that mapping lives, and every consumer -- source terms,
738  // turbulence closures, and the plotfile/subvolume writers -- queries it
739  // instead of testing moisture_type.
741 
742  if (moisture_type == MoistureType::SBM) {
743  if (pp.contains("sbm_zero_transport_fixture")) {
744  bool legacy_zero_transport = false;
745  pp.get("sbm_zero_transport_fixture", legacy_zero_transport);
746  if (legacy_zero_transport) {
747  amrex::Error("erf.sbm_zero_transport_fixture=true is obsolete; M3 advances the mapped spectral state, so remove this option");
748  }
749  }
750  pp.queryAdd("sbm_nbins", sbm_nbins);
751  pp.queryAdd("sbm_moment_mode", sbm_moment_mode);
752  pp.queryAdd("sbm_cloud_rain_split", sbm_cloud_rain_split);
753  pp.queryarr("sbm_edges", sbm_edges);
754  pp.queryarr("sbm_pivots", sbm_pivots);
755  pp.queryarr("sbm_fixture_initial_state", sbm_fixture_initial_state);
756 
757  if (sbm_nbins < 2 || (sbm_moment_mode != 1 && sbm_moment_mode != 2)) {
758  amrex::Error("SBM requires sbm_nbins >= 2 and sbm_moment_mode equal to 1 or 2");
759  }
760  if (sbm_edges.empty()) {
761  sbm_edges.resize(static_cast<std::size_t>(sbm_nbins + 1));
762  sbm_pivots.resize(static_cast<std::size_t>(sbm_nbins));
763  for (int b = 0; b <= sbm_nbins; ++b) {
764  const amrex::Real fraction = static_cast<amrex::Real>(b) /
765  static_cast<amrex::Real>(sbm_nbins);
766  sbm_edges[static_cast<std::size_t>(b)] =
767  std::pow(amrex::Real(10.0), amrex::Real(-18.0) + amrex::Real(6.0) * fraction);
768  }
769  for (int b = 0; b < sbm_nbins; ++b) {
770  sbm_pivots[static_cast<std::size_t>(b)] = std::sqrt(
771  sbm_edges[static_cast<std::size_t>(b)] * sbm_edges[static_cast<std::size_t>(b + 1)]);
772  }
773  } else {
774  sbm_nbins = static_cast<int>(sbm_edges.size()) - 1;
775  if (sbm_nbins < 2) amrex::Error("sbm_edges must define at least two bins");
776  if (sbm_pivots.empty()) {
777  sbm_pivots.resize(static_cast<std::size_t>(sbm_nbins));
778  for (int b = 0; b < sbm_nbins; ++b) {
779  sbm_pivots[static_cast<std::size_t>(b)] = std::sqrt(
780  sbm_edges[static_cast<std::size_t>(b)] * sbm_edges[static_cast<std::size_t>(b + 1)]);
781  }
782  }
783  }
784  if (sbm_pivots.size() != static_cast<amrex::Long>(sbm_nbins)) {
785  amrex::Error("sbm_pivots must contain one value per SBM bin");
786  }
788  if (sbm_cloud_rain_split <= 0 || sbm_cloud_rain_split >= sbm_nbins) {
789  amrex::Error("sbm_cloud_rain_split must be strictly inside the liquid bin range");
790  }
791  const int expected_sbm_components = sbm_nbins * (sbm_moment_mode == 2 ? 2 : 1);
792  if (!sbm_fixture_initial_state.empty() &&
793  sbm_fixture_initial_state.size() != static_cast<amrex::Long>(expected_sbm_components)) {
794  amrex::Error("sbm_fixture_initial_state must match the full runtime SBM component count");
795  }
796  for (const amrex::Real value : sbm_fixture_initial_state) {
797  if (!std::isfinite(value) || value < amrex::Real(0.0)) {
798  amrex::Error("sbm_fixture_initial_state values must be finite and nonnegative");
799  }
800  }
801  }
802 
803  // Set a default for both dry and moist
804  buoyancy_type.resize(max_level+1);
805  for (int i = 0; i <= max_level; ++i) {
806  buoyancy_type[i] = 1; // uses Rhoprime
807  }
808 
810  pp.queryAdd("moisture_tight_coupling",moisture_tight_coupling);
811  }
812 
813  // Which expression (1,2/3 or 4) to use for buoyancy
814  int default_buoyancy_type = buoyancy_type[0];
815  read_int_string(max_level, "buoyancy_type", buoyancy_type, default_buoyancy_type);
816 
817  // What type of land surface model to use
818  lsm_type = LandSurfaceType::None; // Default
819  pp.query_enum_case_insensitive("land_surface_model",lsm_type);
820 
821  // What type of urban model to use and whether it is active at the given level
823  pp.query_enum_case_insensitive("urban_model", urban_type);
824  read_int_string(max_level, "urban_lev_active", urban_enabled_lev, 1);
825  for (int lev = 0; lev <= max_level; ++lev) {
826  if (urban_enabled_lev[lev] != 0 && urban_enabled_lev[lev] != 1) {
827  amrex::Error("urban_lev_active should be 0 or 1");
828  }
829  }
830 
831  // Will an external ocean coupler supply SST for part or all of the water
832  // cells this run? The surface layer needs to know this it in time to select
833  // ThetaCalcType::SURFACE_TEMPERATURE, which is long before the first
834  // ApplyOceanSurfaceState call.
835  pp.queryAdd("use_coupled_sst", use_coupled_sst);
836 
837  read_int_string(max_level, "is_land", is_land, 1);
838  for (int lev = 0; lev <= max_level; ++lev) {
839  if (is_land[lev] == 1) {
840  amrex::Print() << "Level " << lev << " is land" << std::endl;
841  } else if (is_land[lev] == 0) {
842  amrex::Print() << "Level " << lev << " is water" << std::endl;
843  } else {
844  amrex::Error("is_land should be 0 or 1");
845  }
846  }
847 
848  // What type of radiation model to use
849  rad_type = RadiationType::None; // Default
850  pp.query_enum_case_insensitive("radiation_model", rad_type);
851 
852  // Verify that radiation model cannot be RRTMGP if ERF was not compiled with RRTMGP
853 #ifndef ERF_USE_RRTMGP
854  if (rad_type == RadiationType::RRTMGP)
855  {
856  amrex::Error("ERF was not compiled with RRTMGP enabled!");
857  }
858 #endif
859 
860  // Is the terrain none, static or moving?
861  std::string terrain_type_temp = "";
862  pp.queryAdd("terrain_type", terrain_type_temp);
863  if (terrain_type_temp == "Moving") {
864  amrex::Warning("erf.terrain_type = Moving is deprecated; please replace Moving by MovingFittedMesh");
865  terrain_type = TerrainType::MovingFittedMesh;
866  } else if (terrain_type_temp == "Static") {
867  amrex::Warning("erf.terrain_type = Static is deprecated; please replace Static by StaticFittedMesh");
868  terrain_type = TerrainType::StaticFittedMesh;
869  } else {
870  pp.query_enum_case_insensitive("terrain_type",terrain_type);
871  }
872 
873  // Whether the terrain is flat - this allows planar averages (lsf, nudging) with StaticFittedMesh
874  pp.queryAdd("flat_terrain", flat_terrain);
875 
876  // Get buildings type
877  std::string buildings_type_temp = "";
878  pp.queryAdd("buildings_type", buildings_type_temp);
879  if (buildings_type_temp == "ImmersedForcing") {
880  buildings_type = BuildingsType::ImmersedForcing;
881  }
882 
883  //
884  // Read the init_type here to make sure we correctly set the mesh and terrain types
885  //
886  std::string init_type_temp_string;
887 
888  int found = pp.queryAdd("init_type",init_type_temp_string);
889 
890  if ( (init_type_temp_string == "Real") || (init_type_temp_string == "real") ) {
891  amrex::Error("erf.init_type = Real is deprecated; please replace Real by WRFInput");
892  } else if ( (init_type_temp_string == "Ideal") || (init_type_temp_string == "ideal") ) {
893  amrex::Error("erf.init_type = Ideal is deprecated; please replace Ideal by WRFInput");
894  } else {
895  pp.query_enum_case_insensitive("init_type",init_type);
896  use_real_bcs = ( (init_type == InitType::WRFInput) || (init_type == InitType::Metgrid) );
897  }
898 
899  if ( (init_type == InitType::WRFInput) || (init_type == InitType::Metgrid) ) {
900  if (terrain_type != TerrainType::StaticFittedMesh) {
901  amrex::Error("Only terrain_type = StaticFittedMesh are allowed with init_type = WRFInput or Metgrid");
902  }
903  }
904 
905  if (init_type == InitType::MoistBaseState) {
907  amrex::Error("Makes no sense to have moist base state with no moisture model");
908  }
909  }
910 
911  if (init_type == InitType::WRFInput) {
913  amrex::Error("Can't have moisture_type = None with init_type = WRFInput");
914  }
915 
916  // NetCDF wrfbdy lateral boundary file
917  std::string nc_bdy_file_temp_string;
918  bool has_bdy = pp.queryAdd("nc_bdy_file", nc_bdy_file_temp_string);
919  if (!has_bdy) use_real_bcs = false;
920 
921  bool use_real_bcs_temp = use_real_bcs;
922  pp.queryAdd("use_real_bcs", use_real_bcs_temp);
923  if (use_real_bcs && !use_real_bcs_temp) {
924  use_real_bcs = false;
925  }
926  }
927 
928  if (found == 0 || init_type == InitType::None) {
929  amrex::Print() << "init_type must now be set. The options are " << std::endl;
930  amrex::Print() << " Input_Sounding, NCFile, WRFInput, Metgrid, Uniform, " << std::endl;
931  amrex::Print() << " ConstantDensity, Isentropic, MoistBaseState, or HindCast " << std::endl;
932  amrex::Error("Please add a string for init_type to your inputs file or command line");
933  }
934 
935  // How to interpret input_sounding
936  if (init_type == InitType::Input_Sounding) {
937  pp.query_enum_case_insensitive("sounding_type",sounding_type);
938  }
939 
940  if (terrain_type == TerrainType::StaticFittedMesh ||
941  terrain_type == TerrainType::MovingFittedMesh) {
942  mesh_type = MeshType::VariableDz;
943  }
944 
945  if (flat_terrain && terrain_type != TerrainType::StaticFittedMesh) {
946  amrex::Error("erf.flat_terrain requires terrain_type = StaticFittedMesh");
947  }
948 
949  if ( (moisture_type == MoistureType::SAM ||
950  moisture_type == MoistureType::SAM_NoIce ||
951  moisture_type == MoistureType::SAM_NoPrecip_NoIce ) &&
952  (mesh_type == MeshType::VariableDz) )
953  {
954  amrex::Abort("SAM is not correct with variable dz -- choose another moisture model");
955  }
956 
957  // queryAdd puts the default in the table, so ask whether the ratio was given first
958  const bool have_stretching_ratio = pp.contains("grid_stretching_ratio");
959  pp.queryAdd("grid_stretching_ratio", grid_stretching_ratio);
960  if (grid_stretching_ratio != 0) {
962  "The grid stretching ratio must be greater than 1");
963  }
964  // erf.initial_dz on its own asks for the stretching ratio to be solved for, so that
965  // a first layer that thick stretches geometrically to close on prob_hi[2]. An
966  // explicit erf.grid_stretching_ratio = 0 still means no stretching at all.
967  const bool solve_stretching_ratio = !have_stretching_ratio && pp.contains("initial_dz");
968  if (grid_stretching_ratio >= 1 || solve_stretching_ratio) {
970  terrain_type = TerrainType::StaticFittedMesh;
971  }
972  if (mesh_type == MeshType::ConstantDz) {
973  mesh_type = MeshType::StretchedDz;
974  }
975  pp.queryAdd("zsurface", zsurf);
976  if (zsurf != zero) {
977  amrex::Print() << "Nominal zsurface height != 0, may result in unexpected behavior"
978  << std::endl;
979  }
980  pp.get("initial_dz", dz0);
981  }
982 
983  int n_zlevels = pp.countval("terrain_z_levels");
984  if (n_zlevels > 0)
985  {
987  terrain_type = TerrainType::StaticFittedMesh;
988  }
989  if (mesh_type == MeshType::ConstantDz) {
990  mesh_type = MeshType::StretchedDz;
991  }
992  }
993 
994  // Use lagged_delta_rt in the fast integrator?
995  pp.queryAdd("use_lagged_delta_rt", use_lagged_delta_rt);
996 
997  // Average the input z-face heights onto the nodes, or reconstruct our own
998  pp.queryAdd("avg_grid_faces_to_nodes",avg_grid_faces_to_nodes);
999 
1000  // Build the ERF vertical grid from the file's own mean layer-thickness profile,
1001  // or from a single geometric stretch anchored on the file's first layer?
1002  pp.queryAdd("wrfinput_zlevels_from_file",wrfinput_zlevels_from_file);
1003 
1004  // Catch the old name for the flag above so the error says what to do
1005  // rather than silently ignoring the setting.
1006  if (pp.contains("use_wrf_height_grid")) {
1007  amrex::Abort("erf.use_wrf_height_grid has been renamed. "
1008  "Set erf.avg_grid_faces_to_nodes instead; it carries "
1009  "the same meaning (average the input z-face heights "
1010  "onto the nodes rather than reconstructing them).");
1011  }
1012 
1013  // Interpolate atmospheric state from coarse level instead of reading from wrfinput
1014  // when creating a finer level from coarse at a later time?
1015  pp.queryAdd("interp_atmos_from_coarse", interp_atmos_from_coarse);
1016 
1017  // Rebalance wrf state?
1018  pp.queryAdd("rebalance_wrf_input", rebalance_wrf_input);
1019 
1020  // Must rebalance if the nodal heights were reconstructed rather than averaged
1022  amrex::Print() << "Must rebalance when not averaging the input height grid. Setting rebalance_wrf_input to true \n";
1023  rebalance_wrf_input = true;
1024  }
1025 
1026  // These default to true but are used for unit testing
1027  pp.queryAdd("use_gravity", use_gravity);
1028 
1029  // Initializing from Metgrid or WRFInput without gravity makes no sense
1030  if ( !use_gravity && ( (init_type == InitType::WRFInput) || (init_type == InitType::Metgrid) ) ) {
1031  amrex::Print() << "Setting use_gravity to true due to init_type = WRFInput / Metgrid " << std::endl;
1032  use_gravity = true;
1033  }
1034 
1036 
1037  pp.queryAdd("c_p", c_p);
1038  rdOcp = R_d / c_p;
1039 
1040  // *******************************************************************************
1041  // Read anelastic etc and over-ride if necessary
1042  // *******************************************************************************
1043 
1044  read_int_string(max_level, "anelastic", anelastic, 0);
1045  const bool fixed_density_given =
1046  read_int_string(max_level, "fixed_density", fixed_density, 0);
1047  read_int_string(max_level, "project_initial_velocity", project_initial_velocity, 0);
1048 
1049  // The anelastic equations hold the density at its base-state value, so
1050  // fixed_density is forced to 1 at every anelastic level; a user value of 0
1051  // there is ignored, and we say so rather than drop it silently.
1052  bool any_anelastic = false;
1053  bool any_compress = false;
1054  for (int i = 0; i <= max_level; ++i) {
1055  if (anelastic[i] == 1) {
1056  if (fixed_density_given && fixed_density[i] == 0) {
1057  amrex::Print() << "WARNING: erf.fixed_density = 0 is ignored at level " << i
1058  << " because erf.anelastic = 1 there; the anelastic equations"
1059  << " always hold the density fixed in time." << std::endl;
1060  }
1061  project_initial_velocity[i] = 1;
1062  fixed_density[i] = 1; // Always fixed when anelastic
1063  buoyancy_type[i] = 3; // (This isn't actually used when anelastic is set)
1064  any_anelastic = true;
1065  } else {
1066  any_compress = true;
1067  }
1068  }
1069 
1071  amrex::Error("erf.moisture_model = SuperDroplets is not supported with "
1072  "erf.anelastic = 1: the Super-Droplet path currently uses "
1073  "the compressible equation of state. Use compressible "
1074  "dynamics or a supported Eulerian moisture model.");
1075  }
1076 
1077  // Want to have different immersed forcing defaults depending on anelastic or fully compressible.
1078  // We should have different starting values because the stability of the method is dependent on dt.
1079  // dt is coarser for anelastic --> need to loosen stiffness of immersed forcing.
1080  if (any_anelastic) {
1081  immersed_forcing_substep = false;
1082  if_Cd_momentum = amrex::Real(50.0);
1083  if_Cd_scalar = amrex::Real(5.0);
1084  } else {
1085  immersed_forcing_substep = true;
1086  if_Cd_momentum = amrex::Real(500.0);
1087  if_Cd_scalar = amrex::Real(50.0);
1088  }
1089 
1090  // *******************************************************************************
1091  // Read anelastic_type and allow for different values at each level
1092  // *******************************************************************************
1093  anelastic_type.resize(max_level+1);
1094 
1095  for (int i = 0; i <= max_level; i++) {
1096  anelastic_type[i] = AnelasticType::RK2;
1097  }
1098 
1099  for (int i = 0; i <= max_level; i++) {
1101  pp, "anelastic_type", anelastic_type[i], i, max_level);
1102  }
1103 
1104  if (pp.contains("anelastic_type") && !any_anelastic) {
1105  amrex::Print() << "Ignoring erf.anelastic_type because no level is anelastic" << std::endl;
1106  for (int i = 0; i <= max_level; i++) { anelastic_type[i] = AnelasticType::RK2; }
1107  }
1108 
1109  // *******************************************************************************
1110  // Read substepping_type and allow for different values at each level
1111  // *******************************************************************************
1112  substepping_type.resize(max_level+1);
1113 
1114  for (int i = 0; i <= max_level; i++) {
1115  substepping_type[i] = SubsteppingType::Implicit;
1116  }
1117 
1118  for (int i = 0; i <= max_level; i++) {
1120  pp, "substepping_type", substepping_type[i], i, max_level);
1121  }
1122 
1123  pp.queryAdd("substepping_diag", substepping_diag);
1124 
1125  pp.queryAdd("beta_s", beta_s);
1126 
1127  // *******************************************************************************
1128  // Error check on deprecated input
1129  // *******************************************************************************
1130  int nvals_old = pp.countval("no_substepping");
1131  if (nvals_old > 0) {
1132  amrex::Error("The no_substepping flag is deprecated -- set substepping_type instead");
1133  }
1134 
1135  pp.queryAdd("ncorr", ncorr);
1136  // Wall distance on a terrain-fitted mesh (RANS): "poisson" (Tucker 2003
1137  // differential-equation distance) or "terrain_height" (height above the
1138  // local surface projected on its normal, no linear solve)
1139  pp.queryAdd("wall_dist_type", wall_dist_type);
1140  if (wall_dist_type != "poisson" && wall_dist_type != "terrain_height") {
1141  amrex::Error("erf.wall_dist_type must be poisson or terrain_height");
1142  }
1143  pp.queryAdd("poisson_abstol", poisson_abstol);
1144  pp.queryAdd("poisson_reltol", poisson_reltol);
1145 #ifdef AMREX_USE_FLOAT
1146  poisson_abstol = amrex::max(poisson_abstol,amrex::Real(1e-6));
1147  poisson_reltol = amrex::max(poisson_reltol,amrex::Real(1e-6));
1148 #endif
1149  for (int lev = 0; lev <= max_level; lev++) {
1150  if (anelastic[lev] != 0)
1151  {
1153  }
1154  }
1155 
1156  pp.queryAdd("force_stage1_single_substep", force_stage1_single_substep);
1157 
1158  // Include Coriolis forcing?
1159  pp.queryAdd("use_coriolis", use_coriolis);
1160  pp.queryAdd("variable_coriolis", variable_coriolis);
1161 
1162  // Include four stream radiation approximation
1163  pp.queryAdd("four_stream_radiation", four_stream_radiation);
1164 
1165  // flags for whether to apply other source terms in substep only
1166  pp.queryAdd("immersed_forcing_substep", immersed_forcing_substep); // apply immersed forcing source terms in substep only
1167  pp.queryAdd("forest_substep", forest_substep); // apply canopy-related source terms in substep only
1168 
1169  // Fixed-leaf-temperature canopy heat exchange
1170  pp.query("forest_biophysics", forest_biophysics);
1171  pp.query("forest_biophysics_heat", forest_biophysics_heat);
1172  pp.query("forest_leaf_theta_fixed", forest_leaf_theta_fixed);
1173 
1176  "forest_biophysics_heat requires forest_biophysics = true");
1180  "forest_biophysics_heat requires a positive forest_leaf_theta_fixed");
1183  "forest_leaf_theta_fixed requires forest_biophysics_heat = true");
1184 
1185  // immersed forcing parameters
1186  pp.queryAdd("if_Cd_momentum", if_Cd_momentum);
1187  pp.queryAdd("if_Cd_scalar", if_Cd_scalar);
1188  pp.queryAdd("if_implicit_drag", if_implicit_drag); // flag for implicit vs. explicit drag formulation
1189  pp.queryAdd("if_z0", if_z0);
1190  pp.queryAdd("if_surf_temp_flux", if_surf_temp_flux);
1191  pp.queryAdd("if_init_surf_temp", if_init_surf_temp);
1192 
1193  pp.queryAdd("if_surf_heating_rate", if_surf_heating_rate);
1194 
1195  // Modify rate to be in units of K / s rather than K / hr
1196  if_surf_heating_rate /= amrex::Real(3600.0); // [K/s]
1197 
1198  pp.queryAdd("if_Olen", if_Olen_in);
1199  pp.queryAdd("if_use_most",if_use_most);
1200  pp.queryAdd("if_snap_partial_cells",if_snap_partial_cells);
1201  // The snapped staircase puts full-strength forcing on every wall face,
1202  // whose explicit relaxation rate (Cd / dx per substep) sits at the
1203  // stability limit and fails where faces stack at rims and corners; the
1204  // point-implicit form holds at any rate, so the snap uses it.
1206  amrex::Print() << "erf.if_snap_partial_cells: using the point-implicit drag (erf.if_implicit_drag = true)\n";
1207  if_implicit_drag = true;
1208  }
1209  pp.queryAdd("if_stability_correction",if_stability_correction);
1210  pp.queryAdd("if_ws_floor",if_ws_floor);
1211  pp.queryAdd("if_damp_alpha",if_damp_alpha);
1212  // Opt-in WRF-style bounds on the wall law (erf-model/ERF#4016): the wind floor behind the
1213  // friction velocity of its stability estimate, and the cap on psi_m in the momentum law as
1214  // a fraction of ln(z/z0); 0 and 1 (the defaults) turn them off
1215  pp.queryAdd("if_stability_wind_floor",if_stability_wind_floor);
1216  pp.queryAdd("if_psi_cap_factor",if_psi_cap_factor);
1217  if (!(if_stability_wind_floor >= zero)) {
1218  amrex::Abort("erf.if_stability_wind_floor must be >= 0 [m/s] (0 leaves the wind as it is)");
1219  }
1220  if (!(if_psi_cap_factor > zero && if_psi_cap_factor <= one)) {
1221  amrex::Abort("erf.if_psi_cap_factor must be in (0, 1] (1 caps psi at ln(z/z0))");
1222  }
1223  // Say so when a bound is set and the wall law's stability estimate is in use
1224  if ((terrain_type == TerrainType::ImmersedForcing || buildings_type == BuildingsType::ImmersedForcing) &&
1225  (if_use_most || if_surf_temp_flux != amrex::Real(1e-8) || if_Olen_in != amrex::Real(1e-8)) &&
1226  (if_psi_cap_factor < one || if_stability_wind_floor > zero))
1227  {
1228  amrex::Print() << "Immersed wall law: erf.if_psi_cap_factor = " << if_psi_cap_factor
1229  << ", erf.if_stability_wind_floor = " << if_stability_wind_floor
1230  << " m/s (WRF-style bounds; the defaults 1 and 0 turn them off)\n";
1231  }
1232 
1233  if ((if_init_surf_temp > zero && if_surf_temp_flux != amrex::Real(1e-8)) ||
1234  (if_init_surf_temp > zero && if_Olen_in != amrex::Real(1e-8)) ||
1235  (if_Olen_in != amrex::Real(1e-8) && if_surf_temp_flux != amrex::Real(1e-8)))
1236  {
1237  amrex::Error("Can only specify one of init_surf_temp, surf_temp_flux, or Olen");
1238  }
1239  if (if_Olen_in == zero &&
1240  (terrain_type == TerrainType::ImmersedForcing || buildings_type == BuildingsType::ImmersedForcing)) {
1241  amrex::Abort("erf.if_Olen = 0 is not an Obukhov length: give a nonzero length [m] (a large |L| is near neutral)");
1242  }
1243 
1244  // Flag to do MOST rotations with terrain
1245  pp.queryAdd("use_rotate_surface_flux",use_rotate_surface_flux);
1247  AMREX_ASSERT_WITH_MESSAGE(terrain_type != TerrainType::None,"MOST stress rotations are only valid with terrain!");
1248  }
1249 
1250  // Which external forcings?
1251  abl_driver_type = ABLDriverType::None; // Default: no ABL driver for simulating classical fluid dynamics problems
1252  pp.query_enum_case_insensitive("abl_driver_type",abl_driver_type);
1253  pp.queryAdd("const_massflux_u", const_massflux_u);
1254  pp.queryAdd("const_massflux_v", const_massflux_v);
1255  pp.queryAdd("const_massflux_tau", const_massflux_tau);
1256  pp.queryAdd("const_massflux_layer_lo", const_massflux_layer_lo);
1257  pp.queryAdd("const_massflux_layer_hi", const_massflux_layer_hi);
1258 
1259  // Which type of inflow turbulent generation
1260  pert_type.resize(max_level+1);
1261  for (int lev = 0; lev <= max_level; ++lev) {
1262  pert_type[lev] = PerturbationType::None; // Default
1264  pp, "perturbation_type", pert_type[lev], lev, max_level);
1265  }
1266 
1267  amrex::Vector<amrex::Real> abl_pressure_grad_in = {zero, zero, zero};
1268  pp.queryarr("abl_pressure_grad",abl_pressure_grad_in);
1269  for(int i = 0; i < AMREX_SPACEDIM; ++i) abl_pressure_grad[i] = abl_pressure_grad_in[i];
1270 
1271  amrex::Vector<amrex::Real> abl_geo_forcing_in = {zero, zero, zero};
1272  if(pp.queryarr("abl_geo_forcing",abl_geo_forcing_in)) {
1273  amrex::Print() << "Specified abl_geo_forcing: (";
1274  for (int i = 0; i < AMREX_SPACEDIM; ++i) {
1275  abl_geo_forcing[i] = abl_geo_forcing_in[i];
1276  amrex::Print() << abl_geo_forcing[i] << " ";
1277  }
1278  amrex::Print() << ")" << std::endl;
1279  }
1280 
1281  if (use_coriolis)
1282  {
1284  }
1285 
1286  pp.queryAdd("add_custom_rhotheta_forcing", custom_rhotheta_forcing);
1287  pp.queryAdd("add_custom_moisture_forcing", custom_moisture_forcing);
1288  pp.queryAdd("add_custom_w_subsidence", custom_w_subsidence);
1289  pp.queryAdd("add_do_theta_advection", do_theta_advection); // If true, apply custom subsidence to (rho*theta) when add_custom_w_subsidence is used
1290  pp.queryAdd("add_do_mom_advection", do_mom_advection); // If true, apply custom subsidence to momentum when add_custom_w_subsidence is used
1291  pp.queryAdd("add_custom_geostrophic_profile", custom_geostrophic_profile);
1292  pp.queryAdd("custom_forcing_uses_primitive_vars", custom_forcing_prim_vars);
1293  pp.queryAdd("spatial_rhotheta_forcing", spatial_rhotheta_forcing);
1294  pp.queryAdd("spatial_moisture_forcing", spatial_moisture_forcing);
1295 
1296  pp.queryAdd("nudging_from_input_sounding", nudging_from_input_sounding);
1297 
1298  // Nudging towards observations at stations; the stations and the
1299  // parameters are read by the ObsNudging class, under erf.obs_nudging
1300  pp.queryAdd("nudging_from_observations", nudging_from_observations);
1301  if (nudging_from_observations && terrain_type == TerrainType::EB) {
1302  amrex::Abort("erf.nudging_from_observations does not support erf.terrain_type = EB; "
1303  "use a terrain-fitted mesh or immersed forcing");
1304  }
1305 
1306  int nudging_u_z1_set = pp.queryAdd("nudging_u_z1", nudging_u_z1);
1307  int nudging_u_z2_set = pp.queryAdd("nudging_u_z2", nudging_u_z2);
1308  pp.queryAdd("nudging_t_z1", nudging_t_z1);
1309  pp.queryAdd("nudging_t_z2", nudging_t_z2);
1310  pp.queryAdd("nudging_q_z1", nudging_q_z1);
1311  pp.queryAdd("nudging_q_z2", nudging_q_z2);
1312 
1314  "nudging_u_z1 must be less than or equal to nudging_u_z2");
1316  "nudging_t_z1 must be less than or equal to nudging_t_z2");
1318  "nudging_q_z1 must be less than or equal to nudging_q_z2");
1319 
1320  pp.queryAdd("nudging_u", nudging_u);
1321  pp.queryAdd("nudging_t", nudging_t);
1322  pp.queryAdd("nudging_q", nudging_q);
1323 
1324  pp.queryAdd("large_scale_forcing", large_scale_forcing);
1325 
1327  if (!nudging_u) {
1328  amrex::Print() << "WARNING: erf.nudging_u = false has no effect when erf.large_scale_forcing "
1329  "= true; momentum nudging is then controlled solely by large_scale_forcing.\n";
1330  }
1331  if (nudging_u_z1_set || nudging_u_z2_set) {
1332  amrex::Print() << "WARNING: erf.nudging_u_z1/erf.nudging_u_z2 are ignored when "
1333  "erf.large_scale_forcing = true; momentum nudging is then applied "
1334  "at all heights.\n";
1335  }
1336  }
1337 
1340  "Should not have both abl_geo_wind_table and custom_geostrophic_profile set.");
1341 
1342  pp.queryAdd("Ave_Plane", ave_plane);
1343 
1344  // Use numerical diffusion?
1345  pp.queryAdd("num_diff_coeff",num_diff_coeff);
1347  "Numerical diffusion coefficient must be between 0 & one");
1348  use_num_diff = (num_diff_coeff > 0);
1349  if (use_num_diff) {
1350  amrex::Print() << "6th-order numerical diffusion turned on with coefficient = "
1351  << num_diff_coeff << std::endl;
1352  num_diff_coeff *= amrex::Math::powi<-6>(two);
1353  }
1354 
1355  advChoice.init_params(pp_prefix);
1356  diffChoice.init_params(pp_prefix);
1357  dampingChoice.init_params(pp_prefix);
1358  spongeChoice.init_params(pp_prefix);
1359  ebChoice.init_params(pp_prefix);
1360 
1361  turbChoice.resize(max_level+1);
1362  for (int lev = 0; lev <= max_level; lev++) {
1363  turbChoice[lev].init_params(lev,max_level,pp_prefix);
1364  }
1365 
1366  // WRF's Smagorinsky-2D slope limiter divides K_h by the terrain slope factor of the
1367  // mesh, which is 1 everywhere without a terrain-fitted mesh; and the EB closure
1368  // (ComputeTurbulentViscosityLES_EB) applies neither limit.
1369  bool smag2d_requested = false;
1370  bool smag2d_somewhere = false;
1371  for (int lev = 0; lev <= max_level; lev++) {
1372  smag2d_requested = smag2d_requested || turbChoice[lev].smag2d_limits_requested;
1373  smag2d_somewhere = smag2d_somewhere || turbChoice[lev].smag2d;
1374  }
1375  if (smag2d_requested && !smag2d_somewhere) {
1376  amrex::Error("erf.smag2d_slope_limiter and erf.smag2d_kh_cap apply only to "
1377  "erf.les_type = Smagorinsky2D, which no level uses");
1378  }
1379  for (int lev = 0; lev <= max_level; lev++) {
1380  const bool fitted = (terrain_type == TerrainType::StaticFittedMesh ||
1381  terrain_type == TerrainType::MovingFittedMesh);
1382  if (turbChoice[lev].smag2d_slope_limiter && !fitted) {
1383  amrex::Error("erf.smag2d_slope_limiter requires erf.terrain_type = StaticFittedMesh "
1384  "or MovingFittedMesh");
1385  }
1386  if (turbChoice[lev].smag2d_kh_cap > zero && terrain_type == TerrainType::EB) {
1387  amrex::Error("erf.smag2d_kh_cap is not supported with erf.terrain_type = EB");
1388  }
1389  }
1390 
1391  // erf.radiation_model = TwoStream selects the two-stream model; its
1392  // erf.radiation.* sub-options are read only then.
1393  radChoice.init_params(rad_type == RadiationType::TwoStream, pp_prefix);
1394 
1395  // Noah-MP integrates on the downwelling shortwave, downwelling longwave and solar
1396  // zenith angle a radiation model writes into it. Only RRTMGP and TwoStream register
1397  // those outputs with the land model (rad_feeds_lsm, ERF::init_stuff), so under any
1398  // other choice they are never written and Noah-MP runs with no radiative forcing at
1399  // all -- the inputs it reads fall back to zero. That is a legitimate thing to want
1400  // in a test, and rarely what anyone running a land model means, so say it at
1401  // start-up.
1402  if (lsm_type == LandSurfaceType::NOAHMP && !rad_feeds_lsm()) {
1403  amrex::Print() << "WARNING: erf.land_surface_model = NOAHMP with erf.radiation_model = "
1404  << amrex::getEnumNameString(rad_type)
1405  << ": only RRTMGP and TwoStream supply the downwelling shortwave, "
1406  "downwelling longwave and solar zenith angle Noah-MP needs. Noah-MP "
1407  "will run with no radiative forcing (zero SWDOWN, GLW and COSZEN).\n";
1408  }
1409 
1410  vert_implicit_fac.resize(max_level+1);
1411  for (int lev = 0; lev <= max_level; lev++) {
1412  vert_implicit_fac[lev].resize(3);
1413  vert_implicit_fac[lev][0] = one;
1414  vert_implicit_fac[lev][1] = one;
1415  vert_implicit_fac[lev][2] = zero;
1416  }
1417 
1418  // YSU PBL: use consistent coriolis frequency
1419  for (int lev = 0; lev <= max_level; lev++) {
1420  if (turbChoice[lev].pbl_ysu_use_consistent_coriolis) {
1421  if (use_coriolis) {
1422  turbChoice[lev].pbl_ysu_coriolis_freq = coriolis_factor * sinphi;
1423  if (lev == 0) {
1424  amrex::Print() << "YSU PBL using ERF coriolis frequency: " << turbChoice[lev].pbl_ysu_coriolis_freq << std::endl;
1425  }
1426  } else {
1427  amrex::Error("YSU cannot use ERF coriolis frequency if not using coriolis");
1428  }
1429  }
1430  }
1431  // MRF
1432  for (int lev = 0; lev <= max_level; lev++) {
1433  if (turbChoice[lev].pbl_ysu_use_consistent_coriolis) {
1434  if (use_coriolis) {
1435  turbChoice[lev].pbl_ysu_coriolis_freq = coriolis_factor * sinphi;
1436  if (lev == 0) {
1437  amrex::Print() << "MRF PBL using ERF coriolis frequency: " << turbChoice[lev].pbl_ysu_coriolis_freq << std::endl;
1438  }
1439  } else {
1440  amrex::Error("MRF cannot use ERF coriolis frequency if not using coriolis");
1441  }
1442  }
1443  }
1444 
1445  // What's the strength of the bdy nudging?
1446  pp.queryAdd("bdy_nudge_factor",bdy_nudge_factor);
1447 
1448  // Optionally use the dry-air density reconstructed from wrfbdy.
1449  pp.queryAdd("use_wrf_bdy_density", use_wrf_bdy_density);
1450 
1451  // Optionally ingest cloud water and cloud ice from wrfinput/wrfbdy.
1452  pp.queryAdd("use_wrf_bdy_qc_qi", use_wrf_bdy_qc_qi);
1453 
1454  if (!use_real_bcs || init_type != InitType::WRFInput) {
1455  use_wrf_bdy_density = false;
1456  }
1457 
1458  pp.queryAdd("bdy_rho_nudge_factor", bdy_rho_nudge_factor);
1459 
1460  // Which approach to nudging the moist variables in the boundary region?
1461  pp.queryAdd("bdy_moist_nudge_type",bdy_moist_nudge_type);
1462  if (bdy_moist_nudge_type < 0 || bdy_moist_nudge_type > 3) {
1463  amrex::Error("erf.bdy_moist_nudge_type must be one of 0, 1, 2, or 3");
1464  }
1465  if (bdy_moist_nudge_type == 3 && !use_wrf_bdy_qc_qi) {
1466  amrex::Error("erf.bdy_moist_nudge_type = 3 requires erf.use_wrf_bdy_qc_qi = true");
1467  }
1468  if (use_wrf_bdy_qc_qi) {
1470  amrex::Error("erf.use_wrf_bdy_qc_qi requires an active moisture model");
1471  }
1472  if (!use_real_bcs || init_type != InitType::WRFInput) {
1473  amrex::Error("erf.use_wrf_bdy_qc_qi requires WRFInput real boundary conditions");
1474  }
1477  amrex::Error("erf.use_wrf_bdy_qc_qi requires active qv and qc component indices");
1478  }
1479  const int optional_moisture_comps[] = {moisture_indices.qi,
1483  for (const int comp : optional_moisture_comps) {
1484  if (comp != -1 && (comp < RhoQ1_comp || comp > RhoQ11_comp)) {
1485  amrex::Error("erf.use_wrf_bdy_qc_qi found an invalid active moisture component index");
1486  }
1487  }
1488  }
1489 
1490  // Are me transporting the scalar component?
1491  pp.queryAdd("transport_scalar",transport_scalar);
1492 
1493  for (int lev = 0; lev <= max_level; ++lev) {
1494  if (turbChoice[lev].uses_eamxx_shoc()) {
1495  use_eamxx_shoc = true;
1496  }
1497  if (turbChoice[lev].uses_native_shoc()) {
1498  use_native_shoc = true;
1500  }
1501  }
1502 
1503  // Set up the vertical implicit diffusion solve
1504  int n_impfac = pp.countval("vert_implicit_fac");
1505  AMREX_ALWAYS_ASSERT(n_impfac == 0 || n_impfac == 1 || n_impfac==3);
1506  if (n_impfac == 1) {
1507  amrex::Real fac_in;
1508  pp.get("vert_implicit_fac", fac_in);
1509  for (int lev = 0; lev <= max_level; lev++) {
1510  for (int i=0; i<3; ++i) {
1511  vert_implicit_fac[lev][i] = fac_in;
1512  }
1513  }
1514  } else if (n_impfac == 3) {
1515  for (int lev = 0; lev <= max_level; lev++) {
1516  pp.getarr("vert_implicit_fac", vert_implicit_fac[lev]);
1517  }
1518  }
1519 
1520  // Record whether the user explicitly requested these
1521  const bool user_set_imp_thermal = pp.contains("implicit_thermal_diffusion");
1522  const bool user_set_imp_moisture = pp.contains("implicit_moisture_diffusion");
1523  const bool user_set_imp_ke = pp.contains("implicit_ke_diffusion");
1524  const bool user_set_imp_momentum = pp.contains("implicit_momentum_diffusion");
1525 
1526  // If true (default), include implicit contributions to vertical thermal diffusion
1527  pp.queryAdd("implicit_thermal_diffusion", implicit_thermal_diffusion);
1528 
1529  // If true (default), include implicit contributions to vertical moisture diffusion
1530  pp.queryAdd("implicit_moisture_diffusion", implicit_moisture_diffusion);
1531 
1532  // If true (default), include implicit contributions to vertical KE diffusion
1533  pp.queryAdd("implicit_ke_diffusion", implicit_ke_diffusion);
1534 
1535  // If true (default), include implicit contributions in tau13, tau23,
1536  pp.queryAdd("implicit_momentum_diffusion", implicit_momentum_diffusion);
1537 
1538  // If true (default false), also solve the compact terrain-metric part of the vertical
1539  // diffusion, K_h M d2/dz2 (ERF_TerrainImplicitMetric.H), implicitly (terrain-fitted
1540  // meshes only)
1541  pp.queryAdd("implicit_terrain_metric", implicit_terrain_metric);
1542 
1543  // The default is true (i.e. that it happens before the acoustic substepping).
1544  pp.queryAdd("implicit_before_substep", implicit_before_substep);
1545  for (int lev = 0; lev <= max_level; lev++) {
1547  amrex::Print() << "implicit_before_substep cannot be false without substepping; setting to true." << "\n";
1548  implicit_before_substep = true;
1549  }
1550  }
1551 
1552  // Handle shoc case -- SHOC owns whatever vertical diffusion the host does not
1553  if (uses_shoc_family()) {
1554  const bool host_owns_scalars = host_owns_vertical_scalar_diffusion();
1555  const bool host_owns_momentum = host_owns_vertical_momentum_diffusion();
1556  if (!host_owns_scalars &&
1557  ( (user_set_imp_thermal && implicit_thermal_diffusion ) ||
1558  (user_set_imp_moisture && implicit_moisture_diffusion) ||
1559  (user_set_imp_ke && implicit_ke_diffusion ) ) ) {
1560  amrex::Print() << "Ignoring erf.implicit_{thermal,moisture,ke}_diffusion = true; "
1561  << "SHOC owns vertical scalar diffusion." << "\n";
1562  }
1563  if (!host_owns_momentum && user_set_imp_momentum && implicit_momentum_diffusion) {
1564  amrex::Print() << "Ignoring erf.implicit_momentum_diffusion = true; "
1565  << "SHOC owns vertical momentum diffusion." << "\n";
1566  }
1567 
1568  implicit_thermal_diffusion = (implicit_thermal_diffusion && host_owns_scalars);
1570  implicit_ke_diffusion = (implicit_ke_diffusion && host_owns_scalars);
1571  implicit_momentum_diffusion = (implicit_momentum_diffusion && host_owns_momentum);
1572 
1573  // Make the resulting configuration visible in the run log
1574  if (!host_owns_scalars && !host_owns_momentum) {
1575  amrex::Print() << "Turning off vertical implicit solve for all components since SHOC owns diffusion." << "\n";
1576  } else {
1577  amrex::Print() << "SHOC hands vertical diffusion of"
1578  << (host_owns_scalars ? " scalars" : "")
1579  << (host_owns_momentum ? " momentum" : "")
1580  << " to the host; keeping the vertical implicit solve on (theta = "
1582  << ", moisture = " << implicit_moisture_diffusion
1583  << ", tke = " << implicit_ke_diffusion
1584  << ", momenta = " << implicit_momentum_diffusion << ")." << "\n";
1585  }
1586  } // uses_shoc_family
1587 
1588  // Do not allow implicit vertical diff if user turns it off
1589  bool do_vert_implicit = true;
1590  pp.queryAdd("vert_implicit", do_vert_implicit);
1591  if (!do_vert_implicit) {
1592  for (int lev = 0; lev <= max_level; lev++) {
1593  amrex::Print() << "Turning off native vertical implicit solve from vert_implicit flag at level " << lev << std::endl;
1594  vert_implicit_fac[lev][0] = zero;
1595  vert_implicit_fac[lev][1] = zero;
1596  vert_implicit_fac[lev][2] = zero;
1597  }
1598  }
1599 
1600  // The implicit vertical diffusion is only second order in an anelastic run when
1601  // the two stages are the midpoint method and the solve is done in the first stage
1602  // alone: S^* = S^n + (dt/2) F(S^*) and S^{n+1} = S^n + dt F(S^*) give
1603  // S^* = (S^n + S^{n+1})/2, i.e. the implicit midpoint rule. Solving again in the
1604  // second stage would reduce the pair to backward Euler, and with the RK2 (Heun)
1605  // stages there is no stage that plays the role of the midpoint at all.
1606  for (int lev = 0; lev <= max_level; lev++) {
1607  if (anelastic[lev]) {
1608  if (anelastic_type[lev] == AnelasticType::RK2) {
1609  amrex::Print() << "Turning off native vertical implicit solve flag because anelastic at level " << lev
1610  << " with RK2 scheme." << std::endl;
1611  vert_implicit_fac[lev][0] = zero;
1612  vert_implicit_fac[lev][1] = zero;
1613  vert_implicit_fac[lev][2] = zero;
1614  } else if (anelastic_type[lev] == AnelasticType::MidPoint) {
1615  if (do_vert_implicit && vert_implicit_fac[lev][0] != one) {
1616  amrex::Print() << "Forcing implicit factor 1 in first stage of MidPoint to ensure second-order accuracy." << std::endl;
1617  vert_implicit_fac[lev][0] = one;
1618  }
1619  if (vert_implicit_fac[lev][1] > zero) {
1620  amrex::Print() << "Turning off the second-stage vertical implicit solve at level " << lev
1621  << " because anelastic with MidPoint solves in the first stage only."
1622  << std::endl;
1623  }
1624  // The anelastic integrator only takes two stages, so [2] is never used
1625  vert_implicit_fac[lev][1] = zero;
1626  vert_implicit_fac[lev][2] = zero;
1627  }
1628  }
1629  }
1630 
1631  // Do not allow implicit vertical diff with EB
1632  if (terrain_type == TerrainType::EB) {
1633  for (int lev = 0; lev <= max_level; lev++) {
1634  if (do_vert_implicit) {
1635  amrex::Print() << "Implicit diffusion is not supported with EB; turning off at level " << lev << "\n";
1636  vert_implicit_fac[lev][0] = zero;
1637  vert_implicit_fac[lev][1] = zero;
1638  vert_implicit_fac[lev][2] = zero;
1639  }
1640  }
1641  }
1642 
1643  // The EB diffusion path adds no buoyancy, shear or dissipation source for
1644  // a prognostic TKE closure
1645  if (terrain_type == TerrainType::EB) {
1646  for (int lev = 0; lev <= max_level; lev++) {
1647  if (turbChoice[lev].use_keqn) {
1648  amrex::Error("erf.terrain_type = EB cannot be used with erf.les_type = Deardorff "
1649  "or erf.rans_type = kEqn: the EB diffusion path has no TKE sources");
1650  }
1651  }
1652  }
1653 
1654  // Do not allow implicit vertical diff when all the components are false
1659  amrex::Print() << "Thermal, moisture, KE, and momentum diffusion are all turned off; turning off vertical implicit solve." << std::endl;
1660  for (int lev = 0; lev <= max_level; lev++) {
1661  vert_implicit_fac[lev][0] = zero;
1662  vert_implicit_fac[lev][1] = zero;
1663  vert_implicit_fac[lev][2] = zero;
1664  }
1665  }
1666 
1667  // Which type of multilevel coupling
1668  coupling_type = CouplingType::TwoWay; // Default
1669  pp.query_enum_case_insensitive("coupling_type",coupling_type);
1670 
1671  // Test for hybrid (compressible + anelastic) -- in this case we must use one-way coupling
1672  if (any_anelastic && any_compress) {
1673  coupling_type = CouplingType::OneWay;
1674  }
1675 
1676  // Which type of windfarm model
1677  windfarm_type = WindFarmType::None; // Default
1678  pp.query_enum_case_insensitive("windfarm_type",windfarm_type);
1679 
1681  pp.query_enum_case_insensitive("windfarm_loc_type",windfarm_loc_type);
1682 
1683  pp.queryAdd("windfarm_loc_table", windfarm_loc_table);
1684  pp.queryAdd("windfarm_spec_table", windfarm_spec_table);
1685  pp.queryAdd("windfarm_blade_table", windfarm_blade_table);
1686  pp.queryAdd("windfarm_airfoil_tables", windfarm_airfoil_tables);
1687  pp.queryAdd("windfarm_spec_table_extra", windfarm_spec_table_extra);
1688 
1689  // Sampling distance upstream of the turbine to find the
1690  // incoming free stream velocity as a factor of the diameter of the
1691  // turbine. ie. the sampling distance will be this number multiplied
1692  // by the diameter of the turbine
1693  pp.queryAdd("sampling_distance_by_D", sampling_distance_by_D);
1694  pp.queryAdd("turb_disk_angle_from_x", turb_disk_angle);
1695 
1696  pp.queryAdd("windfarm_x_shift",windfarm_x_shift);
1697  pp.queryAdd("windfarm_y_shift",windfarm_y_shift);
1698  // Test if time averaged data is to be output
1699  pp.queryAdd("time_avg_vel",time_avg_vel);
1700 
1701  // Interval means and resolved turbulent moments for plotfile output
1702  pp.queryAdd("compute_mean_vars", compute_mean_vars);
1703  pp.queryAdd("mean_vars_reset_mode", mean_vars_reset_mode);
1704  pp.queryAdd("mean_vars_reset_time", mean_vars_reset_time);
1705 
1706  if (compute_mean_vars &&
1707  mean_vars_reset_mode != "plotfile" && mean_vars_reset_mode != "time") {
1708  amrex::Error("erf.mean_vars_reset_mode must be either 'plotfile' or 'time'");
1709  }
1710  if (compute_mean_vars && mean_vars_reset_mode == "time" &&
1712  amrex::Error("erf.mean_vars_reset_time must be non-negative when "
1713  "erf.mean_vars_reset_mode = 'time'");
1714  }
1715 
1716  pp.queryAdd("hindcast_lateral_forcing", hindcast_lateral_forcing);
1717 
1719  pp.queryAdd("hindcast_boundary_data_dir", hindcast_boundary_data_dir);
1720 
1721  if(hindcast_boundary_data_dir.empty()) {
1722  amrex::Error("ERROR: Missing input parameter 'erf.hindcast_boundary_data_dir' for boundary data for lateral forcing");
1723  }
1724  pp.queryAdd("hindcast_data_interval_in_hrs", hindcast_data_interval_in_hrs);
1726  amrex::Error("ERROR: Input parameter 'erf.hindcast_data_interval_in_hrs' which is the time interval between the "
1727  "data files is either missing or set to less than zero");
1728  }
1729  pp.queryAdd("hindcast_lateral_sponge_strength", hindcast_lateral_sponge_strength);
1730  pp.queryAdd("hindcast_lateral_sponge_length", hindcast_lateral_sponge_length);
1731 
1732  pp.queryAdd("hindcast_zhi_sponge_length", hindcast_zhi_sponge_length);
1733  pp.queryAdd("hindcast_zhi_sponge_strength", hindcast_zhi_sponge_strength);
1734 
1735  pp.queryAdd("hindcast_zhi_sponge_damping", hindcast_zhi_sponge_damping);
1736 
1738  amrex::Error("ERROR: Missing input parameter 'erf.hindcast_lateral_sponge_strength' or it is specified to be less than zero");
1739  }
1740 
1742  amrex::Error("ERROR: Missing input parameter 'erf.hindcast_lateral_sponge_length' or it is specified to be less than zero");
1743  }
1744 
1746  amrex::Error("ERROR: Missing input parameter 'erf.hindcast_zhi_sponge_length' or it is specified to be less than zero");
1747  }
1748 
1750  amrex::Error("ERROR: Missing input parameter 'erf.hindcast_zhi_sponge_strength' or it is specified to be less than zero");
1751  }
1752  }
1753 
1754  pp.queryAdd("hindcast_surface_bcs", hindcast_surface_bcs);
1755  if(hindcast_surface_bcs) {
1756  pp.queryAdd("hindcast_surface_data_dir", hindcast_surface_data_dir);
1757  }
1758 
1759  pp.queryAdd("io_hurricane_eye_tracker", io_hurricane_eye_tracker);
1761  pp.queryAdd("hurricane_eye_latitude", hurricane_eye_latitude);
1762  pp.queryAdd("hurricane_eye_longitude", hurricane_eye_longitude);
1764  amrex::Error("ERROR: You are using 'erf.io_hurricane_eye_tracker' to write out the files that track the eye of the hurricane"
1765  " but have not provided the initial location of the eye of the hurricane to be tracked. There has to be two"
1766  " options in the inputs - erf.hurricane_eye_latitude and erf.hurricane_eye_longitude that gives an approximate"
1767  " location of the eye in the initial condition");
1768  }
1769  }
1770 
1771  pp.queryAdd("is_init_for_ensemble", is_init_for_ensemble);
1772  if(is_init_for_ensemble) {
1773  amrex::ParmParse pp_ens("ensemble");
1774  pp_ens.queryAdd("n_members", n_ensemble);
1775  if(n_ensemble < 2) {
1776  amrex::Abort("You are using an ensemble run. There needs to be at least 2 ensemble members. "
1777  "erf.n_ensemble must be >=2.");
1778  }
1779  pp_ens.queryAdd("coarse_bckgnd_data_file", coarse_bckgnd_data_file);
1780  if (coarse_bckgnd_data_file.empty()) {
1781  amrex::Abort("coarse_bckgnd_data_file is empty! For ensmeble simulations, there needs to be a coarse background file which "
1782  "contains the data which will be interpolated onto the fine mesh. There has to a entry ensemble.coarse_bckgnd_data_file "
1783  "which contains the filename in the inputs.");
1784  }
1785  pp_ens.queryAdd("ens_pert_amplitude", ens_pert_amplitude);
1786  if(ens_pert_amplitude <= 0.0) {
1787  amrex::Error("You are using initialization for ensemble simulations using the inputs option "
1788  "ensemble.is_init_for_ensemble=true. In this case, there has to be an option "
1789  "ensemble.ens_pert_amplitude which is the value of the amplitude of the perturbation "
1790  "to be added to the background state and has to be greater than 0.0");
1791  }
1792  pp_ens.queryAdd("ens_pert_correlated_radius", ens_pert_correlated_radius);
1793  if(ens_pert_correlated_radius <= 0.0) {
1794  amrex::Error("You are using initialization with spatially correlated perturbations using the inputs option "
1795  "ensemble.is_init_for_ensemble=true. In this case, there has to be an option "
1796  "ensemble.ens_pert_correlated_radius which is the value of the the spatial correlation radius, "
1797  "and has to be greater than 0.0");
1798  }
1799  }
1800  }
constexpr amrex::Real CONST_GRAV
Definition: ERF_Constants.H:68
constexpr amrex::Real R_d
Definition: ERF_Constants.H:46
bool anelastic_superdroplets_configuration_invalid(const MoistureType moisture_type, const bool any_anelastic) noexcept
Whether an anelastic SuperDroplets configuration is unsupported.
Definition: ERF_DataStruct.H:140
#define RhoQ11_comp
Definition: ERF_IndexDefines.H:58
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:48
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
constexpr amrex::Real two
Definition: ERF_NumericalConstants.H:38
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:37
void read_shoc_transport_modes(ShocTransportMode &transport_mode, ShocMomentumTransport &momentum_transport)
Read the native SHOC transport modes from the erf.shoc input namespace.
Definition: ERF_ShocTransportStruct.H:118
int query_one_or_per_level_enum_case_insensitive(const amrex::ParmParse &pp, const char *query_string, T &query_var, const int lev, const int maxlev)
Query a scalar or per-level enum input value using case-insensitive matching.
Definition: ERF_TurbStruct.H:81
AMREX_ASSERT_WITH_MESSAGE(wbar_cutoff_min > wbar_cutoff_max, "ERROR: wbar_cutoff_min < wbar_cutoff_max")
void init_params(std::string pp_prefix)
Read advection options from the input parameter database.
Definition: ERF_AdvStruct.H:25
void init_params(std::string pp_prefix)
Read damping options from the input parameter database.
Definition: ERF_DampingStruct.H:28
void init_params(std::string pp_prefix)
Read diffusion options from the input parameter database.
Definition: ERF_DiffStruct.H:28
void init_params(std::string pp_prefix)
Read embedded-boundary options from the input parameter database.
Definition: ERF_EBStruct.H:42
int qs
snow
Definition: ERF_DataStruct.H:253
int qr
rain
Definition: ERF_DataStruct.H:252
int qi
cloud ice
Definition: ERF_DataStruct.H:251
int qv
water vapor
Definition: ERF_DataStruct.H:249
int qc
cloud liquid water
Definition: ERF_DataStruct.H:250
int qg
graupel
Definition: ERF_DataStruct.H:254
static MoistureComponentIndices from_moisture_model(const MoistureType moisture_type)
Build the complete index map – conserved-state components and qmoist diagnostic slots – for a moistur...
Definition: ERF_DataStruct.H:338
void init_params(bool two_stream_selected, std::string pp_prefix)
Definition: ERF_RadStruct.H:858
bool use_coupled_sst
Definition: ERF_DataStruct.H:2562
int sbm_moment_mode
Definition: ERF_DataStruct.H:2526
bool custom_geostrophic_profile
Whether a custom geostrophic wind profile is used.
Definition: ERF_DataStruct.H:2363
int n_ensemble
Number of ensemble members.
Definition: ERF_DataStruct.H:2643
bool implicit_before_substep
Whether implicit diffusion is applied before acoustic substepping.
Definition: ERF_DataStruct.H:2284
std::string hindcast_boundary_data_dir
Directory containing hindcast lateral boundary data.
Definition: ERF_DataStruct.H:2631
amrex::Real if_psi_cap_factor
Cap on psi_m in the immersed momentum wall law as a fraction of ln(z/z0) (1: none).
Definition: ERF_DataStruct.H:2334
amrex::Real ens_pert_correlated_radius
Spatial correlation radius for ensemble perturbations.
Definition: ERF_DataStruct.H:2644
amrex::Real forest_leaf_theta_fixed
Definition: ERF_DataStruct.H:2620
static InitType init_type
Initial-condition source selected for the run.
Definition: ERF_DataStruct.H:2218
bool io_hurricane_eye_tracker
Whether hurricane-eye tracking output is enabled.
Definition: ERF_DataStruct.H:2639
amrex::Real const_massflux_layer_lo
Lower height of the constant-mass-flux forcing layer.
Definition: ERF_DataStruct.H:2626
amrex::Real hindcast_zhi_sponge_length
Length of the upper hindcast sponge layer.
Definition: ERF_DataStruct.H:2636
amrex::Real gravity
Effective gravitational acceleration.
Definition: ERF_DataStruct.H:2343
bool variable_coriolis
Whether spatially varying Coriolis forcing is enabled.
Definition: ERF_DataStruct.H:2570
amrex::Real poisson_abstol
Absolute tolerance for the Poisson solve.
Definition: ERF_DataStruct.H:2295
amrex::Real if_Cd_momentum
Immersed-forcing drag coefficient for momentum.
Definition: ERF_DataStruct.H:2317
bool nudging_t
Definition: ERF_DataStruct.H:2384
amrex::Real if_Olen_in
Input Obukhov length for immersed-forcing MOST [m].
Definition: ERF_DataStruct.H:2327
bool forest_biophysics
Definition: ERF_DataStruct.H:2618
void build_coriolis_forcings_const_lat(std::string pp_prefix)
Build constant-latitude Coriolis forcing parameters.
Definition: ERF_DataStruct.H:2143
bool use_pert_pres_gradient
Whether momentum equations use perturbational pressure gradients.
Definition: ERF_DataStruct.H:2303
bool sbm_test_native_qc_write_fault
Definition: ERF_DataStruct.H:2528
amrex::Vector< int > project_initial_velocity
Per-level flag for projecting the initial velocity.
Definition: ERF_DataStruct.H:2262
int ave_plane
Averaging plane index used by diagnostics.
Definition: ERF_DataStruct.H:2572
bool nudging_q
Definition: ERF_DataStruct.H:2385
int ncorr
Number of projection correction iterations.
Definition: ERF_DataStruct.H:2289
bool use_rotate_surface_flux
Whether MOST surface fluxes are rotated with terrain.
Definition: ERF_DataStruct.H:2392
bool moisture_tight_coupling
Whether moisture updates use tight coupling.
Definition: ERF_DataStruct.H:2577
bool compute_mean_vars
Definition: ERF_DataStruct.H:2409
amrex::Real beta_s
Time off-centering coefficient for forward weighting.
Definition: ERF_DataStruct.H:2271
bool interp_atmos_from_coarse
Definition: ERF_DataStruct.H:2612
amrex::Real if_z0
Immersed-forcing roughness length [m].
Definition: ERF_DataStruct.H:2323
bool forest_substep
Whether canopy source terms are applied only during substeps.
Definition: ERF_DataStruct.H:2314
bool use_wrf_bdy_density
Definition: ERF_DataStruct.H:2590
std::string mean_vars_reset_mode
Definition: ERF_DataStruct.H:2412
amrex::Real num_diff_coeff
Numerical diffusion coefficient after input scaling.
Definition: ERF_DataStruct.H:2521
amrex::Real bdy_nudge_factor
Boundary sponge nudging factor.
Definition: ERF_DataStruct.H:2587
int sbm_cloud_rain_split
Definition: ERF_DataStruct.H:2527
amrex::Real rdOcp
Ratio of dry-air gas constant to c_p.
Definition: ERF_DataStruct.H:2345
bool hindcast_lateral_forcing
Whether hindcast lateral forcing is enabled.
Definition: ERF_DataStruct.H:2633
bool do_theta_advection
Whether custom vertical subsidence is applied to rho-theta.
Definition: ERF_DataStruct.H:2361
amrex::Real nudging_q_z2
Definition: ERF_DataStruct.H:2381
static bool use_real_bcs
Whether real-data lateral boundary conditions are used.
Definition: ERF_DataStruct.H:2233
bool spatial_moisture_forcing
Whether spatially varying moisture forcing is enabled.
Definition: ERF_DataStruct.H:2366
amrex::Real nudging_u_z2
Definition: ERF_DataStruct.H:2377
static SoundingType sounding_type
Interpretation used for input sounding profiles.
Definition: ERF_DataStruct.H:2221
int bdy_moist_nudge_type
Moist-variable nudging strategy in boundary regions.
Definition: ERF_DataStruct.H:2599
amrex::Real poisson_reltol
Relative tolerance for the Poisson solve.
Definition: ERF_DataStruct.H:2296
UrbanType urban_type
Definition: ERF_DataStruct.H:2536
bool time_avg_vel
Whether time-averaged velocity fields are output.
Definition: ERF_DataStruct.H:2406
bool have_geo_wind_profile
Whether a geostrophic wind profile has been configured.
Definition: ERF_DataStruct.H:2568
RadChoice radChoice
Definition: ERF_DataStruct.H:2254
bool four_stream_radiation
Whether the four-stream radiation approximation is enabled.
Definition: ERF_DataStruct.H:2310
amrex::Real if_damp_alpha
Immersed-forcing damping coefficient.
Definition: ERF_DataStruct.H:2332
bool rebalance_wrf_input
Whether to rebalance states from wrfinput and wrfbdy data.
Definition: ERF_DataStruct.H:2340
bool wrfinput_zlevels_from_file
Definition: ERF_DataStruct.H:2609
amrex::Vector< amrex::Real > sbm_edges
Definition: ERF_DataStruct.H:2530
amrex::Real hindcast_data_interval_in_hrs
Time interval between hindcast data files [hr].
Definition: ERF_DataStruct.H:2632
amrex::Real const_massflux_layer_hi
Upper height of the constant-mass-flux forcing layer.
Definition: ERF_DataStruct.H:2627
std::string wall_dist_type
Definition: ERF_DataStruct.H:2290
bool avg_grid_faces_to_nodes
Definition: ERF_DataStruct.H:2602
std::string windfarm_spec_table_extra
Additional wind-farm turbine specification table path.
Definition: ERF_DataStruct.H:2579
amrex::Real if_ws_floor
Wind-speed floor [m/s] in the per-step change limit of the building wall-law forcing.
Definition: ERF_DataStruct.H:2331
bool is_init_for_ensemble
Whether initialization is for an ensemble simulation.
Definition: ERF_DataStruct.H:2642
bool uses_shoc_family() const noexcept
Query whether any SHOC-family PBL scheme is active.
Definition: ERF_DataStruct.H:2464
bool test_mapfactor
Whether to use test map scale factors.
Definition: ERF_DataStruct.H:2299
amrex::Real nudging_u_z1
Definition: ERF_DataStruct.H:2376
bool if_snap_partial_cells
Definition: ERF_DataStruct.H:2329
amrex::Vector< amrex::Real > sbm_pivots
Definition: ERF_DataStruct.H:2531
std::string coarse_bckgnd_data_file
Coarse background data file used for ensemble initialization.
Definition: ERF_DataStruct.H:2646
amrex::Real dz0
Initial vertical grid spacing for stretched-grid setup.
Definition: ERF_DataStruct.H:2350
amrex::Real ens_pert_amplitude
Amplitude of ensemble initialization perturbations.
Definition: ERF_DataStruct.H:2645
std::string windfarm_airfoil_tables
Wind-farm airfoil table paths.
Definition: ERF_DataStruct.H:2580
amrex::Real bdy_rho_nudge_factor
Definition: ERF_DataStruct.H:2596
amrex::Real nudging_q_z1
Definition: ERF_DataStruct.H:2380
bool transport_scalar
Whether the passive scalar component is transported.
Definition: ERF_DataStruct.H:2403
bool hindcast_zhi_sponge_damping
Whether upper-boundary hindcast sponge damping is enabled.
Definition: ERF_DataStruct.H:2637
amrex::Real hurricane_eye_longitude
Initial hurricane-eye longitude.
Definition: ERF_DataStruct.H:2640
bool nudging_from_observations
Whether solution fields are nudged toward observations at stations.
Definition: ERF_DataStruct.H:2374
LandSurfaceType lsm_type
Land-surface model.
Definition: ERF_DataStruct.H:2535
bool large_scale_forcing
Definition: ERF_DataStruct.H:2387
bool substepping_diag
Whether to emit extra CFL diagnostics for compressible substepping.
Definition: ERF_DataStruct.H:2267
amrex::Real mean_vars_reset_time
Definition: ERF_DataStruct.H:2413
std::string windfarm_blade_table
Wind-farm blade table path.
Definition: ERF_DataStruct.H:2580
amrex::Vector< int > is_land
Per-level land/water selector.
Definition: ERF_DataStruct.H:2264
amrex::Real hindcast_lateral_sponge_strength
Strength of the hindcast lateral sponge layer.
Definition: ERF_DataStruct.H:2635
bool forest_biophysics_heat
Definition: ERF_DataStruct.H:2619
ShocTransportMode shoc_transport_mode
Definition: ERF_DataStruct.H:2399
amrex::Real hurricane_eye_latitude
Initial hurricane-eye latitude.
Definition: ERF_DataStruct.H:2640
amrex::Real if_Cd_scalar
Immersed-forcing drag coefficient for scalars.
Definition: ERF_DataStruct.H:2318
std::string windfarm_loc_table
Wind-farm location table path.
Definition: ERF_DataStruct.H:2579
std::string hindcast_surface_data_dir
Directory containing hindcast surface boundary data.
Definition: ERF_DataStruct.H:2631
bool custom_rhotheta_forcing
Whether custom rho-theta forcing is enabled.
Definition: ERF_DataStruct.H:2358
bool sbm_test_donor_cfl_fault
Definition: ERF_DataStruct.H:2529
amrex::Real zsurf
Nominal surface height for stretched-grid setup.
Definition: ERF_DataStruct.H:2349
amrex::Real if_init_surf_temp
Initial immersed-forcing surface temperature [K].
Definition: ERF_DataStruct.H:2325
amrex::Real nudging_t_z2
Definition: ERF_DataStruct.H:2379
std::string windfarm_spec_table
Wind-farm turbine specification table path.
Definition: ERF_DataStruct.H:2579
bool read_int_string(int max_level, const char *string_to_read, amrex::Vector< int > &vec_to_fill, int default_int)
Read one integer value or one value per AMR level.
Definition: ERF_DataStruct.H:2194
amrex::Real if_surf_temp_flux
Immersed-forcing surface temperature flux [K m/s].
Definition: ERF_DataStruct.H:2324
bool spatial_rhotheta_forcing
Whether spatially varying rho-theta forcing is enabled.
Definition: ERF_DataStruct.H:2365
amrex::Vector< int > urban_enabled_lev
Definition: ERF_DataStruct.H:2537
bool custom_w_subsidence
Whether custom vertical subsidence is enabled.
Definition: ERF_DataStruct.H:2360
bool rad_feeds_lsm() const
True when the radiation model's outputs feed the land model (downwelling shortwave,...
Definition: ERF_DataStruct.H:2556
bool custom_moisture_forcing
Whether custom moisture forcing is enabled.
Definition: ERF_DataStruct.H:2359
amrex::Real if_surf_heating_rate
Immersed-forcing surface heating rate [K/hr].
Definition: ERF_DataStruct.H:2326
int sbm_nbins
Definition: ERF_DataStruct.H:2525
MoistureComponentIndices moisture_indices
Index map of the moisture data carried by the active scheme: conserved-state components for the speci...
Definition: ERF_DataStruct.H:2575
amrex::Real grid_stretching_ratio
Vertical grid stretching ratio.
Definition: ERF_DataStruct.H:2348
bool hindcast_surface_bcs
Whether hindcast surface boundary conditions are enabled.
Definition: ERF_DataStruct.H:2634
bool host_owns_vertical_scalar_diffusion() const noexcept
Test whether the host owns scalar diffusion.
Definition: ERF_DataStruct.H:2484
bool immersed_forcing_substep
Whether immersed-forcing source terms are applied only during substeps.
Definition: ERF_DataStruct.H:2313
bool if_use_most
Whether immersed-forcing MOST is enabled.
Definition: ERF_DataStruct.H:2328
amrex::Real const_massflux_tau
Relaxation time scale for constant-mass-flux forcing.
Definition: ERF_DataStruct.H:2625
amrex::Real hindcast_lateral_sponge_length
Length of the hindcast lateral sponge layer.
Definition: ERF_DataStruct.H:2635
bool host_owns_vertical_momentum_diffusion() const noexcept
Test whether the host owns momentum diffusion.
Definition: ERF_DataStruct.H:2473
amrex::Real hindcast_zhi_sponge_strength
Strength of the upper hindcast sponge layer.
Definition: ERF_DataStruct.H:2636
int force_stage1_single_substep
Flag forcing a single substep in the first RK stage.
Definition: ERF_DataStruct.H:2256
amrex::Real c_p
Specific heat at constant pressure for dry air [J/(kg-K)].
Definition: ERF_DataStruct.H:2344
bool if_implicit_drag
Definition: ERF_DataStruct.H:2321
bool do_mom_advection
Whether custom vertical subsidence is applied to momentum.
Definition: ERF_DataStruct.H:2362
bool if_stability_correction
Whether immersed-forcing stability corrections are enabled.
Definition: ERF_DataStruct.H:2330
amrex::Real nudging_t_z1
Definition: ERF_DataStruct.H:2378
amrex::Vector< amrex::Real > sbm_fixture_initial_state
Definition: ERF_DataStruct.H:2532
bool custom_forcing_prim_vars
Whether custom forcing operates on primitive variables.
Definition: ERF_DataStruct.H:2364
amrex::Real if_stability_wind_floor
Wind-speed floor [m/s] behind the friction velocity of the wall law's stability estimate (0: none).
Definition: ERF_DataStruct.H:2333
bool nudging_u
Definition: ERF_DataStruct.H:2383
bool nudging_from_input_sounding
Whether solution fields are nudged toward input sounding data.
Definition: ERF_DataStruct.H:2370
bool use_num_diff
Whether sixth-order numerical diffusion is enabled.
Definition: ERF_DataStruct.H:2520
bool use_wrf_bdy_qc_qi
Whether WRF cloud water and active cloud ice are ingested at real boundaries.
Definition: ERF_DataStruct.H:2593
void init_params(std::string pp_prefix)
Read sponge-layer options from the input parameter database.
Definition: ERF_SpongeStruct.H:28
Here is the call graph for this function:

◆ pbl_suppresses_microphysics_condensation()

bool SolverChoice::pbl_suppresses_microphysics_condensation ( ) const
inlinenoexcept

Query whether the active PBL scheme suppresses microphysics condensation.

Returns
True when the active PBL scheme owns condensation handling.
2496  {
2497  return uses_shoc_family();
2498  }
Here is the call graph for this function:

◆ rad_feeds_lsm()

bool SolverChoice::rad_feeds_lsm ( ) const
inline

True when the radiation model's outputs feed the land model (downwelling shortwave, downwelling longwave, solar zenith angle). RRTMGP writes them for any land model through lsm_output_ptrs; the two-stream model writes the broadband three for Noah-MP only (TwoStreamRadiation::write_land_forcing), since SLM wants the visible / near-infrared direct / diffuse split it does not compute. Both register the outputs in ERF::init_stuff and write them in ERF::advance_radiation; every site that encodes that rule must use this predicate so wiring another model in (e.g. Simple, which already runs through the interface) is one edit.

2556  {
2557  return (rad_type == RadiationType::RRTMGP) ||
2558  (rad_type == RadiationType::TwoStream && lsm_type == LandSurfaceType::NOAHMP);
2559  }

Referenced by NOAHMP::Define(), and init_params().

Here is the caller graph for this function:

◆ rad_uses_interface()

bool SolverChoice::rad_uses_interface ( ) const
inline

True for the models that run through the IRadiation interface (RRTMGP, Simple); the two-stream model has its own class.

2542  {
2543  return (rad_type == RadiationType::RRTMGP) || (rad_type == RadiationType::Simple);
2544  }

◆ read_int_string()

bool SolverChoice::read_int_string ( int  max_level,
const char *  string_to_read,
amrex::Vector< int > &  vec_to_fill,
int  default_int 
)
inline

Read one integer value or one value per AMR level.

Parameters
max_levelMaximum AMR level configured for the run.
string_to_readParmParse key to read.
vec_to_fillDestination vector with one entry per level.
default_intDefault value used when the key is absent.
Returns
True if the key was present in the inputs.
2196  {
2197  amrex::ParmParse pp("erf");
2198  int nvals = pp.countval(string_to_read);
2199  AMREX_ALWAYS_ASSERT(nvals == 0 || nvals == 1 || nvals >= max_level+1);
2200  amrex::Vector<int> temp; temp.resize(nvals);
2201  pp.queryarr(string_to_read,temp);
2202 
2203  if (vec_to_fill.size() < max_level+1) {
2204  vec_to_fill.resize(max_level+1);
2205  }
2206 
2207  if (nvals == 0) {
2208  for (int i = 0; i <= max_level; ++i) vec_to_fill[i] = default_int;
2209  } else if (nvals == 1) {
2210  for (int i = 0; i <= max_level; ++i) vec_to_fill[i] = temp[0];
2211  } else {
2212  for (int i = 0; i <= max_level; ++i) vec_to_fill[i] = temp[i];
2213  }
2214  return (nvals > 0);
2215  }

Referenced by init_params().

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

◆ set_mesh_type()

static void SolverChoice::set_mesh_type ( MeshType  new_mesh_type)
inlinestatic

Override the globally selected mesh type.

Parameters
new_mesh_typeMesh type to store.
2244  {
2245  mesh_type = new_mesh_type;
2246  }

Referenced by ERF::check_mesh_type(), and ProblemBase::init_custom_terrain().

Here is the caller graph for this function:

◆ use_direct_perturbation()

bool SolverChoice::use_direct_perturbation ( int  lev) const
inline

Query whether direct turbulent perturbations are enabled on a level.

Parameters
levAMR level index.
Returns
True if direct, CPM, or CPM_W perturbations are enabled.
2434  {
2435  return pert_type[lev] == PerturbationType::Direct ||
2436  pert_type[lev] == PerturbationType::CPM ||
2437  pert_type[lev] == PerturbationType::CPM_W;
2438  }

◆ use_perturbation()

bool SolverChoice::use_perturbation ( int  lev) const
inline

Query whether any turbulent perturbation mode is enabled on a level.

Parameters
levAMR level index.
Returns
True if source, direct, CPM, or CPM_W perturbations are enabled.
2421  {
2422  return pert_type[lev] == PerturbationType::Source ||
2423  pert_type[lev] == PerturbationType::Direct ||
2424  pert_type[lev] == PerturbationType::CPM ||
2425  pert_type[lev] == PerturbationType::CPM_W;
2426  }

◆ use_source_perturbation()

bool SolverChoice::use_source_perturbation ( int  lev) const
inline

Query whether source-term turbulent perturbations are enabled on a level.

Parameters
levAMR level index.
Returns
True if source perturbations are enabled.
2446  {
2447  return pert_type[lev] == PerturbationType::Source;
2448  }

Referenced by make_sources().

Here is the caller graph for this function:

◆ use_wvel_perturbation()

bool SolverChoice::use_wvel_perturbation ( int  lev) const
inline

Query whether vertical-velocity CPM perturbations are enabled on a level.

Parameters
levAMR level index.
Returns
True if CPM_W perturbations are enabled.
2456  {
2457  return pert_type[lev] == PerturbationType::CPM_W;
2458  }

◆ uses_shoc_family()

bool SolverChoice::uses_shoc_family ( ) const
inlinenoexcept

Query whether any SHOC-family PBL scheme is active.

Returns
True if native or EAMxx SHOC is active.
2465  {
2466  return (use_eamxx_shoc || use_native_shoc);
2467  }

Referenced by Kessler::Define(), Morrison::Define(), SAM::Define(), SatAdj::Define(), WDM6::Define(), WSM6::Define(), init_params(), and pbl_suppresses_microphysics_condensation().

Here is the caller graph for this function:

Member Data Documentation

◆ abl_driver_type

SolverChoice::abl_driver_type

Atmospheric boundary-layer driver type.

Referenced by build_coriolis_forcings_const_lat(), display(), and init_params().

◆ abl_geo_forcing

SolverChoice::abl_geo_forcing

Applied geostrophic-wind forcing vector.

Referenced by build_coriolis_forcings_const_lat(), display(), init_params(), and make_mom_sources().

◆ abl_geo_wind_table

SolverChoice::abl_geo_wind_table

Path to a time-varying geostrophic wind table.

Referenced by build_coriolis_forcings_const_lat(), and init_params().

◆ abl_pressure_grad

SolverChoice::abl_pressure_grad

Applied ABL pressure-gradient forcing vector.

Referenced by display(), erf_slow_rhs_pre(), and init_params().

◆ advChoice

SolverChoice::advChoice

Advection-related options.

Referenced by ERF::ComputeGhostCells(), display(), erf_slow_rhs_post(), erf_slow_rhs_pre(), and init_params().

◆ anelastic

SolverChoice::anelastic

◆ anelastic_type

SolverChoice::anelastic_type

Per-level two-stage scheme used by the anelastic integrator.

Referenced by display(), erf_slow_rhs_post(), erf_slow_rhs_pre(), and init_params().

◆ ave_plane

SolverChoice::ave_plane {2}

Averaging plane index used by diagnostics.

Referenced by SAM::Define(), WDM6::Define(), WSM6::Define(), init_params(), make_mom_sources(), and make_sources().

◆ avg_grid_faces_to_nodes

bool SolverChoice::avg_grid_faces_to_nodes {false}

Referenced by init_params().

◆ bdy_moist_nudge_type

SolverChoice::bdy_moist_nudge_type = 1

Moist-variable nudging strategy in boundary regions.

Referenced by init_params().

◆ bdy_nudge_factor

SolverChoice::bdy_nudge_factor = amrex::Real(10.0)

Boundary sponge nudging factor.

Referenced by init_params().

◆ bdy_rho_nudge_factor

amrex::Real SolverChoice::bdy_rho_nudge_factor = amrex::Real(-1.0)

Referenced by init_params().

◆ beta_s

SolverChoice::beta_s = amrex::Real(0.1)

Time off-centering coefficient for forward weighting.

Referenced by init_params().

◆ buildings_type

SolverChoice::buildings_type = BuildingsType::None
inlinestatic

Building representation.

Referenced by display(), init_params(), make_mom_sources(), and make_sources().

◆ buoyancy_type

SolverChoice::buoyancy_type

Per-level buoyancy formulation selector.

Referenced by check_params(), display(), init_params(), and make_buoyancy().

◆ c_p

SolverChoice::c_p = Cp_d

Specific heat at constant pressure for dry air [J/(kg-K)].

Referenced by Kessler::Define(), SAM::Define(), SatAdj::Define(), and init_params().

◆ coarse_bckgnd_data_file

SolverChoice::coarse_bckgnd_data_file

Coarse background data file used for ensemble initialization.

Referenced by init_params().

◆ compute_mean_vars

bool SolverChoice::compute_mean_vars = false

Referenced by init_params().

◆ const_massflux_layer_hi

SolverChoice::const_massflux_layer_hi = amrex::Real( bogus_large_value)

Upper height of the constant-mass-flux forcing layer.

Referenced by ERF::ERF_shared(), and init_params().

◆ const_massflux_layer_lo

SolverChoice::const_massflux_layer_lo = amrex::Real(-bogus_large_value)

Lower height of the constant-mass-flux forcing layer.

Referenced by ERF::ERF_shared(), and init_params().

◆ const_massflux_tau

SolverChoice::const_massflux_tau = one

Relaxation time scale for constant-mass-flux forcing.

Referenced by init_params(), and make_mom_sources().

◆ const_massflux_u

SolverChoice::const_massflux_u = zero

Target constant mass flux in the x direction.

Referenced by check_params(), ERF::ERF_shared(), init_params(), and make_mom_sources().

◆ const_massflux_v

SolverChoice::const_massflux_v = zero

Target constant mass flux in the y direction.

Referenced by check_params(), ERF::ERF_shared(), init_params(), and make_mom_sources().

◆ coriolis_3d

SolverChoice::coriolis_3d = true

Whether the three-dimensional Coriolis terms are included.

Referenced by build_coriolis_forcings_const_lat().

◆ coriolis_factor

SolverChoice::coriolis_factor = zero

Twice the planetary rotation rate used for Coriolis forcing.

Referenced by build_coriolis_forcings_const_lat(), init_params(), and make_mom_sources().

◆ cosphi

SolverChoice::cosphi = zero

Cosine of the latitude used for Coriolis forcing.

Referenced by build_coriolis_forcings_const_lat(), and make_mom_sources().

◆ coupling_type

SolverChoice::coupling_type

Multilevel coupling strategy.

Referenced by display(), erf_slow_rhs_post(), erf_slow_rhs_pre(), and init_params().

◆ custom_forcing_prim_vars

SolverChoice::custom_forcing_prim_vars = false

Whether custom forcing operates on primitive variables.

Referenced by init_params(), make_mom_sources(), and make_sources().

◆ custom_geostrophic_profile

SolverChoice::custom_geostrophic_profile = false

Whether a custom geostrophic wind profile is used.

Referenced by init_params().

◆ custom_moisture_forcing

SolverChoice::custom_moisture_forcing = false

Whether custom moisture forcing is enabled.

Referenced by init_params(), and make_sources().

◆ custom_rhotheta_forcing

SolverChoice::custom_rhotheta_forcing = false

Whether custom rho-theta forcing is enabled.

Referenced by init_params(), and make_sources().

◆ custom_w_subsidence

SolverChoice::custom_w_subsidence = false

Whether custom vertical subsidence is enabled.

Referenced by init_params(), make_mom_sources(), and make_sources().

◆ dampingChoice

SolverChoice::dampingChoice

Damping-related options.

Referenced by display(), init_params(), make_mom_sources(), and make_sources().

◆ diffChoice

◆ do_forest_drag

SolverChoice::do_forest_drag {false}

Whether forest canopy drag is enabled.

Referenced by make_mom_sources().

◆ do_mom_advection

SolverChoice::do_mom_advection = true

Whether custom vertical subsidence is applied to momentum.

Referenced by init_params(), and make_mom_sources().

◆ do_theta_advection

SolverChoice::do_theta_advection = true

Whether custom vertical subsidence is applied to rho-theta.

Referenced by init_params(), and make_sources().

◆ dz0

SolverChoice::dz0 = zero

Initial vertical grid spacing for stretched-grid setup.

Referenced by ERF::ERF_shared(), and init_params().

◆ ebChoice

SolverChoice::ebChoice

◆ ens_pert_amplitude

SolverChoice::ens_pert_amplitude = -1.0

Amplitude of ensemble initialization perturbations.

Referenced by init_params().

◆ ens_pert_correlated_radius

SolverChoice::ens_pert_correlated_radius = -1.0

Spatial correlation radius for ensemble perturbations.

Referenced by init_params().

◆ fixed_density

SolverChoice::fixed_density

Per-level flag selecting fixed-density treatment; always 1 at an anelastic level.

Referenced by display(), erf_slow_rhs_pre(), and init_params().

◆ flat_terrain

SolverChoice::flat_terrain = false
inlinestatic

Permit fixed-index planar averages after validating a flat fitted mesh.

Referenced by display(), init_params(), and make_mom_sources().

◆ force_stage1_single_substep

SolverChoice::force_stage1_single_substep = 1

Flag forcing a single substep in the first RK stage.

Referenced by init_params().

◆ forest_biophysics

bool SolverChoice::forest_biophysics {false}

Referenced by init_params().

◆ forest_biophysics_heat

bool SolverChoice::forest_biophysics_heat {false}

◆ forest_leaf_theta_fixed

amrex::Real SolverChoice::forest_leaf_theta_fixed {-one}

◆ forest_substep

SolverChoice::forest_substep = false

Whether canopy source terms are applied only during substeps.

Referenced by init_params(), and make_mom_sources().

◆ four_stream_radiation

SolverChoice::four_stream_radiation = false

Whether the four-stream radiation approximation is enabled.

Referenced by init_params(), and make_sources().

◆ gradp_type

SolverChoice::gradp_type = 0

Terrain-fitted horizontal pressure-gradient formulation.

Referenced by display(), init_params(), and make_gradp_pert().

◆ gravity

SolverChoice::gravity

Effective gravitational acceleration.

Referenced by ComputeTurbulentViscosity(), erf_slow_rhs_post(), init_params(), and make_buoyancy().

◆ grid_stretching_ratio

SolverChoice::grid_stretching_ratio = 0

Vertical grid stretching ratio.

Referenced by ERF::ERF_shared(), and init_params().

◆ have_geo_wind_profile

SolverChoice::have_geo_wind_profile {false}

Whether a geostrophic wind profile has been configured.

Referenced by init_params(), and make_mom_sources().

◆ hindcast_boundary_data_dir

SolverChoice::hindcast_boundary_data_dir

Directory containing hindcast lateral boundary data.

Referenced by init_params().

◆ hindcast_data_interval_in_hrs

SolverChoice::hindcast_data_interval_in_hrs = -one

Time interval between hindcast data files [hr].

Referenced by init_params().

◆ hindcast_lateral_forcing

SolverChoice::hindcast_lateral_forcing = false

Whether hindcast lateral forcing is enabled.

Referenced by init_params(), and make_mom_sources().

◆ hindcast_lateral_sponge_length

SolverChoice::hindcast_lateral_sponge_length = -one

Length of the hindcast lateral sponge layer.

Referenced by ApplyBndryForcing_Forecast(), and init_params().

◆ hindcast_lateral_sponge_strength

SolverChoice::hindcast_lateral_sponge_strength = -one

Strength of the hindcast lateral sponge layer.

Referenced by ApplyBndryForcing_Forecast(), and init_params().

◆ hindcast_surface_bcs

SolverChoice::hindcast_surface_bcs = false

Whether hindcast surface boundary conditions are enabled.

Referenced by init_params().

◆ hindcast_surface_data_dir

SolverChoice::hindcast_surface_data_dir

Directory containing hindcast surface boundary data.

Referenced by init_params().

◆ hindcast_zhi_sponge_damping

SolverChoice::hindcast_zhi_sponge_damping = false

Whether upper-boundary hindcast sponge damping is enabled.

Referenced by ApplyBndryForcing_Forecast(), and init_params().

◆ hindcast_zhi_sponge_length

SolverChoice::hindcast_zhi_sponge_length = -one

Length of the upper hindcast sponge layer.

Referenced by ApplyBndryForcing_Forecast(), and init_params().

◆ hindcast_zhi_sponge_strength

SolverChoice::hindcast_zhi_sponge_strength = -one

Strength of the upper hindcast sponge layer.

Referenced by ApplyBndryForcing_Forecast(), and init_params().

◆ hurricane_eye_latitude

SolverChoice::hurricane_eye_latitude = -1e10

Initial hurricane-eye latitude.

Referenced by ERF::HurricaneEyeTracker(), and init_params().

◆ hurricane_eye_longitude

SolverChoice::hurricane_eye_longitude = -1e10

Initial hurricane-eye longitude.

Referenced by ERF::HurricaneEyeTracker(), and init_params().

◆ if_Cd_momentum

◆ if_Cd_scalar

SolverChoice::if_Cd_scalar = amrex::Real(10.0)

Immersed-forcing drag coefficient for scalars.

Referenced by ImmersedForcingBuildings_Scalar(), ImmersedForcingTerrain_Scalar(), and init_params().

◆ if_damp_alpha

SolverChoice::if_damp_alpha = 0.5

◆ if_implicit_drag

◆ if_init_surf_temp

SolverChoice::if_init_surf_temp = zero

Initial immersed-forcing surface temperature [K].

Referenced by ImmersedForcingBuildings_Scalar(), ImmersedForcingTerrain_Scalar(), and init_params().

◆ if_Olen_in

◆ if_psi_cap_factor

SolverChoice::if_psi_cap_factor = amrex::Real(1.0)

Cap on psi_m in the immersed momentum wall law as a fraction of ln(z/z0) (1: none).

Referenced by ImmersedForcingBuildings_Xmom(), ImmersedForcingBuildings_Ymom(), ImmersedForcingBuildings_Zmom(), ImmersedForcingTerrain_Xmom(), ImmersedForcingTerrain_Ymom(), and init_params().

◆ if_snap_partial_cells

SolverChoice::if_snap_partial_cells = false

When true, the immersed forcing reads the blanking snapped to solid (1) or fluid (0) at half, so a building from a height map becomes the same staircase of whole cells an exact box is: the wall law (and the thermal conditions) sit on the boundary solid cells, roofs included, the drag on the interior cells, and nothing on the sliver cells of the reader's one-cell ramp (1-20 percent solid at the corners), on which the raw fractions make the wall law and the drag disagree and grow a vertical checkerboard over hours. The staircase puts full-strength forcing on every wall face, so the switch also selects the point-implicit drag form (if_implicit_drag), without which the explicit rate at rims and corners drives the density negative within seconds. The momentum kernels take the blanking of a face from the two cells it joins (solid if either is), so the staircase is the same with and without the face-centred blanking of the build; a face between a solid and a fluid cell is wall-normal and gets the interior drag toward zero (no penetration) whichever row it lies in, and a face between two solid cells the roof or wall law of its row (with the full log-law target; the partial-cell weight of the target is not applied) or the interior drag. Buildings only (erf.buildings_type = ImmersedForcing): the terrain kernels keep the raw fractions, whose wall law is weighted by the fluid fraction of the face. Default false, the raw fractions, for backward compatibility (on an exact box a boundary cell then carries the wall law and the interior drag together, and the roof only the drag); set it for height-map buildings.

Referenced by ImmersedForcingBuildings_Scalar(), ImmersedForcingBuildings_Xmom(), ImmersedForcingBuildings_Ymom(), ImmersedForcingBuildings_Zmom(), and init_params().

◆ if_stability_correction

SolverChoice::if_stability_correction = false

Whether immersed-forcing stability corrections are enabled.

Referenced by ImmersedForcingBuildings_Xmom(), ImmersedForcingBuildings_Ymom(), ImmersedForcingBuildings_Zmom(), and init_params().

◆ if_stability_wind_floor

SolverChoice::if_stability_wind_floor = amrex::Real(0.0)

◆ if_surf_heating_rate

SolverChoice::if_surf_heating_rate = zero

Immersed-forcing surface heating rate [K/hr].

Referenced by ImmersedForcingBuildings_Scalar(), ImmersedForcingTerrain_Scalar(), and init_params().

◆ if_surf_temp_flux

◆ if_use_most

◆ if_ws_floor

SolverChoice::if_ws_floor = 0.001

Wind-speed floor [m/s] in the per-step change limit of the building wall-law forcing.

Referenced by ImmersedForcingBuildings_Xmom(), ImmersedForcingBuildings_Ymom(), ImmersedForcingBuildings_Zmom(), and init_params().

◆ if_z0

◆ immersed_forcing_substep

SolverChoice::immersed_forcing_substep = false

Whether immersed-forcing source terms are applied only during substeps.

Referenced by ImmersedForcingBuildings_Xmom(), ImmersedForcingBuildings_Ymom(), ImmersedForcingBuildings_Zmom(), init_params(), make_mom_sources(), and make_sources().

◆ implicit_before_substep

SolverChoice::implicit_before_substep = true

Whether implicit diffusion is applied before acoustic substepping.

Referenced by init_params().

◆ implicit_ke_diffusion

SolverChoice::implicit_ke_diffusion = true

Whether implicit vertical TKE diffusion is included.

Referenced by display(), erf_slow_rhs_post(), and init_params().

◆ implicit_moisture_diffusion

SolverChoice::implicit_moisture_diffusion = true

Whether implicit vertical moisture diffusion is included.

Referenced by check_params(), display(), erf_slow_rhs_post(), and init_params().

◆ implicit_momentum_diffusion

SolverChoice::implicit_momentum_diffusion = true

Whether implicit vertical momentum diffusion is included.

Referenced by check_params(), display(), erf_make_tau_terms(), and init_params().

◆ implicit_terrain_metric

SolverChoice::implicit_terrain_metric = false

Whether the compact terrain-metric part of the vertical diffusion is solved implicitly.

Referenced by check_params(), DiffusionSrcForState_T(), display(), erf_make_tau_terms(), and init_params().

◆ implicit_thermal_diffusion

SolverChoice::implicit_thermal_diffusion = true

Whether implicit vertical thermal diffusion is included.

Referenced by check_params(), display(), erf_slow_rhs_pre(), and init_params().

◆ init_type

SolverChoice::init_type = InitType::None
inlinestatic

◆ interp_atmos_from_coarse

bool SolverChoice::interp_atmos_from_coarse {false}

Referenced by init_params().

◆ io_hurricane_eye_tracker

SolverChoice::io_hurricane_eye_tracker = false

Whether hurricane-eye tracking output is enabled.

Referenced by init_params().

◆ is_init_for_ensemble

SolverChoice::is_init_for_ensemble = false

Whether initialization is for an ensemble simulation.

Referenced by init_params().

◆ is_land

SolverChoice::is_land

Per-level land/water selector.

Referenced by init_params().

◆ large_scale_forcing

bool SolverChoice::large_scale_forcing = false

Referenced by init_params(), and make_mom_sources().

◆ lsf_file

std::string SolverChoice::lsf_file = ""

◆ lsf_timescale

amrex::Real SolverChoice::lsf_timescale = zero

◆ lsm_type

SolverChoice::lsm_type

Land-surface model.

Referenced by init_params(), rad_feeds_lsm(), and Radiation::Radiation().

◆ massflux_khi

SolverChoice::massflux_khi {0}

Upper vertical index for constant-mass-flux forcing.

Referenced by ERF::ERF_shared(), and make_mom_sources().

◆ massflux_klo

SolverChoice::massflux_klo {0}

Lower vertical index for constant-mass-flux forcing.

Referenced by ERF::ERF_shared(), and make_mom_sources().

◆ mean_vars_reset_mode

std::string SolverChoice::mean_vars_reset_mode = "plotfile"

Referenced by init_params().

◆ mean_vars_reset_time

amrex::Real SolverChoice::mean_vars_reset_time = -one

Referenced by init_params().

◆ mesh_type

◆ moisture_indices

◆ moisture_tight_coupling

SolverChoice::moisture_tight_coupling {false}

Whether moisture updates use tight coupling.

Referenced by init_params().

◆ moisture_type

◆ n_ensemble

SolverChoice::n_ensemble = -1

Number of ensemble members.

Referenced by init_params().

◆ ncorr

SolverChoice::ncorr = 1

Number of projection correction iterations.

Referenced by init_params().

◆ nudging_from_input_sounding

SolverChoice::nudging_from_input_sounding = false

Whether solution fields are nudged toward input sounding data.

Referenced by init_params(), and make_mom_sources().

◆ nudging_from_observations

SolverChoice::nudging_from_observations = false

Whether solution fields are nudged toward observations at stations.

Referenced by init_params().

◆ nudging_q

bool SolverChoice::nudging_q = true

Referenced by init_params().

◆ nudging_q_z1

amrex::Real SolverChoice::nudging_q_z1 = zero

Referenced by init_params().

◆ nudging_q_z2

amrex::Real SolverChoice::nudging_q_z2 = amrex::Real(10000.0)

Referenced by init_params().

◆ nudging_t

bool SolverChoice::nudging_t = true

Referenced by init_params().

◆ nudging_t_z1

amrex::Real SolverChoice::nudging_t_z1 = zero

Referenced by init_params().

◆ nudging_t_z2

amrex::Real SolverChoice::nudging_t_z2 = amrex::Real(10000.0)

Referenced by init_params().

◆ nudging_u

bool SolverChoice::nudging_u = true

Referenced by init_params(), and make_mom_sources().

◆ nudging_u_z1

amrex::Real SolverChoice::nudging_u_z1 = amrex::Real(-1.0e36)

Referenced by init_params(), and make_mom_sources().

◆ nudging_u_z2

amrex::Real SolverChoice::nudging_u_z2 = amrex::Real(1.0e36)

Referenced by init_params(), and make_mom_sources().

◆ num_diff_coeff

SolverChoice::num_diff_coeff {zero}

Numerical diffusion coefficient after input scaling.

Referenced by init_params(), make_mom_sources(), and make_sources().

◆ pert_type

SolverChoice::pert_type

◆ poisson_abstol

SolverChoice::poisson_abstol = amrex::Real(1e-8)

Absolute tolerance for the Poisson solve.

Referenced by init_params().

◆ poisson_reltol

SolverChoice::poisson_reltol = amrex::Real(1e-8)

Relative tolerance for the Poisson solve.

Referenced by init_params().

◆ project_initial_velocity

SolverChoice::project_initial_velocity

Per-level flag for projecting the initial velocity.

Referenced by init_params().

◆ rad_type

◆ radChoice

RadChoice SolverChoice::radChoice

Referenced by init_params().

◆ rdOcp

◆ rebalance_wrf_input

SolverChoice::rebalance_wrf_input = true

Whether to rebalance states from wrfinput and wrfbdy data.

Referenced by init_params().

◆ sampling_distance_by_D

SolverChoice::sampling_distance_by_D = -one

Turbine inflow sampling distance normalized by rotor diameter.

Referenced by check_params(), and init_params().

◆ sbm_cloud_rain_split

int SolverChoice::sbm_cloud_rain_split {-1}

Referenced by init_params().

◆ sbm_edges

amrex::Vector<amrex::Real> SolverChoice::sbm_edges

Referenced by init_params().

◆ sbm_fixture_initial_state

amrex::Vector<amrex::Real> SolverChoice::sbm_fixture_initial_state

Referenced by ERF::ERF_shared(), and init_params().

◆ sbm_moment_mode

int SolverChoice::sbm_moment_mode {1}

Referenced by init_params().

◆ sbm_nbins

int SolverChoice::sbm_nbins {4}

Referenced by init_params().

◆ sbm_pivots

amrex::Vector<amrex::Real> SolverChoice::sbm_pivots

Referenced by init_params().

◆ sbm_test_donor_cfl_fault

bool SolverChoice::sbm_test_donor_cfl_fault {false}

Referenced by erf_slow_rhs_post(), and init_params().

◆ sbm_test_native_qc_write_fault

bool SolverChoice::sbm_test_native_qc_write_fault {false}

Referenced by erf_slow_rhs_post(), and init_params().

◆ shoc_momentum_transport

◆ shoc_transport_mode

ShocTransportMode SolverChoice::shoc_transport_mode = ShocTransportMode::StateUpdate

◆ sinphi

SolverChoice::sinphi = zero

Sine of the latitude used for Coriolis forcing.

Referenced by build_coriolis_forcings_const_lat(), init_params(), and make_mom_sources().

◆ sounding_type

SolverChoice::sounding_type = SoundingType::Ideal
inlinestatic

Interpretation used for input sounding profiles.

Referenced by init_params().

◆ spatial_moisture_forcing

SolverChoice::spatial_moisture_forcing = false

Whether spatially varying moisture forcing is enabled.

Referenced by init_params(), and make_sources().

◆ spatial_rhotheta_forcing

SolverChoice::spatial_rhotheta_forcing = false

Whether spatially varying rho-theta forcing is enabled.

Referenced by init_params(), and make_sources().

◆ spongeChoice

SolverChoice::spongeChoice

Sponge-layer options.

Referenced by display(), init_params(), make_mom_sources(), and make_sources().

◆ substepping_diag

SolverChoice::substepping_diag = false

Whether to emit extra CFL diagnostics for compressible substepping.

Referenced by init_params().

◆ substepping_type

SolverChoice::substepping_type

Acoustic substepping type for each AMR level.

Referenced by display(), and init_params().

◆ terrain_type

◆ test_mapfactor

SolverChoice::test_mapfactor = false

Whether to use test map scale factors.

Referenced by init_params().

◆ time_avg_vel

SolverChoice::time_avg_vel = false

Whether time-averaged velocity fields are output.

Referenced by init_params().

◆ transport_scalar

SolverChoice::transport_scalar = true

Whether the passive scalar component is transported.

Referenced by erf_slow_rhs_post(), and init_params().

◆ turb_disk_angle

SolverChoice::turb_disk_angle = -one

Turbine disk angle from the x axis [deg].

Referenced by check_params(), and init_params().

◆ turbChoice

◆ urban_enabled_lev

amrex::Vector<int> SolverChoice::urban_enabled_lev

Referenced by init_params().

◆ urban_type

UrbanType SolverChoice::urban_type

Referenced by init_params().

◆ use_coriolis

SolverChoice::use_coriolis = false

Whether Coriolis forcing is enabled.

Referenced by display(), init_params(), and make_mom_sources().

◆ use_coupled_sst

bool SolverChoice::use_coupled_sst = false

◆ use_eamxx_shoc

SolverChoice::use_eamxx_shoc = false

Whether any level uses the EAMxx SHOC PBL scheme.

Referenced by host_owns_vertical_momentum_diffusion(), host_owns_vertical_scalar_diffusion(), init_params(), and uses_shoc_family().

◆ use_gravity

SolverChoice::use_gravity = false

Whether gravitational forcing is enabled.

Referenced by display(), and init_params().

◆ use_lagged_delta_rt

SolverChoice::use_lagged_delta_rt = true

Whether to use lagged delta terms for moving terrain.

Referenced by check_params(), and init_params().

◆ use_native_shoc

SolverChoice::use_native_shoc = false

Whether any level uses the native SHOC PBL scheme.

Referenced by host_owns_vertical_momentum_diffusion(), host_owns_vertical_scalar_diffusion(), init_params(), and uses_shoc_family().

◆ use_num_diff

SolverChoice::use_num_diff {false}

Whether sixth-order numerical diffusion is enabled.

Referenced by ERF::ComputeGhostCells(), init_params(), and make_sources().

◆ use_pert_pres_gradient

SolverChoice::use_pert_pres_gradient = true

Whether momentum equations use perturbational pressure gradients.

Referenced by init_params(), and make_gradp_pert().

◆ use_real_bcs

SolverChoice::use_real_bcs = false
inlinestatic

Whether real-data lateral boundary conditions are used.

Referenced by init_params().

◆ use_rotate_surface_flux

SolverChoice::use_rotate_surface_flux = false

Whether MOST surface fluxes are rotated with terrain.

Referenced by erf_slow_rhs_post(), erf_slow_rhs_pre(), and init_params().

◆ use_wrf_bdy_density

bool SolverChoice::use_wrf_bdy_density = true

Referenced by init_params().

◆ use_wrf_bdy_qc_qi

SolverChoice::use_wrf_bdy_qc_qi = false

Whether WRF cloud water and active cloud ice are ingested at real boundaries.

Referenced by init_params().

◆ variable_coriolis

SolverChoice::variable_coriolis {false}

Whether spatially varying Coriolis forcing is enabled.

Referenced by init_params(), and make_mom_sources().

◆ vert_implicit_fac

SolverChoice::vert_implicit_fac

Per-level, per-stage implicit vertical diffusion factors.

Referenced by check_params(), display(), erf_make_tau_terms(), erf_slow_rhs_post(), erf_slow_rhs_pre(), and init_params().

◆ wall_dist_type

std::string SolverChoice::wall_dist_type = "poisson"

Referenced by init_params().

◆ windfarm_airfoil_tables

SolverChoice::windfarm_airfoil_tables

Wind-farm airfoil table paths.

Referenced by init_params().

◆ windfarm_blade_table

SolverChoice::windfarm_blade_table

Wind-farm blade table path.

Referenced by init_params().

◆ windfarm_loc_table

SolverChoice::windfarm_loc_table

Wind-farm location table path.

Referenced by init_params().

◆ windfarm_loc_type

SolverChoice::windfarm_loc_type

Coordinate system for wind-farm turbine locations.

Referenced by check_params(), and init_params().

◆ windfarm_spec_table

SolverChoice::windfarm_spec_table

Wind-farm turbine specification table path.

Referenced by init_params().

◆ windfarm_spec_table_extra

SolverChoice::windfarm_spec_table_extra

Additional wind-farm turbine specification table path.

Referenced by init_params().

◆ windfarm_type

SolverChoice::windfarm_type

Wind-farm model.

Referenced by check_params(), and init_params().

◆ windfarm_x_shift

SolverChoice::windfarm_x_shift = -one

Wind-farm x-coordinate shift.

Referenced by check_params(), and init_params().

◆ windfarm_y_shift

SolverChoice::windfarm_y_shift = -one

Wind-farm y-coordinate shift.

Referenced by check_params(), and init_params().

◆ wrfinput_zlevels_from_file

bool SolverChoice::wrfinput_zlevels_from_file {true}

Referenced by init_params().

◆ zsurf

SolverChoice::zsurf = zero

Nominal surface height for stretched-grid setup.

Referenced by ERF::ERF_shared(), and init_params().


The documentation for this struct was generated from the following file: