1 #ifndef ERF_TWO_STREAM_COLUMN_H_
2 #define ERF_TWO_STREAM_COLUMN_H_
8 #include <AMReX_Array4.H>
10 #include <AMReX_Geometry.H>
11 #include <AMReX_GpuControl.H>
12 #include <AMReX_Math.H>
13 #include <AMReX_REAL.H>
121 static_assert(std::is_trivially_copyable<TwoStreamParams>::value,
122 "TwoStreamParams must stay trivially copyable so it can be captured by device lambdas");
199 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
204 if (!(
rho > 0.0) || !amrex::Math::isfinite(
rho) ||
205 !(rho_theta > 0.0) || !amrex::Math::isfinite(rho_theta)) {
208 if (!(
qv >= 0.0) || !amrex::Math::isfinite(
qv)) {
213 if (!amrex::Math::isfinite(
T) ||
T <= 0.0) {
224 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
227 return amrex::Math::isfinite(value) && value > 0.0 && value <
lsm_undefined;
244 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
247 const amrex::Array4<const amrex::Real>* hetero_alb_sw,
253 if (has_hetero_alb && hetero_alb_sw !=
nullptr && hetero_alb_sw->contains(i, j, 0)) {
254 amrex::Real hetero_val = (*hetero_alb_sw)(i, j, 0, 0);
255 if (amrex::Math::isfinite(hetero_val) && hetero_val >= 0.0 && hetero_val <= 1.0) {
277 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
280 const amrex::Array4<const amrex::Real>* hetero_emiss_lw,
282 bool has_hetero_emiss)
286 if (has_hetero_emiss && hetero_emiss_lw !=
nullptr && hetero_emiss_lw->contains(i, j, 0)) {
287 amrex::Real hetero_val = (*hetero_emiss_lw)(i, j, 0, 0);
288 if (amrex::Math::isfinite(hetero_val) && hetero_val >= 0.0 && hetero_val <= 1.0) {
323 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
326 const amrex::Array4<const amrex::Real>* lsm_t_sfc,
328 const amrex::Array4<const amrex::Real>* seb_t_sfc,
330 const amrex::Array4<const amrex::Real>* surface_layer_theta,
331 bool has_surface_layer,
333 bool& from_surface_layer)
336 from_surface_layer =
false;
338 if (has_lsm_t_sfc && lsm_t_sfc !=
nullptr && lsm_t_sfc->contains(i, j, 0)) {
339 const amrex::Real lsm_value = (*lsm_t_sfc)(i, j, 0, 0);
345 if (has_seb_t_sfc && seb_t_sfc !=
nullptr && seb_t_sfc->contains(i, j, 0)) {
346 const amrex::Real seb_value = (*seb_t_sfc)(i, j, 0, 0);
352 if (has_surface_layer && surface_layer_theta !=
nullptr &&
353 surface_layer_theta->contains(i, j, 0)) {
356 from_surface_layer =
true;
372 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
385 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
387 const amrex::Array4<const amrex::Real>& state_arr)
389 if (state_arr.nComp() <=
RhoQ1_comp)
return 0.0;
392 if (!(
rho > 0.0) || !amrex::Math::isfinite(
rho) || !amrex::Math::isfinite(rho_qv))
return 0.0;
394 return (amrex::Math::isfinite(
qv) &&
qv > 0.0) ?
qv : 0.0;
404 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
406 const amrex::Array4<const amrex::Real>& state_arr)
409 if (!(rho_theta > 0.0) || !amrex::Math::isfinite(rho_theta))
return 1.0;
412 return (amrex::Math::isfinite(
pi) &&
pi > 0.0) ? 1.0 /
pi : 1.0;
421 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
423 const amrex::Array4<const amrex::Real>& state_arr)
425 if (state_arr.nComp() <=
RhoQ2_comp)
return 0.0;
428 if (!(
rho > 0.0) || !amrex::Math::isfinite(
rho) || !amrex::Math::isfinite(rho_qc))
return 0.0;
430 return (amrex::Math::isfinite(
qc) &&
qc > 0.0) ?
qc : 0.0;
449 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
453 if (!(
qv > 0.0) || !amrex::Math::isfinite(
qv))
qv = 0.0;
454 if (!(
qc > 0.0) || !amrex::Math::isfinite(
qc))
qc = 0.0;
456 if (!amrex::Math::isfinite(tau))
return tau_base;
457 if (tau < 0.0) tau = 0.0;
458 if (tau > 100.0) tau = 100.0;
479 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
484 if (!apply_cloud || rad_choice.
tau_profile_type != TauProfileType::CloudLayer) {
514 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
519 bool use_cloud_props = apply_cloud &&
523 if (use_cloud_props) {
550 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
553 const amrex::Array4<const amrex::Real>& state_arr,
568 if (
rho <= 0.0 || !amrex::Math::isfinite(
rho))
rho = 1.0;
569 if (rho_theta <= 0.0 || !amrex::Math::isfinite(rho_theta)) rho_theta = 288.15;
574 if (
P <= 0.0 || !amrex::Math::isfinite(
P))
P =
p_0;
599 constexpr
int DZ = 0;
644 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
648 const amrex::Array4<const amrex::Real>& state_arr,
660 if (!(
rho > 0.0) || !amrex::Math::isfinite(
rho))
rho = 0.0;
666 if (!amrex::Math::isfinite(base) || base < 0.0) base = 0.0;
675 if (dynamic_enabled) {
746 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
750 const amrex::Array4<const amrex::Real>& state_arr,
757 if (!is_sw || rad_choice.
tau_model != TauModel::Mass) {
758 tau =
diagnose_layer_tau(i, j, k, dz_layer, z_center, state_arr, tau_base, is_sw, cloudy, rad_choice);
767 if (!(
rho > 0.0) || !amrex::Math::isfinite(
rho))
rho = 0.0;
777 amrex::Real ext = tau_dry_abs + tau_rayleigh + tau_vapor + tau_cloud;
798 0.0,
true, cloudy, rad_choice) - band;
799 if (additions > 0.0) ext += additions;
801 if (!amrex::Math::isfinite(ext) || ext <= 0.0) {
809 g = (sca > 0.0) ? gsca / sca : 0.0;
810 if (
g > 1.0)
g = 1.0;
811 if (
g < -1.0)
g = -1.0;
885 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
888 const amrex::Box& bx,
890 const amrex::Array4<const amrex::Real>& state_arr,
893 const amrex::Array4<amrex::Real>& qheating_arr,
900 const amrex::Array4<const amrex::Real>& z_phys_nd,
901 const amrex::Array4<amrex::Real>& scratch,
902 bool has_hetero_alb_sw =
false,
903 const amrex::Array4<const amrex::Real>* hetero_alb_sw =
nullptr,
904 bool has_hetero_emiss_lw =
false,
905 const amrex::Array4<const amrex::Real>* hetero_emiss_lw =
nullptr,
906 bool has_lsm_t_sfc =
false,
907 const amrex::Array4<const amrex::Real>* lsm_t_sfc =
nullptr,
908 bool has_seb_t_sfc =
false,
909 const amrex::Array4<const amrex::Real>* seb_t_sfc =
nullptr,
910 bool has_surface_layer =
false,
911 const amrex::Array4<const amrex::Real>* surface_layer_theta =
nullptr,
912 bool has_latlon =
false,
913 const amrex::Array4<const amrex::Real>* lat_arr =
nullptr,
914 const amrex::Array4<const amrex::Real>* lon_arr =
nullptr,
915 const amrex::Array4<amrex::Real>* rad_flux_out =
nullptr)
918 const int kmin = bx.smallEnd(2);
919 const int kmax = bx.bigEnd(2);
920 const int nlev = kmax - kmin + 1;
924 AMREX_ASSERT(scratch.contains(i, j, kmin) && scratch.contains(i, j, kmax + 1));
925 AMREX_ASSERT(rad_flux_out ==
nullptr ||
926 (rad_flux_out->contains(i, j, kmin) && rad_flux_out->contains(i, j, kmax + 1)));
957 return 0.25 * (z_phys_nd(i, j, k) + z_phys_nd(i + 1, j, k) +
958 z_phys_nd(i, j + 1, k) + z_phys_nd(i + 1, j + 1, k));
961 for (
int m = 0; m < nlev; ++m) {
965 dz_level(m) = (dz_computed > 0.0 && amrex::Math::isfinite(dz_computed)) ? dz_computed : dz_uniform;
966 z_level(m) = 0.5 * (z_lo + z_hi) - z_surface;
969 for (
int m = 0; m < nlev; ++m) {
970 dz_level(m) = dz_uniform;
971 z_level(m) = (
static_cast<amrex::Real>(m) + 0.5) * dz_uniform;
983 const amrex::Real lat_rad = (has_latlon && lat_arr !=
nullptr && lat_arr->contains(i, j, 0))
985 const amrex::Real lon_rad = (has_latlon && lon_arr !=
nullptr && lon_arr->contains(i, j, 0))
1004 for (
int k = kmin; k <= kmax; ++k) {
1005 qheating_arr(i, j, k, 0) = 0.0;
1006 qheating_arr(i, j, k, 1) = 0.0;
1008 if (rad_flux_out !=
nullptr) {
1009 for (
int k = kmin; k <= kmax + 1; ++k) {
1010 for (
int comp = 0; comp < 4; ++comp) { (*rad_flux_out)(i, j, k, comp) = 0.0; }
1013 sw_down_toa = (rad_choice.
sw_enabled && cos_zenith > 0.0) ? S0 * cos_zenith : 0.0;
1040 F_dir(nlev) = S0 * cos_zenith;
1041 for (
int k = kmax; k >= kmin; --k) {
1042 const int m = k - kmin;
1045 true, cloudy, rad_choice, tau_sw_level(m), omega_m, g_m);
1046 tau_sw_cum += tau_sw_level(m);
1051 auto layer_props = [&](
int m) {
1054 true, cloudy, rad_choice, tau_m,
omega,
g);
1060 S(0) = alb_dir * F_dir(0);
1061 for (
int m = 0; m < nlev; ++m) {
1064 if (denom < 1.0e-12) denom = 1.0e-12;
1066 S(m + 1) = L.
R_dir * F_dir(m + 1)
1067 + L.
T_dif * (
S(m) +
A(m) * L.
T_dir * F_dir(m + 1)) / denom;
1073 sw_up_at_toa = u_above;
1074 amrex::Real F_net_above = F_dir(nlev) + d_above - u_above;
1075 if (rad_flux_out !=
nullptr) {
1076 (*rad_flux_out)(i, j, kmax + 1, 0) = u_above;
1077 (*rad_flux_out)(i, j, kmax + 1, 1) = F_dir(nlev);
1079 for (
int k = kmax; k >= kmin; --k) {
1080 const int m = k - kmin;
1083 if (denom < 1.0e-12) denom = 1.0e-12;
1088 if (rad_flux_out !=
nullptr) {
1089 (*rad_flux_out)(i, j, k, 0) = u_m;
1090 (*rad_flux_out)(i, j, k, 1) = F_dir(m) + d_m;
1094 if (
rho <= 0.0 || !amrex::Math::isfinite(
rho))
rho = 1.0;
1099 dz_level(m),
rho, cp_air)
1101 qheating_arr(i, j, k, 0) = Q_sw;
1102 local_max_heating = std::max(local_max_heating, std::abs(Q_sw));
1105 F_net_above = F_net_m;
1107 sw_surface_absorbed = (1.0 - alb_dir) * F_dir(0) + (1.0 - alb_dif) * d_m;
1120 F_lw_down_iface(nlev) = 0.0;
1121 for (
int k = kmax; k >= kmin; --k) {
1122 const int m = k - kmin;
1126 if (
rho <= 0.0 || !amrex::Math::isfinite(
rho))
rho = 1.0;
1127 if (rho_theta <= 0.0 || !amrex::Math::isfinite(rho_theta)) rho_theta = 288.15;
1132 state_arr, tau_lw_base,
false, cloudy,
1142 bool t_sfc_from_surface_layer =
false;
1144 i, j, lsm_t_sfc, has_lsm_t_sfc, seb_t_sfc, has_seb_t_sfc,
1145 surface_layer_theta, has_surface_layer, rad_choice,
1146 t_sfc_from_surface_layer);
1151 if (t_sfc_from_surface_layer) {
1157 rho, rho_theta,
qv, delta_z);
1159 t_surface, pressure, rad_choice.
rdOcp, t_surface)) {
1165 + (1.0 - emiss_lw) * F_lw_down_iface(0);
1167 for (
int k = kmin; k <= kmax; ++k) {
1168 const int m = k - kmin;
1172 if (
rho <= 0.0 || !amrex::Math::isfinite(
rho))
rho = 1.0;
1173 if (rho_theta <= 0.0 || !amrex::Math::isfinite(rho_theta)) rho_theta = 288.15;
1182 for (
int k = kmin; k <= kmax; ++k) {
1183 const int m = k - kmin;
1185 if (
rho <= 0.0 || !amrex::Math::isfinite(
rho))
rho = 1.0;
1186 if (rad_flux_out !=
nullptr) {
1187 (*rad_flux_out)(i, j, k, 2) = F_lw_up_iface(m);
1188 (*rad_flux_out)(i, j, k, 3) = F_lw_down_iface(m);
1190 (*rad_flux_out)(i, j, kmax + 1, 2) = F_lw_up_iface(nlev);
1191 (*rad_flux_out)(i, j, kmax + 1, 3) = F_lw_down_iface(nlev);
1195 amrex::Real F_net_top = F_lw_up_iface(m + 1) - F_lw_down_iface(m + 1);
1196 amrex::Real F_net_bot = F_lw_up_iface(m) - F_lw_down_iface(m);
1201 qheating_arr(i, j, k, 1) = Q_lw;
1204 local_max_heating = std::max(local_max_heating, std::abs(Q_sw_here) + std::abs(Q_lw));
1213 sw_surface_flux = sw_surface_absorbed;
1214 sw_up_toa = sw_up_at_toa;
1216 sw_surface_flux = 0.0;
1223 lw_up_toa = F_lw_up_iface(nlev);
1224 lw_net_surface = F_lw_up_sfc - F_lw_down_sfc;
1226 lw_net_surface = 0.0;
1230 max_heating_rate = local_max_heating;
if(l_use_mynn &&start_comp<=RhoKE_comp &&end_comp >=RhoKE_comp)
Definition: ERF_AddQKESources.H:2
Prescribed bulk aerosol/turbidity optical depth diagnosis.
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real diagnose_tau_aerosol_constant(amrex::Real tau_aerosol_const)
Diagnose aerosol optical depth for Constant profile.
Definition: ERF_AerosolOpticalDepth.H:42
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real diagnose_tau_aerosol_exponential(amrex::Real z_level, amrex::Real dz, amrex::Real tau_surface, amrex::Real scale_height_m)
Diagnose aerosol optical depth for Exponential profile.
Definition: ERF_AerosolOpticalDepth.H:77
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real diagnose_tau_aerosol_table(int k)
Diagnose aerosol optical depth for the Table profile.
Definition: ERF_AerosolOpticalDepth.H:123
constexpr amrex::Real Cp_d
Definition: ERF_Constants.H:36
constexpr amrex::Real p_0
Definition: ERF_Constants.H:53
constexpr amrex::Real lsm_undefined
Definition: ERF_Constants.H:26
constexpr amrex::Real RdoCp
Definition: ERF_Constants.H:41
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getTgivenRandRTh(const amrex::Real rho, const amrex::Real rhotheta, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:46
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getExnergivenRTh(const amrex::Real rhotheta, const amrex::Real rdOcp, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:156
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:81
#define Rho_comp
Definition: ERF_IndexDefines.H:39
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:40
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:46
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:45
const Real rdOcp
Definition: ERF_InitCustomPert_ABL.H:72
amrex::Real sigma
Definition: ERF_InitCustomPert_DataAssimilation_ISV.H:11
constexpr amrex::Real PI
Definition: ERF_NumericalConstants.H:39
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE double orbital_cos_zenith_instant(double jday, double lat, double lon, double declin)
Definition: ERF_OrbCosZenith.H:507
Prognostic cloud fraction diagnosis from relative humidity and cloud water.
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_relative_humidity(amrex::Real qv, amrex::Real T, amrex::Real P)
Compute relative humidity from water vapor mixing ratio.
Definition: ERF_PrognosticCloudFraction.H:36
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real diagnose_cloud_fraction_from_rh_qc(amrex::Real rh, amrex::Real qc, amrex::Real rh_min, amrex::Real rh_max, amrex::Real qc_scale)
Diagnose cloud fraction from relative humidity and cloud water.
Definition: ERF_PrognosticCloudFraction.H:98
Radiation model type and control parameters.
amrex::Real Real
Definition: ERF_ShocInterface.H:19
TwoStreamParams make_two_stream_params(const RadChoice &rc, const amrex::Real rdOcp)
Copy the column-kernel parameters out of a RadChoice.
Definition: ERF_TwoStreamColumn.H:127
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real get_inverse_exner(int i, int j, int k, const amrex::Array4< const amrex::Real > &state_arr)
Inverse Exner function 1/pi at (i,j,k) from the state, with pi = (p / p_0)^(R_d/c_p) evaluated by get...
Definition: ERF_TwoStreamColumn.H:405
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real resolve_surface_albedo_sw(int i, int j, const amrex::Array4< const amrex::Real > *hetero_alb_sw, const TwoStreamParams &rad_choice, bool has_hetero_alb)
Resolve per-column shortwave surface albedo from hetero field or fallback.
Definition: ERF_TwoStreamColumn.H:245
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real diagnose_cloud_fraction_prognostic(int i, int j, int k, const amrex::Array4< const amrex::Real > &state_arr, const TwoStreamParams &rad_choice)
GPU-safe helper to diagnose prognostic cloud fraction from per-level relative humidity and cloud liqu...
Definition: ERF_TwoStreamColumn.H:551
amrex::Box two_stream_scratch_box(const amrex::Box &bx)
Box of the scratch FArrayBox a sweep over box bx needs.
Definition: ERF_TwoStreamColumn.H:612
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real get_qv_from_state(int i, int j, int k, const amrex::Array4< const amrex::Real > &state_arr)
Water-vapor mixing ratio qv = RhoQv / Rho at (i,j,k).
Definition: ERF_TwoStreamColumn.H:386
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void diagnose_layer_optics(int i, int j, int k, amrex::Real dz_layer, amrex::Real z_center, const amrex::Array4< const amrex::Real > &state_arr, amrex::Real tau_base, bool is_sw, bool cloudy, const TwoStreamParams &rad_choice, amrex::Real &tau, amrex::Real &omega, amrex::Real &g)
Optical depth, single-scattering albedo and asymmetry factor of layer k for one band,...
Definition: ERF_TwoStreamColumn.H:747
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real tau_layer_value(amrex::Real z_center, amrex::Real tau_base, const TwoStreamParams &rad_choice, bool apply_cloud)
GPU-safe helper to compute the per-layer optical depth at level k, given the base (clear-sky) optical...
Definition: ERF_TwoStreamColumn.H:480
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real get_qc_from_state(int i, int j, int k, const amrex::Array4< const amrex::Real > &state_arr)
Cloud-water mixing ratio qc = RhoQc / Rho at (i,j,k).
Definition: ERF_TwoStreamColumn.H:422
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void vertical_two_stream_sweep(int i, int j, const amrex::Box &bx, amrex::Real dz_uniform, const amrex::Array4< const amrex::Real > &state_arr, const TwoStreamParams &rad_choice, bool cloudy, const amrex::Array4< amrex::Real > &qheating_arr, amrex::Real &max_heating_rate, amrex::Real &sw_surface_flux, amrex::Real &sw_up_toa, amrex::Real &lw_net_surface, amrex::Real &lw_up_toa, amrex::Real &sw_down_toa, const amrex::Array4< const amrex::Real > &z_phys_nd, const amrex::Array4< amrex::Real > &scratch, bool has_hetero_alb_sw=false, const amrex::Array4< const amrex::Real > *hetero_alb_sw=nullptr, bool has_hetero_emiss_lw=false, const amrex::Array4< const amrex::Real > *hetero_emiss_lw=nullptr, bool has_lsm_t_sfc=false, const amrex::Array4< const amrex::Real > *lsm_t_sfc=nullptr, bool has_seb_t_sfc=false, const amrex::Array4< const amrex::Real > *seb_t_sfc=nullptr, bool has_surface_layer=false, const amrex::Array4< const amrex::Real > *surface_layer_theta=nullptr, bool has_latlon=false, const amrex::Array4< const amrex::Real > *lat_arr=nullptr, const amrex::Array4< const amrex::Real > *lon_arr=nullptr, const amrex::Array4< amrex::Real > *rad_flux_out=nullptr)
GPU-safe per-column vertical integration kernel for two-stream radiation, computing either the clear-...
Definition: ERF_TwoStreamColumn.H:886
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real diagnose_tau_dynamic(amrex::Real tau_base, amrex::Real qv, amrex::Real qc, amrex::Real coeff_qv, amrex::Real coeff_qc)
Moisture-dependent (dynamic) per-layer optical depth.
Definition: ERF_TwoStreamColumn.H:450
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool is_cloud_level(amrex::Real z_center, const TwoStreamParams &rad_choice)
GPU-safe helper to determine whether a layer falls within the cloud band [cloud_base_height_m,...
Definition: ERF_TwoStreamColumn.H:373
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool valid_surface_temperature(amrex::Real value)
Check whether a heterogeneous absolute surface temperature is valid.
Definition: ERF_TwoStreamColumn.H:225
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real get_temperature_from_rhotheta(amrex::Real rho_theta, amrex::Real rho, amrex::Real qv=0.0)
GPU-safe helper to compute absolute temperature from (rho, rho*theta).
Definition: ERF_TwoStreamColumn.H:200
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void select_scattering_props(amrex::Real z_center, const TwoStreamParams &rad_choice, bool apply_cloud, amrex::Real &omega, amrex::Real &g)
GPU-safe helper to select the single-scattering albedo and asymmetry factor to use for level k's diff...
Definition: ERF_TwoStreamColumn.H:515
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real resolve_surface_emissivity_lw(int i, int j, const amrex::Array4< const amrex::Real > *hetero_emiss_lw, const TwoStreamParams &rad_choice, bool has_hetero_emiss)
Resolve per-column longwave surface emissivity from hetero field or fallback.
Definition: ERF_TwoStreamColumn.H:278
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real diagnose_layer_tau(int i, int j, int k, amrex::Real dz_layer, amrex::Real z_center, const amrex::Array4< const amrex::Real > &state_arr, amrex::Real tau_base, bool is_sw, bool cloudy, const TwoStreamParams &rad_choice)
GPU-safe helper to assemble the total per-layer optical depth at level k for either the SW or the LW ...
Definition: ERF_TwoStreamColumn.H:645
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real resolve_surface_temp_k(int i, int j, const amrex::Array4< const amrex::Real > *lsm_t_sfc, bool has_lsm_t_sfc, const amrex::Array4< const amrex::Real > *seb_t_sfc, bool has_seb_t_sfc, const amrex::Array4< const amrex::Real > *surface_layer_theta, bool has_surface_layer, const TwoStreamParams &rad_choice, bool &from_surface_layer)
Resolve the per-column surface-temperature boundary condition.
Definition: ERF_TwoStreamColumn.H:324
Longwave (thermal) radiation using gray-gas two-stream model.
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_lw_flux_down(amrex::Real F_down_above, amrex::Real T_layer, amrex::Real sigma, amrex::Real tau_lw)
Compute downwelling LW flux in one layer of a two-stream sweep.
Definition: ERF_TwoStreamLW.H:188
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_thermal_intensity(amrex::Real T, amrex::Real sigma)
Compute thermal (LW) intensity for a given temperature.
Definition: ERF_TwoStreamLW.H:93
constexpr amrex::Real stefan_boltzmann
Stefan-Boltzmann constant [W/(m^2 K^4)] used by the two-stream LW model.
Definition: ERF_TwoStreamLW.H:11
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_lw_heating_rate(amrex::Real F_net_top, amrex::Real F_net_bot, amrex::Real dz, amrex::Real rho, amrex::Real cp)
Compute LW heating rate from net flux divergence.
Definition: ERF_TwoStreamLW.H:236
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_lw_flux_up(amrex::Real F_up_below, amrex::Real T_layer, amrex::Real sigma, amrex::Real tau_lw)
Compute upwelling LW flux in one layer of a two-stream sweep.
Definition: ERF_TwoStreamLW.H:156
Shortwave (solar) radiation kernels: Beer-Lambert direct beam and the two-stream layer solution for t...
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_sw_direct_flux(amrex::Real tau_cumulative, amrex::Real S0, amrex::Real cos_zenith)
Compute Beer-Lambert direct-beam flux at a given optical depth.
Definition: ERF_TwoStreamSW.H:72
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real compute_sw_heating_rate(amrex::Real flux_top, amrex::Real flux_bot, amrex::Real dz, amrex::Real rho, amrex::Real cp)
Compute the shortwave heating rate of a layer from the net (downward positive) flux at its top and bo...
Definition: ERF_TwoStreamSW.H:101
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE TwoStreamLayerSW compute_sw_layer_two_stream(amrex::Real tau, amrex::Real omega, amrex::Real g, amrex::Real cos_zenith)
Compute the two-stream layer solution for shortwave radiation.
Definition: ERF_TwoStreamSW.H:176
@ theta
Definition: ERF_SLM.H:19
@ P
Definition: ERF_IndexDefines.H:204
@ rho
Definition: ERF_Kessler.H:25
@ qv
Definition: ERF_Kessler.H:31
@ omega
Definition: ERF_Morrison.H:55
@ qc
Definition: ERF_SatAdj.H:42
@ T
Definition: ERF_IndexDefines.H:128
Per-column scratch the sweep keeps in a caller-provided Array4.
Definition: ERF_TwoStreamColumn.H:598
constexpr int F_DIR
Definition: ERF_TwoStreamColumn.H:602
constexpr int A
Definition: ERF_TwoStreamColumn.H:603
constexpr int Z
Definition: ERF_TwoStreamColumn.H:600
constexpr int NCOMP
Definition: ERF_TwoStreamColumn.H:608
constexpr int TAU_LW
Definition: ERF_TwoStreamColumn.H:607
constexpr int LW_UP
Definition: ERF_TwoStreamColumn.H:605
constexpr int LW_DN
Definition: ERF_TwoStreamColumn.H:606
constexpr int S
Definition: ERF_TwoStreamColumn.H:604
constexpr int DZ
Definition: ERF_TwoStreamColumn.H:599
constexpr int TAU_SW
Definition: ERF_TwoStreamColumn.H:601
@ p
Definition: ERF_WSM6.H:280
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pressure_at_surface(const amrex::Real rho, const amrex::Real rho_theta, const amrex::Real qv, const amrex::Real delta_z)
Definition: ERF_SurfaceTemperature.H:30
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool theta_to_temperature(const amrex::Real theta, const amrex::Real pressure, const amrex::Real rdOcp, amrex::Real &temperature)
Definition: ERF_SurfaceTemperature.H:54
real(c_double), parameter g
Definition: ERF_module_model_constants.F90:19
real(c_double), parameter, private pi
Definition: ERF_module_mp_morr_two_moment.F90:100
Container holding radiation-related choices and parameters.
Definition: ERF_RadStruct.H:70
amrex::Real lw_kabs_dry
Dry-air gray LW mass absorption coefficient [m^2/kg].
Definition: ERF_RadStruct.H:188
bool aerosol_enable
Enable prescribed bulk aerosol/turbidity optical depth. When true, aerosol optical depth is added on ...
Definition: ERF_RadStruct.H:577
TauModel tau_model
Optical depth model: "per_layer" (default, fixed tau per layer) or "mass" (from the layer mass path i...
Definition: ERF_RadStruct.H:155
amrex::Real sw_kabs_vapor
Mass model, SW: water-vapor gray absorption coefficient [m^2/kg].
Definition: ERF_RadStruct.H:164
amrex::Real cloud_top_height_m
Cloud layer top height [m]. Only used when tau_profile_type == CloudLayer. Must be >= cloud_base_heig...
Definition: ERF_RadStruct.H:276
amrex::Real aerosol_tau_surface
Total-column aerosol optical depth at surface [dimensionless]. Used for AerosolProfileType::Exponenti...
Definition: ERF_RadStruct.H:609
amrex::Real fixed_solar_zenith_angle
erf.fixed_solar_zenith_angle: the COSINE of the solar zenith angle (mu0), as RRTMGP takes it,...
Definition: ERF_RadStruct.H:120
bool sw_enabled
Enable shortwave (solar) radiation computation. Only used by the two-stream model.
Definition: ERF_RadStruct.H:82
amrex::Real cloud_asymmetry_factor
Cloud scattering asymmetry factor in [-1, 1], used instead of asymmetry_factor for levels where the c...
Definition: ERF_RadStruct.H:331
amrex::Real tau_lw_per_layer
Longwave optical depth per layer (constant for all layers). Used in gray-gas LW two-stream solver....
Definition: ERF_RadStruct.H:102
amrex::Real surface_albedo_sw
Shortwave surface albedo fallback [0, 1] for per-column heterogeneous-surface-property resolution....
Definition: ERF_RadStruct.H:340
amrex::Real surface_emissivity_lw
Longwave surface emissivity fallback [0, 1] for per-column heterogeneous-surface-property resolution....
Definition: ERF_RadStruct.H:355
amrex::Real sw_kext_cloud
Mass model, SW: cloud-water extinction coefficient m^2/kg.
Definition: ERF_RadStruct.H:167
amrex::Real tau_sw_coeff_qv
Shortwave optical depth coefficient for water vapor [dimensionless]. Dynamic SW tau = tau_sw_coeff_qv...
Definition: ERF_RadStruct.H:513
amrex::Real fixed_total_solar_irradiance
erf.fixed_total_solar_irradiance: top-of-atmosphere irradiance [W/m^2] when >= 0. Otherwise (default)...
Definition: ERF_RadStruct.H:127
bool tau_lw_dynamic_enable
Enable dynamic longwave optical depth diagnosis from moisture/clouds. When true, LW optical depth is ...
Definition: ERF_RadStruct.H:504
amrex::Real tau_sw_coeff_qc
Shortwave optical depth coefficient for cloud liquid water [dimensionless]. Default 0....
Definition: ERF_RadStruct.H:521
amrex::Real aerosol_tau_per_layer
Constant aerosol optical depth per layer [dimensionless]. Used for AerosolProfileType::Constant profi...
Definition: ERF_RadStruct.H:593
amrex::Real single_scattering_albedo
Clear-sky (background gas) single-scattering albedo in [0, 1] for the SW diffuse (scattering) two-str...
Definition: ERF_RadStruct.H:302
bool tau_sw_dynamic_enable
Definition: ERF_RadStruct.H:505
AerosolProfileType aerosol_profile_type
Aerosol optical depth profile type: Constant, Exponential, or Table.
Definition: ERF_RadStruct.H:586
amrex::Real rad_t_sfc
erf.rad_t_sfc: surface temperature [K] used as the longwave boundary condition wherever no land-surfa...
Definition: ERF_RadStruct.H:135
amrex::Real tau_lw_coeff_qc
Longwave optical depth coefficient for cloud liquid water [dimensionless]. Default 0....
Definition: ERF_RadStruct.H:537
amrex::Real cloud_single_scattering_albedo
Cloud single-scattering albedo in [0, 1], used instead of single_scattering_albedo for levels where t...
Definition: ERF_RadStruct.H:322
amrex::Real lw_kabs_cloud
Cloud-water LW mass absorption coefficient m^2/kg.
Definition: ERF_RadStruct.H:194
amrex::Real sw_cloud_omega
Mass model, SW: cloud-water single-scattering albedo.
Definition: ERF_RadStruct.H:170
amrex::Real sw_kscat_dry
Mass model, SW: dry-air (Rayleigh) scattering coefficient [m^2/kg], omega = 1, g = 0.
Definition: ERF_RadStruct.H:161
amrex::Real sw_kabs_dry
Mass model, SW: dry-air gray absorption coefficient [m^2/kg].
Definition: ERF_RadStruct.H:158
amrex::Real asymmetry_factor
Clear-sky (background gas) scattering asymmetry factor in [-1, 1] (0 = isotropic scattering,...
Definition: ERF_RadStruct.H:310
amrex::Real cloud_fraction_qc_scale
Cloud water [kg/kg] at which the liquid-water term alone gives a cloud fraction of 1: cf += min(1,...
Definition: ERF_RadStruct.H:569
bool cloud_fraction_prog_enable
Enable prognostic cloud fraction diagnosis from RH/qc. When true, cloud fraction is computed per-leve...
Definition: ERF_RadStruct.H:545
bool lw_enabled
Enable longwave (thermal) radiation computation. Only used by the two-stream model.
Definition: ERF_RadStruct.H:88
amrex::Real surface_albedo_sw_diffuse
Shortwave surface albedo for diffuse light [0,1]. A negative value (default) uses surface_albedo_sw f...
Definition: ERF_RadStruct.H:346
amrex::Real cloud_base_height_m
Cloud layer base height [m]. Only used when tau_profile_type == CloudLayer.
Definition: ERF_RadStruct.H:270
amrex::Real lw_kabs_vapor
Water-vapor gray LW mass absorption coefficient [m^2/kg].
Definition: ERF_RadStruct.H:191
amrex::Real tau_per_layer
Shortwave optical depth per layer (constant for all layers). Used in Beer-Lambert direct-beam formula...
Definition: ERF_RadStruct.H:95
amrex::Real tau_lw_coeff_qv
Longwave optical depth coefficient for water vapor [dimensionless]. Dynamic LW tau = tau_lw_coeff_qv ...
Definition: ERF_RadStruct.H:529
amrex::Real cloud_fraction_rh_max
Maximum relative humidity threshold for cloud fraction diagnosis [0, 1]. Must be >= cloud_fraction_rh...
Definition: ERF_RadStruct.H:561
amrex::Real sw_cloud_g
Mass model, SW: cloud-water asymmetry factor.
Definition: ERF_RadStruct.H:173
amrex::Real rad_cons_lon
Definition: ERF_RadStruct.H:139
bool lw_mass_absorption_enable
Gray longwave optical depth from the layer mass path instead of the fixed tau_lw_per_layer (also sele...
Definition: ERF_RadStruct.H:185
amrex::Real cloud_tau_per_layer
Additional optical depth per layer contributed by the cloud, added on top of the clear-sky tau_per_la...
Definition: ERF_RadStruct.H:284
amrex::Real aerosol_scale_height_m
Scale height for exponential aerosol profile [m]. Controls decay rate: tau_aerosol(k) = aerosol_tau_s...
Definition: ERF_RadStruct.H:601
amrex::Real rad_cons_lat
erf.rad_cons_lat / erf.rad_cons_lon: site latitude and longitude [degrees] when the grid has no lat/l...
Definition: ERF_RadStruct.H:138
amrex::Real cloud_fraction_rh_min
Minimum relative humidity threshold for cloud fraction diagnosis [0, 1]. Cloud fraction ramps from 0 ...
Definition: ERF_RadStruct.H:553
TauProfileType tau_profile_type
Optical depth profile type: "constant" (default, the thickness-independent tau) or "cloud_layer" (add...
Definition: ERF_RadStruct.H:264
Two-stream reflectance and transmittance of one homogeneous layer.
Definition: ERF_TwoStreamSW.H:132
amrex::Real T_dir
Definition: ERF_TwoStreamSW.H:136
amrex::Real T_dif
Definition: ERF_TwoStreamSW.H:134
amrex::Real R_dif
Definition: ERF_TwoStreamSW.H:133
amrex::Real R_dir
Definition: ERF_TwoStreamSW.H:135
Trivially copyable subset of RadChoice used by the column kernels.
Definition: ERF_TwoStreamColumn.H:57
amrex::Real cos_zenith_fixed
Definition: ERF_TwoStreamColumn.H:114
bool lw_mass_absorption_enable
Definition: ERF_TwoStreamColumn.H:105
amrex::Real lw_kabs_cloud
Definition: ERF_TwoStreamColumn.H:108
amrex::Real aerosol_tau_per_layer
Definition: ERF_TwoStreamColumn.H:93
amrex::Real sw_cloud_omega
Definition: ERF_TwoStreamColumn.H:102
amrex::Real cloud_single_scattering_albedo
Definition: ERF_TwoStreamColumn.H:70
amrex::Real sw_kabs_vapor
Definition: ERF_TwoStreamColumn.H:100
bool tau_sw_dynamic_enable
Definition: ERF_TwoStreamColumn.H:79
amrex::Real cloud_top_height_m
Definition: ERF_TwoStreamColumn.H:65
bool aerosol_enable
Definition: ERF_TwoStreamColumn.H:91
amrex::Real cloud_base_height_m
Definition: ERF_TwoStreamColumn.H:64
amrex::Real surface_emissivity_lw
Definition: ERF_TwoStreamColumn.H:75
amrex::Real aerosol_tau_surface
Definition: ERF_TwoStreamColumn.H:95
TauModel tau_model
Definition: ERF_TwoStreamColumn.H:97
bool sw_enabled
Definition: ERF_TwoStreamColumn.H:58
amrex::Real tau_lw_coeff_qv
Definition: ERF_TwoStreamColumn.H:83
amrex::Real cloud_tau_per_layer
Definition: ERF_TwoStreamColumn.H:66
TauProfileType tau_profile_type
Definition: ERF_TwoStreamColumn.H:63
amrex::Real surface_albedo_sw
Definition: ERF_TwoStreamColumn.H:73
amrex::Real tau_lw_per_layer
Definition: ERF_TwoStreamColumn.H:61
amrex::Real single_scattering_albedo
Definition: ERF_TwoStreamColumn.H:68
amrex::Real S0
Definition: ERF_TwoStreamColumn.H:115
amrex::Real lat_cons_rad
Definition: ERF_TwoStreamColumn.H:118
amrex::Real sw_kext_cloud
Definition: ERF_TwoStreamColumn.H:101
amrex::Real sw_kabs_dry
Definition: ERF_TwoStreamColumn.H:98
amrex::Real sw_kscat_dry
Definition: ERF_TwoStreamColumn.H:99
amrex::Real tau_sw_coeff_qc
Definition: ERF_TwoStreamColumn.H:82
amrex::Real cloud_fraction_qc_scale
Definition: ERF_TwoStreamColumn.H:89
amrex::Real tau_lw_coeff_qc
Definition: ERF_TwoStreamColumn.H:84
bool lw_enabled
Definition: ERF_TwoStreamColumn.H:59
amrex::Real aerosol_scale_height_m
Definition: ERF_TwoStreamColumn.H:94
amrex::Real t_sfc_default
Definition: ERF_TwoStreamColumn.H:76
amrex::Real surface_albedo_sw_diffuse
Definition: ERF_TwoStreamColumn.H:74
amrex::Real cloud_fraction_rh_max
Definition: ERF_TwoStreamColumn.H:88
amrex::Real rdOcp
Definition: ERF_TwoStreamColumn.H:77
bool cloud_fraction_prog_enable
Definition: ERF_TwoStreamColumn.H:86
amrex::Real tau_per_layer
Definition: ERF_TwoStreamColumn.H:60
amrex::Real cloud_asymmetry_factor
Definition: ERF_TwoStreamColumn.H:71
amrex::Real calday
Definition: ERF_TwoStreamColumn.H:116
amrex::Real declin
Definition: ERF_TwoStreamColumn.H:117
amrex::Real lon_cons_rad
Definition: ERF_TwoStreamColumn.H:119
bool solar_dynamic
Definition: ERF_TwoStreamColumn.H:113
amrex::Real sw_cloud_g
Definition: ERF_TwoStreamColumn.H:103
amrex::Real lw_kabs_vapor
Definition: ERF_TwoStreamColumn.H:107
AerosolProfileType aerosol_profile_type
Definition: ERF_TwoStreamColumn.H:92
amrex::Real tau_sw_coeff_qv
Definition: ERF_TwoStreamColumn.H:81
amrex::Real asymmetry_factor
Definition: ERF_TwoStreamColumn.H:69
bool tau_lw_dynamic_enable
Definition: ERF_TwoStreamColumn.H:80
amrex::Real lw_kabs_dry
Definition: ERF_TwoStreamColumn.H:106
amrex::Real cloud_fraction_rh_min
Definition: ERF_TwoStreamColumn.H:87