ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_SAMUtils.H File Reference
#include <cmath>
#include <limits>
#include <AMReX_Array4.H>
#include <AMReX_GpuQualifiers.H>
#include "ERF_Constants.H"
#include "ERF_MicrophysicsConstants.H"
#include "ERF_DataStruct.H"
#include "ERF_EOS.H"
#include "ERF_IndexDefines.H"
#include "ERF_MicrophysicsUtils.H"
Include dependency graph for ERF_SAMUtils.H:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  SAMPhaseFractions
 
struct  SAMCloudPhaseChange
 
struct  SAMPrecipSources
 
struct  SAMPrimitiveCell
 
struct  SAMPrecipConfig
 
struct  SAMPrecipCellDiagnostics
 
struct  SAMCoefficientRow
 
struct  SAMPrecipFaceState
 
struct  SAMPrecipComponentFaceState
 
struct  SAMFaceState
 
struct  SAMSurfaceAccumulation
 
struct  SAMPrecipFluxComponents
 

Typedefs

using SAMCellState = SAMPrimitiveCell
 

Functions

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_mbar_to_pa (const amrex::Real &pres_mbar) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_pa_to_mbar (const amrex::Real &pres_pa) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_theta_from_stored_mbar_converted_to_pa (const amrex::Real &tabs, const amrex::Real &pres_mbar, const amrex::Real rdOcp) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrimitiveCell sam_cons_to_primitive_with_thermo (const amrex::Real &rho, const amrex::Real &rho_theta, const amrex::Real &rho_qv, const amrex::Real &rho_qcl, const amrex::Real &rho_qci, const amrex::Real &rho_qpr, const amrex::Real &rho_qps, const amrex::Real &rho_qpg, const MicrophysicsThermoState &thermo) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrimitiveCell sam_cons_to_primitive_with_base_state (const amrex::Real &rho, const amrex::Real &rho_theta, const amrex::Real &rho_qv, const amrex::Real &rho_qcl, const amrex::Real &rho_qci, const amrex::Real &rho_qpr, const amrex::Real &rho_qps, const amrex::Real &rho_qpg, const amrex::Real rdOcp, const bool use_anelastic_reference_pressure, const amrex::Real p0) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrimitiveCell sam_copy_state_to_micro_cell (const amrex::Array4< const amrex::Real > &states, const amrex::Array4< const amrex::Real > &base, const amrex::Array4< amrex::Real > &rho, const amrex::Array4< amrex::Real > &theta, const amrex::Array4< amrex::Real > &qv, const amrex::Array4< amrex::Real > &qc, const amrex::Array4< amrex::Real > &qi, const amrex::Array4< amrex::Real > &qn, const amrex::Array4< amrex::Real > &qt, const amrex::Array4< amrex::Real > &qpr, const amrex::Array4< amrex::Real > &qps, const amrex::Array4< amrex::Real > &qpg, const amrex::Array4< amrex::Real > &qp, const amrex::Array4< amrex::Real > &tabs, const amrex::Array4< amrex::Real > &pres, const amrex::Real rdOcp, const bool use_anelastic_reference_pressure, const int i, const int j, const int k) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrimitiveCell sam_cons_to_primitive (const amrex::Real &rho, const amrex::Real &rho_theta, const amrex::Real &rho_qv, const amrex::Real &rho_qcl, const amrex::Real &rho_qci, const amrex::Real &rho_qpr, const amrex::Real &rho_qps, const amrex::Real &rho_qpg) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void sam_primitive_to_cons (const SAMPrimitiveCell &primitive, const amrex::Array4< amrex::Real > &states_arr, const int &i, const int &j, const int &k) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool sam_is_no_ice (const MoistureType &moisture_type) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool sam_is_no_precip (const MoistureType &moisture_type) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_cloud_liquid_fraction (const int &SAM_moisture_type, const amrex::Real &tabs, const amrex::Real an, const amrex::Real bn) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_precip_rain_fraction (const int &SAM_moisture_type, const amrex::Real &tabs) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_graupel_fraction (const int &SAM_moisture_type, const amrex::Real &tabs) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMCloudPhaseChange sam_partition_cloud_phase (const int &SAM_moisture_type, const amrex::Real &tabs, const amrex::Real &qn, const amrex::Real &qcl, const amrex::Real &qci, const amrex::Real fac_cond, const amrex::Real fac_fus, const amrex::Real an, const amrex::Real bn) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_mixed_qsat (const amrex::Real &omn, const amrex::Real &qsatw, const amrex::Real &qsati) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_mixed_dqsat_dT (const amrex::Real &omn, const amrex::Real &domn, const amrex::Real &qsatw, const amrex::Real &qsati, const amrex::Real &dqsatw, const amrex::Real &dqsati) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_mixed_dqif_dT (const amrex::Real &omn, const amrex::Real &domn, const amrex::Real &qn, const amrex::Real &dqsatm) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_newton_residual (const amrex::Real &tabs_new, const amrex::Real &tabs_old, const amrex::Real fcond, const amrex::Real &qv, const amrex::Real &qsatm, const amrex::Real ffus, const amrex::Real &qi, const amrex::Real &qif) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_newton_residual_derivative (const amrex::Real fcond, const amrex::Real ffus, const amrex::Real &dqsatm, const amrex::Real &dqif) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_autoconversion_rates (const amrex::Real &dtn, const amrex::Real &qcc, const amrex::Real &qii, const amrex::Real &coefice_k) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_accretion_rates (const amrex::Real &dtn, const amrex::Real &qcc, const amrex::Real &qii, const amrex::Real &qpr, const amrex::Real &qps, const amrex::Real &qpg, const amrex::Real &powr1, const amrex::Real &pows1, const amrex::Real &powg1, const amrex::Real &omp, const amrex::Real &omg, const amrex::Real &accrrc_k, const amrex::Real &accrsc_k, const amrex::Real &accrsi_k, const amrex::Real &accrgc_k, const amrex::Real &accrgi_k) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_rescale_cloud_sinks (const amrex::Real &qcl, const amrex::Real &qci, const amrex::Real &eps, SAMPrecipSources result) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_partition_autoconverted_precip (SAMPrecipSources result, const amrex::Real &omp, const amrex::Real &omg) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_precip_evaporation_rates (const amrex::Real &qpr, const amrex::Real &qps, const amrex::Real &qpg, const amrex::Real &powr2, const amrex::Real &pows2, const amrex::Real &powg2, const amrex::Real &evapr1_k, const amrex::Real &evapr2_k, const amrex::Real &evaps1_k, const amrex::Real &evaps2_k, const amrex::Real &evapg1_k, const amrex::Real &evapg2_k) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_apply_precip_evaporation_limiter (const amrex::Real &qpr, const amrex::Real &qps, const amrex::Real &qpg, SAMPrecipSources result) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMCellState sam_precip_cell_update (SAMCellState state, const SAMCoefficientRow &coeffs, const SAMPrecipConfig &config, SAMPrecipCellDiagnostics *diagnostics=nullptr) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMCoefficientRow sam_compute_coefficient_row (const amrex::Real &rho, const amrex::Real &tabs, const amrex::Real &gamr1, const amrex::Real &gamr2, const amrex::Real &gams1, const amrex::Real &gams2, const amrex::Real &gamg1, const amrex::Real &gamg2) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_cloud_ice_terminal_velocity (const amrex::Real &qci_avg) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMFaceState sam_face_average_state (const int &k, const int &k_lo, const int &k_hi, const amrex::Real &rho_km1, const amrex::Real &rho_k, const amrex::Real tabs_km1, const amrex::Real tabs_k, const amrex::Real &qci_km1, const amrex::Real &qci_k, const amrex::Real qp_km1, const amrex::Real qp_k) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int sam_precip_face_donor_k (const int &face_k, const int &k_lo, const int &k_hi) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int sam_substep_count_from_reduced_flux (const amrex::Real &reduced_flux, const amrex::Real &dt, const amrex::Real &dz) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipFaceState sam_precip_face_state (const int &SAM_moisture_type, const amrex::Array4< const amrex::Real > &rho_array, const amrex::Array4< const amrex::Real > &tabs_array, const amrex::Array4< const amrex::Real > &qp_array, const int &i, const int &j, const int &k, const int &k_lo, const int &k_hi) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipComponentFaceState sam_precip_component_face_state (const amrex::Array4< const amrex::Real > &rho_array, const amrex::Array4< const amrex::Real > &tabs_array, const amrex::Array4< const amrex::Real > &qpr_array, const amrex::Array4< const amrex::Real > &qps_array, const amrex::Array4< const amrex::Real > &qpg_array, const int &i, const int &j, const int &k, const int &k_lo, const int &k_hi) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_precip_flux_from_face_state (const SAMPrecipFaceState &face_state, const amrex::Real &vrain, const amrex::Real &vsnow, const amrex::Real &vgrau) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipFluxComponents sam_precip_flux_components_from_face_state (const SAMPrecipFaceState &face_state, const amrex::Real &vrain, const amrex::Real &vsnow, const amrex::Real &vgrau) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipFluxComponents sam_precip_component_fluxes_from_face_state (const SAMPrecipComponentFaceState &face_state, const amrex::Real &vrain, const amrex::Real &vsnow, const amrex::Real &vgrau) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_precip_flux_density_corrected (const amrex::Real &precip_flux, const amrex::Real &rho_0, const amrex::Real &rho_avg) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipFluxComponents sam_precip_flux_components_density_corrected (const SAMPrecipFluxComponents &precip_fluxes, const amrex::Real &rho_0, const amrex::Real &rho_avg) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_limit_precip_component_flux (const amrex::Real &raw_flux, const amrex::Real &rho_donor, const amrex::Real &q_donor, const amrex::Real &detJ_donor, const amrex::Real &coef) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_sedimentation_tendency (const amrex::Real &fz_hi, const amrex::Real &fz_lo, const amrex::Real &rho, const amrex::Real &dJinv, const amrex::Real &coef) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMSurfaceAccumulation sam_surface_accumulation_from_component_fluxes (const SAMPrecipFluxComponents &component_fluxes, const amrex::Real &dtn) noexcept
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMSurfaceAccumulation sam_surface_accumulation (const SAMPrecipFaceState &face_state, const amrex::Real &rho_0, const amrex::Real &vrain, const amrex::Real &vsnow, const amrex::Real &vgrau, const amrex::Real &dtn) noexcept
 

Typedef Documentation

◆ SAMCellState

Function Documentation

◆ sam_accretion_rates()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_accretion_rates ( const amrex::Real dtn,
const amrex::Real qcc,
const amrex::Real qii,
const amrex::Real qpr,
const amrex::Real qps,
const amrex::Real qpg,
const amrex::Real powr1,
const amrex::Real pows1,
const amrex::Real powg1,
const amrex::Real omp,
const amrex::Real omg,
const amrex::Real accrrc_k,
const amrex::Real accrsc_k,
const amrex::Real accrsi_k,
const amrex::Real accrgc_k,
const amrex::Real accrgi_k 
)
noexcept
534 {
535  SAMPrecipSources result{};
536  amrex::Real accrcr = zero;
537  amrex::Real accrcs = zero;
538  amrex::Real accris = zero;
539  amrex::Real accrcg = zero;
540  amrex::Real accrig = zero;
541 
542  // Accretion increments over dtn. Liquid-origin sinks feed rain, snow, and
543  // graupel; ice-origin sinks feed snow and graupel. These strict empirical
544  // selector thresholds are implementation rules, not fundamental laws:
545  // rain requires omp > 0.001, snow requires omp < 0.999 and omg < 0.999,
546  // and graupel requires omp < 0.999 and omg > 0.001. Equality is inactive.
547  if (omp > amrex::Real(0.001)) {
548  accrcr = accrrc_k;
549  }
550  if (omp < amrex::Real(0.999) && omg < amrex::Real(0.999)) {
551  accrcs = accrsc_k;
552  accris = accrsi_k;
553  }
554  if (omp < amrex::Real(0.999) && omg > amrex::Real(0.001)) {
555  accrcg = accrgc_k;
556  accrig = accrgi_k;
557  }
558 
559  result.dprc = dtn * accrcr * qcc * std::pow(qpr, powr1);
560  result.dpsc = dtn * accrcs * qcc * std::pow(qps, pows1);
561  result.dpgc = dtn * accrcg * qcc * std::pow(qpg, powg1);
562  result.dpsi = dtn * accris * qii * std::pow(qps, pows1);
563  result.dpgi = dtn * accrig * qii * std::pow(qpg, powg1);
564  return result;
565 }
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:29
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ qpg
Definition: ERF_Morrison.H:43
@ qps
Definition: ERF_Morrison.H:42
@ qpr
Definition: ERF_Morrison.H:41
Definition: ERF_SAMUtils.H:36

Referenced by sam_precip_cell_update().

Here is the caller graph for this function:

◆ sam_apply_precip_evaporation_limiter()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_apply_precip_evaporation_limiter ( const amrex::Real qpr,
const amrex::Real qps,
const amrex::Real qpg,
SAMPrecipSources  result 
)
noexcept
640 {
641  // Limits rain evaporation and snow/graupel sublimation by available
642  // qpr/qps/qpg so the source update cannot make precipitating species
643  // negative.
644  result.dqpr = amrex::min(qpr, result.dqpr);
645  result.dqps = amrex::min(qps, result.dqps);
646  result.dqpg = amrex::min(qpg, result.dqpg);
647  result.dqp = result.dqpr + result.dqps + result.dqpg;
648  return result;
649 }
amrex::Real dqpg
Definition: ERF_SAMUtils.H:48
amrex::Real dqps
Definition: ERF_SAMUtils.H:47
amrex::Real dqp
Definition: ERF_SAMUtils.H:49
amrex::Real dqpr
Definition: ERF_SAMUtils.H:46

Referenced by sam_precip_cell_update().

Here is the caller graph for this function:

◆ sam_autoconversion_rates()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_autoconversion_rates ( const amrex::Real dtn,
const amrex::Real qcc,
const amrex::Real qii,
const amrex::Real coefice_k 
)
noexcept
505 {
506  SAMPrecipSources result{};
507  // Thresholded cloud-liquid and cloud-ice autoconversion increments over
508  // the microphysics time step dtn. The strict qcw0/qci0 thresholds are
509  // intentional: equality leaves the source inactive.
510  const amrex::Real auto_r = (qcc > qcw0) ? alphaelq : zero;
511  const amrex::Real autos = (qii > qci0) ? betaelq * coefice_k : zero;
512  result.dqca = dtn * auto_r * (qcc - qcw0);
513  result.dqia = dtn * autos * (qii - qci0);
514  return result;
515 }
constexpr amrex::Real qci0
Definition: ERF_MicrophysicsConstants.H:77
constexpr amrex::Real betaelq
Definition: ERF_MicrophysicsConstants.H:79
constexpr amrex::Real alphaelq
Definition: ERF_MicrophysicsConstants.H:78
constexpr amrex::Real qcw0
Definition: ERF_MicrophysicsConstants.H:76

Referenced by sam_precip_cell_update().

Here is the caller graph for this function:

◆ sam_cloud_ice_terminal_velocity()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_cloud_ice_terminal_velocity ( const amrex::Real qci_avg)
noexcept
862 {
863  // MUST MATCH: SAM cloud-ice terminal-velocity coefficient and exponent.
864  return amrex::min(amrex::Real(0.4),
865  amrex::Real(8.66) * std::pow((amrex::max(amrex::Real(0.0), qci_avg) + amrex::Real(1.e-10)), amrex::Real(0.24)));
866 }

Referenced by SAM::IceFall().

Here is the caller graph for this function:

◆ sam_cloud_liquid_fraction()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_cloud_liquid_fraction ( const int &  SAM_moisture_type,
const amrex::Real tabs,
const amrex::Real  an,
const amrex::Real  bn 
)
noexcept
350 {
351  // Empirical cloud phase-fraction closure for omega_n. No-ice mode forces
352  // liquid fraction to one; the warm branch is all liquid, the cold branch
353  // is all ice, and the mixed branch varies linearly with temperature.
354  if (SAM_moisture_type == 2) {
355  return one;
356  }
357  if (tabs >= tbgmax) {
358  return one;
359  }
360  if (tabs <= tbgmin) {
361  return zero;
362  }
363  return an * tabs - bn;
364 }
constexpr amrex::Real tbgmax
Definition: ERF_MicrophysicsConstants.H:49
constexpr amrex::Real tbgmin
Definition: ERF_MicrophysicsConstants.H:48
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:30
@ tabs
Definition: ERF_Kessler.H:27

Referenced by SAM::NewtonIterSat(), sam_partition_cloud_phase(), and sam_precip_cell_update().

Here is the caller graph for this function:

◆ sam_compute_coefficient_row()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMCoefficientRow sam_compute_coefficient_row ( const amrex::Real rho,
const amrex::Real tabs,
const amrex::Real gamr1,
const amrex::Real gamr2,
const amrex::Real gams1,
const amrex::Real gams2,
const amrex::Real gamg1,
const amrex::Real gamg2 
)
noexcept
812 {
813  // Preserve the SAM baseline formula ordering in these closure rows.
814  SAMCoefficientRow row{};
815  amrex::Real prefactor;
816  amrex::Real pratio = std::sqrt(amrex::Real(1.29) / rho);
817  amrex::Real estw = amrex::Real(100.0) * erf_esatw(tabs);
818  amrex::Real esti = amrex::Real(100.0) * erf_esati(tabs);
819 
820  amrex::Real coef1 = fourth * PI * nzeros * a_snow * gams1 * pratio
821  / std::pow((PI * rhos * nzeros / rho), ((three + b_snow) / amrex::Real(4.0)));
822  amrex::Real coef2 = std::exp(amrex::Real(0.025) * (tabs - amrex::Real(273.15)));
823  row.accrsi = coef1 * coef2 * esicoef;
824  row.accrsc = coef1 * esccoef;
825  row.coefice = coef2;
826 
827  coef1 = (lsub / (tabs * R_v) - one) * lsub / (therco * tabs);
828  coef2 = R_v * tabs / (diffelq * esti);
829  prefactor = two * PI * nzeros / (rho * (coef1 + coef2));
830  prefactor *= (two / PI);
831  row.evaps1 = prefactor * amrex::Real(0.65) * std::sqrt(rho / (PI * rhos * nzeros));
832  row.evaps2 = prefactor * amrex::Real(0.44) * std::sqrt(a_snow * rho / muelq) * gams2
833  * std::sqrt(pratio) * std::pow(rho / (PI * rhos * nzeros), ((amrex::Real(5.0) + b_snow) / amrex::Real(8.0)));
834 
835  coef1 = fourth * PI * nzerog * a_grau * gamg1 * pratio
836  / std::pow((PI * rhog * nzerog / rho), ((three + b_grau) / amrex::Real(4.0)));
837  coef2 = std::exp(amrex::Real(0.025) * (tabs - amrex::Real(273.15)));
838  row.accrgi = coef1 * coef2 * egicoef;
839  row.accrgc = coef1 * egccoef;
840 
841  coef1 = (lsub / (tabs * R_v) - one) * lsub / (therco * tabs);
842  coef2 = R_v * tabs / (diffelq * esti);
843  prefactor = two * PI * nzerog / (rho * (coef1 + coef2));
844  row.evapg1 = prefactor * amrex::Real(0.78) * std::sqrt(rho / (PI * rhog * nzerog));
845  row.evapg2 = prefactor * amrex::Real(0.31) * std::sqrt(a_grau * rho / muelq) * gamg2
846  * std::sqrt(pratio) * std::pow(rho / (PI * rhog * nzerog), ((amrex::Real(5.0) + b_grau) / amrex::Real(8.0)));
847 
848  row.accrrc = fourth * PI * nzeror * a_rain * gamr1 * pratio
849  / std::pow((PI * rhor * nzeror / rho), ((three + b_rain) / amrex::Real(4.0))) * erccoef;
850 
851  coef1 = (lcond / (tabs * R_v) - one) * lcond / (therco * tabs);
852  coef2 = R_v * tabs / (diffelq * estw);
853  prefactor = two * PI * nzeror / (rho * (coef1 + coef2));
854  row.evapr1 = prefactor * amrex::Real(0.78) * std::sqrt(rho / (PI * rhor * nzeror));
855  row.evapr2 = prefactor * amrex::Real(0.31) * std::sqrt(a_rain * rho / muelq) * gamr2
856  * std::sqrt(pratio) * std::pow(rho / (PI * rhor * nzeror), ((amrex::Real(5.0) + b_rain) / amrex::Real(8.0)));
857  return row;
858 }
constexpr amrex::Real R_v
Definition: ERF_Constants.H:35
constexpr amrex::Real rhog
Definition: ERF_MicrophysicsConstants.H:41
constexpr amrex::Real muelq
Definition: ERF_MicrophysicsConstants.H:104
constexpr amrex::Real nzerog
Definition: ERF_MicrophysicsConstants.H:95
constexpr amrex::Real a_grau
Definition: ERF_MicrophysicsConstants.H:66
constexpr amrex::Real lsub
Definition: ERF_MicrophysicsConstants.H:111
constexpr amrex::Real esicoef
Definition: ERF_MicrophysicsConstants.H:86
constexpr amrex::Real diffelq
Definition: ERF_MicrophysicsConstants.H:102
constexpr amrex::Real therco
Definition: ERF_MicrophysicsConstants.H:103
constexpr amrex::Real b_grau
Definition: ERF_MicrophysicsConstants.H:67
constexpr amrex::Real egccoef
Definition: ERF_MicrophysicsConstants.H:87
constexpr amrex::Real egicoef
Definition: ERF_MicrophysicsConstants.H:88
constexpr amrex::Real b_rain
Definition: ERF_MicrophysicsConstants.H:63
constexpr amrex::Real lcond
Definition: ERF_MicrophysicsConstants.H:109
constexpr amrex::Real nzeror
Definition: ERF_MicrophysicsConstants.H:93
constexpr amrex::Real rhos
Definition: ERF_MicrophysicsConstants.H:40
constexpr amrex::Real esccoef
Definition: ERF_MicrophysicsConstants.H:85
constexpr amrex::Real rhor
Definition: ERF_MicrophysicsConstants.H:39
constexpr amrex::Real a_rain
Definition: ERF_MicrophysicsConstants.H:62
constexpr amrex::Real nzeros
Definition: ERF_MicrophysicsConstants.H:94
constexpr amrex::Real a_snow
Definition: ERF_MicrophysicsConstants.H:64
constexpr amrex::Real b_snow
Definition: ERF_MicrophysicsConstants.H:65
constexpr amrex::Real erccoef
Definition: ERF_MicrophysicsConstants.H:84
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_esati(amrex::Real t)
Definition: ERF_MicrophysicsUtils.H:67
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real erf_esatw(amrex::Real t, bool use_empirical=false)
Definition: ERF_MicrophysicsUtils.H:159
constexpr amrex::Real three
Definition: ERF_NumericalConstants.H:32
constexpr amrex::Real two
Definition: ERF_NumericalConstants.H:31
constexpr amrex::Real fourth
Definition: ERF_NumericalConstants.H:35
constexpr amrex::Real PI
Definition: ERF_NumericalConstants.H:39
@ rho
Definition: ERF_Kessler.H:25
Definition: ERF_SAMUtils.H:99

Referenced by SAM::Compute_Coefficients().

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

◆ sam_cons_to_primitive()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrimitiveCell sam_cons_to_primitive ( const amrex::Real rho,
const amrex::Real rho_theta,
const amrex::Real rho_qv,
const amrex::Real rho_qcl,
const amrex::Real rho_qci,
const amrex::Real rho_qpr,
const amrex::Real rho_qps,
const amrex::Real rho_qpg 
)
noexcept
293 {
294  // Keep the established compressible copy-in formula as its own entry
295  // point so the compressible path retains its original evaluation order.
296  SAMPrimitiveCell result{};
297  result.rho = rho;
298  result.theta = rho_theta / rho;
299  result.qv = amrex::max(amrex::Real(0.0), rho_qv / rho);
300  result.qcl = amrex::max(amrex::Real(0.0), rho_qcl / rho);
301  result.qci = amrex::max(amrex::Real(0.0), rho_qci / rho);
302  result.qn = result.qcl + result.qci;
303  result.qt = result.qv + result.qn;
304  result.qpr = amrex::max(amrex::Real(0.0), rho_qpr / rho);
305  result.qps = amrex::max(amrex::Real(0.0), rho_qps / rho);
306  result.qpg = amrex::max(amrex::Real(0.0), rho_qpg / rho);
307  result.qp = result.qpr + result.qps + result.qpg;
308  result.tabs = getTgivenRandRTh(rho, rho_theta, result.qv);
309  result.pres_mbar = sam_pa_to_mbar(getPgivenRTh(rho_theta, result.qv));
310  return result;
311 }
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 getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv=amrex::Real(0))
Definition: ERF_EOS.H:81
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_pa_to_mbar(const amrex::Real &pres_pa) noexcept
Definition: ERF_SAMUtils.H:166
Definition: ERF_SAMUtils.H:52
amrex::Real rho
Definition: ERF_SAMUtils.H:53
Here is the call graph for this function:

◆ sam_cons_to_primitive_with_base_state()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrimitiveCell sam_cons_to_primitive_with_base_state ( const amrex::Real rho,
const amrex::Real rho_theta,
const amrex::Real rho_qv,
const amrex::Real rho_qcl,
const amrex::Real rho_qci,
const amrex::Real rho_qpr,
const amrex::Real rho_qps,
const amrex::Real rho_qpg,
const amrex::Real  rdOcp,
const bool  use_anelastic_reference_pressure,
const amrex::Real  p0 
)
noexcept
226 {
227  const amrex::Real qv = amrex::max(amrex::Real(0.0), rho_qv / rho);
229  rho, rho_theta, qv, rdOcp,
230  use_anelastic_reference_pressure, p0);
232  rho, rho_theta, rho_qv, rho_qcl, rho_qci, rho_qpr, rho_qps, rho_qpg,
233  thermo);
234 }
const Real rdOcp
Definition: ERF_InitCustomPert_ABL.H:72
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE MicrophysicsThermoState diagnose_microphysics_thermo_state(const amrex::Real rho, const amrex::Real rho_theta, const amrex::Real qv, const amrex::Real rdOcp, const bool use_anelastic_reference_pressure, const amrex::Real p0) noexcept
Definition: ERF_MicrophysicsUtils.H:35
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrimitiveCell sam_cons_to_primitive_with_thermo(const amrex::Real &rho, const amrex::Real &rho_theta, const amrex::Real &rho_qv, const amrex::Real &rho_qcl, const amrex::Real &rho_qci, const amrex::Real &rho_qpr, const amrex::Real &rho_qps, const amrex::Real &rho_qpg, const MicrophysicsThermoState &thermo) noexcept
Definition: ERF_SAMUtils.H:183
@ qv
Definition: ERF_Kessler.H:31
real(c_double), parameter p0
Definition: ERF_module_model_constants.F90:40
Definition: ERF_MicrophysicsUtils.H:22

Referenced by sam_copy_state_to_micro_cell().

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

◆ sam_cons_to_primitive_with_thermo()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrimitiveCell sam_cons_to_primitive_with_thermo ( const amrex::Real rho,
const amrex::Real rho_theta,
const amrex::Real rho_qv,
const amrex::Real rho_qcl,
const amrex::Real rho_qci,
const amrex::Real rho_qpr,
const amrex::Real rho_qps,
const amrex::Real rho_qpg,
const MicrophysicsThermoState thermo 
)
noexcept
193 {
194  // The pressure and temperature are supplied by ERF's shared thermodynamic
195  // contract. SAM converts pressure to its established mbar storage here.
196  SAMPrimitiveCell result{};
197  result.rho = rho;
198  result.theta = rho_theta / rho;
199  result.qv = amrex::max(amrex::Real(0.0), rho_qv / rho);
200  result.qcl = amrex::max(amrex::Real(0.0), rho_qcl / rho);
201  result.qci = amrex::max(amrex::Real(0.0), rho_qci / rho);
202  result.qn = result.qcl + result.qci;
203  result.qt = result.qv + result.qn;
204  result.qpr = amrex::max(amrex::Real(0.0), rho_qpr / rho);
205  result.qps = amrex::max(amrex::Real(0.0), rho_qps / rho);
206  result.qpg = amrex::max(amrex::Real(0.0), rho_qpg / rho);
207  result.qp = result.qpr + result.qps + result.qpg;
208  result.tabs = thermo.temperature;
209  result.pres_mbar = sam_pa_to_mbar(thermo.pressure_pa);
210  return result;
211 }
amrex::Real pressure_pa
Definition: ERF_MicrophysicsUtils.H:23
amrex::Real temperature
Definition: ERF_MicrophysicsUtils.H:24

Referenced by sam_cons_to_primitive_with_base_state().

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

◆ sam_copy_state_to_micro_cell()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrimitiveCell sam_copy_state_to_micro_cell ( const amrex::Array4< const amrex::Real > &  states,
const amrex::Array4< const amrex::Real > &  base,
const amrex::Array4< amrex::Real > &  rho,
const amrex::Array4< amrex::Real > &  theta,
const amrex::Array4< amrex::Real > &  qv,
const amrex::Array4< amrex::Real > &  qc,
const amrex::Array4< amrex::Real > &  qi,
const amrex::Array4< amrex::Real > &  qn,
const amrex::Array4< amrex::Real > &  qt,
const amrex::Array4< amrex::Real > &  qpr,
const amrex::Array4< amrex::Real > &  qps,
const amrex::Array4< amrex::Real > &  qpg,
const amrex::Array4< amrex::Real > &  qp,
const amrex::Array4< amrex::Real > &  tabs,
const amrex::Array4< amrex::Real > &  pres,
const amrex::Real  rdOcp,
const bool  use_anelastic_reference_pressure,
const int  i,
const int  j,
const int  k 
)
noexcept
258 {
259  const amrex::Real rho_value = states(i,j,k,Rho_comp);
260  const amrex::Real p0 = use_anelastic_reference_pressure
261  ? base(i,j,k,BaseState::p0_comp) : amrex::Real(0.0);
263  rho_value, states(i,j,k,RhoTheta_comp),
264  states(i,j,k,RhoQ1_comp), states(i,j,k,RhoQ2_comp),
265  states(i,j,k,RhoQ3_comp), states(i,j,k,RhoQ4_comp),
266  states(i,j,k,RhoQ5_comp), states(i,j,k,RhoQ6_comp), rdOcp,
267  use_anelastic_reference_pressure, p0);
268  rho(i,j,k) = primitive.rho;
269  theta(i,j,k) = primitive.theta;
270  qv(i,j,k) = primitive.qv;
271  qc(i,j,k) = primitive.qcl;
272  qi(i,j,k) = primitive.qci;
273  qn(i,j,k) = primitive.qn;
274  qt(i,j,k) = primitive.qt;
275  qpr(i,j,k) = primitive.qpr;
276  qps(i,j,k) = primitive.qps;
277  qpg(i,j,k) = primitive.qpg;
278  qp(i,j,k) = primitive.qp;
279  tabs(i,j,k) = primitive.tabs;
280  pres(i,j,k) = primitive.pres_mbar;
281  return primitive;
282 }
#define Rho_comp
Definition: ERF_IndexDefines.H:39
#define RhoQ4_comp
Definition: ERF_IndexDefines.H:48
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:40
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:46
#define RhoQ3_comp
Definition: ERF_IndexDefines.H:47
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:45
#define RhoQ6_comp
Definition: ERF_IndexDefines.H:50
#define RhoQ5_comp
Definition: ERF_IndexDefines.H:49
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrimitiveCell sam_cons_to_primitive_with_base_state(const amrex::Real &rho, const amrex::Real &rho_theta, const amrex::Real &rho_qv, const amrex::Real &rho_qcl, const amrex::Real &rho_qci, const amrex::Real &rho_qpr, const amrex::Real &rho_qps, const amrex::Real &rho_qpg, const amrex::Real rdOcp, const bool use_anelastic_reference_pressure, const amrex::Real p0) noexcept
Definition: ERF_SAMUtils.H:214
@ p0_comp
Definition: ERF_IndexDefines.H:77
@ theta
Definition: ERF_SLM.H:19
@ qp
Definition: ERF_Kessler.H:34
@ pres
Definition: ERF_Kessler.H:28
@ qt
Definition: ERF_Kessler.H:30
@ qn
Definition: ERF_Morrison.H:35
@ qc
Definition: ERF_SatAdj.H:42
@ qi
Definition: ERF_WDM6.H:28
Definition: ERF_ConsoleIO.cpp:15
amrex::Real theta
Definition: ERF_SAMUtils.H:54
amrex::Real qpr
Definition: ERF_SAMUtils.H:62
amrex::Real qn
Definition: ERF_SAMUtils.H:60
amrex::Real qps
Definition: ERF_SAMUtils.H:63
amrex::Real qci
Definition: ERF_SAMUtils.H:59
amrex::Real qv
Definition: ERF_SAMUtils.H:57
amrex::Real tabs
Definition: ERF_SAMUtils.H:55
amrex::Real qpg
Definition: ERF_SAMUtils.H:64
amrex::Real qt
Definition: ERF_SAMUtils.H:61
amrex::Real qcl
Definition: ERF_SAMUtils.H:58
amrex::Real pres_mbar
Definition: ERF_SAMUtils.H:56
amrex::Real qp
Definition: ERF_SAMUtils.H:65
Here is the call graph for this function:

◆ sam_face_average_state()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMFaceState sam_face_average_state ( const int &  k,
const int &  k_lo,
const int &  k_hi,
const amrex::Real rho_km1,
const amrex::Real rho_k,
const amrex::Real  tabs_km1,
const amrex::Real  tabs_k,
const amrex::Real qci_km1,
const amrex::Real qci_k,
const amrex::Real  qp_km1,
const amrex::Real  qp_k 
)
noexcept
880 {
881  SAMFaceState result{};
882  if (k == k_lo) {
883  result.rho_avg = rho_k;
884  result.tabs_avg = tabs_k;
885  result.qci_avg = qci_k;
886  result.qp_avg = qp_k;
887  } else if (k == k_hi + 1) {
888  result.rho_avg = rho_km1;
889  result.tabs_avg = tabs_km1;
890  result.qci_avg = qci_km1;
891  result.qp_avg = qp_km1;
892  } else {
893  result.rho_avg = myhalf * (rho_km1 + rho_k);
894  result.tabs_avg = myhalf * (tabs_km1 + tabs_k);
895  result.qci_avg = myhalf * (qci_km1 + qci_k);
896  result.qp_avg = myhalf * (qp_km1 + qp_k);
897  }
898  return result;
899 }
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:34
Definition: ERF_SAMUtils.H:133
amrex::Real rho_avg
Definition: ERF_SAMUtils.H:134

Referenced by SAM::IceFall().

Here is the caller graph for this function:

◆ sam_graupel_fraction()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_graupel_fraction ( const int &  SAM_moisture_type,
const amrex::Real tabs 
)
noexcept
381 {
382  // Empirical graupel fraction omega_g. No-ice mode forces graupel fraction
383  // to zero, and the result is clipped to [0, 1].
384  if (SAM_moisture_type == 2) {
385  return zero;
386  }
387  return amrex::max(amrex::Real(0.0), amrex::min(amrex::Real(1.0), (tabs - tgrmin) * a_gr));
388 }
constexpr amrex::Real a_gr
Definition: ERF_MicrophysicsConstants.H:57
constexpr amrex::Real tgrmin
Definition: ERF_MicrophysicsConstants.H:52

Referenced by sam_precip_cell_update(), and sam_precip_face_state().

Here is the caller graph for this function:

◆ sam_is_no_ice()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool sam_is_no_ice ( const MoistureType &  moisture_type)
noexcept
334 {
335  return moisture_type == MoistureType::SAM_NoIce ||
336  moisture_type == MoistureType::SAM_NoPrecip_NoIce;
337 }

Referenced by SAM::Cloud(), and SAM::IceFall().

Here is the caller graph for this function:

◆ sam_is_no_precip()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool sam_is_no_precip ( const MoistureType &  moisture_type)
noexcept
341 {
342  return moisture_type == MoistureType::SAM_NoPrecip_NoIce;
343 }

Referenced by SAM::Precip(), and SAM::PrecipFall().

Here is the caller graph for this function:

◆ sam_limit_precip_component_flux()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_limit_precip_component_flux ( const amrex::Real raw_flux,
const amrex::Real rho_donor,
const amrex::Real q_donor,
const amrex::Real detJ_donor,
const amrex::Real coef 
)
noexcept
1093 {
1094  const amrex::Real available_flux =
1095  rho_donor * amrex::max(amrex::Real(0.0), q_donor) * detJ_donor / coef;
1096  return amrex::min(raw_flux, available_flux);
1097 }

Referenced by SAM::PrecipFall().

Here is the caller graph for this function:

◆ sam_mbar_to_pa()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_mbar_to_pa ( const amrex::Real pres_mbar)
noexcept
160 {
161  // SAM stores pressure in mbar. EOS and theta helpers expect Pa.
162  return amrex::Real(100.0) * pres_mbar;
163 }

Referenced by sam_theta_from_stored_mbar_converted_to_pa().

Here is the caller graph for this function:

◆ sam_mixed_dqif_dT()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_mixed_dqif_dT ( const amrex::Real omn,
const amrex::Real domn,
const amrex::Real qn,
const amrex::Real dqsatm 
)
noexcept
471 {
472  // Temperature derivative of the final ice fraction
473  return -domn * qn - (one - omn) * dqsatm;
474 }

Referenced by SAM::NewtonIterSat().

Here is the caller graph for this function:

◆ sam_mixed_dqsat_dT()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_mixed_dqsat_dT ( const amrex::Real omn,
const amrex::Real domn,
const amrex::Real qsatw,
const amrex::Real qsati,
const amrex::Real dqsatw,
const amrex::Real dqsati 
)
noexcept
460 {
461  // Temperature derivative of mixed saturation, including the mixed-branch
462  // temperature derivative of the liquid/ice phase fraction.
463  return omn * dqsatw + (one - omn) * dqsati + domn * qsatw - domn * qsati;
464 }
@ qsatw
Definition: ERF_WSM6.H:340
@ qsati
Definition: ERF_WSM6.H:340

Referenced by SAM::NewtonIterSat().

Here is the caller graph for this function:

◆ sam_mixed_qsat()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_mixed_qsat ( const amrex::Real omn,
const amrex::Real qsatw,
const amrex::Real qsati 
)
noexcept
448 {
449  // Mixed liquid/ice saturation relation used by the SAM cloud adjustment.
450  return omn * qsatw + (one - omn) * qsati;
451 }

Referenced by SAM::Cloud(), SAM::NewtonIterSat(), and sam_precip_cell_update().

Here is the caller graph for this function:

◆ sam_newton_residual()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_newton_residual ( const amrex::Real tabs_new,
const amrex::Real tabs_old,
const amrex::Real  fcond,
const amrex::Real qv,
const amrex::Real qsatm,
const amrex::Real  ffus,
const amrex::Real qi,
const amrex::Real qif 
)
noexcept
485 {
486  // Residual for the local constant-pressure saturation adjustment solve.
487  return -tabs_new + tabs_old + fcond * (qv - qsatm) - ffus * (qi - qif);
488 }

Referenced by SAM::NewtonIterSat().

Here is the caller graph for this function:

◆ sam_newton_residual_derivative()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_newton_residual_derivative ( const amrex::Real  fcond,
const amrex::Real  ffus,
const amrex::Real dqsatm,
const amrex::Real dqif 
)
noexcept
495 {
496  // Derivative for the local constant-pressure saturation adjustment solve.
497  return -one - fcond * dqsatm + ffus * dqif;
498 }

Referenced by SAM::NewtonIterSat().

Here is the caller graph for this function:

◆ sam_pa_to_mbar()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_pa_to_mbar ( const amrex::Real pres_pa)
noexcept
167 {
168  return amrex::Real(0.01) * pres_pa;
169 }

Referenced by SAM::Compute_Coefficients(), sam_cons_to_primitive(), and sam_cons_to_primitive_with_thermo().

Here is the caller graph for this function:

◆ sam_partition_autoconverted_precip()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_partition_autoconverted_precip ( SAMPrecipSources  result,
const amrex::Real omp,
const amrex::Real omg 
)
noexcept
601 {
602  // Partitions limited autoconversion sources into rain/snow/graupel using
603  // the precipitating phase fractions and adds direct accretion
604  // contributions. dqpr + dqps + dqpg equals the limited cloud sink total.
605  result.dqpr = (result.dqca + result.dqia) * omp + result.dprc;
606  result.dqps = (result.dqca + result.dqia) * (one - omp) * (one - omg) + result.dpsc + result.dpsi;
607  result.dqpg = (result.dqca + result.dqia) * (one - omp) * omg + result.dpgc + result.dpgi;
608  return result;
609 }
amrex::Real dpgc
Definition: ERF_SAMUtils.H:40
amrex::Real dqca
Definition: ERF_SAMUtils.H:37
amrex::Real dpsc
Definition: ERF_SAMUtils.H:39
amrex::Real dpgi
Definition: ERF_SAMUtils.H:43
amrex::Real dprc
Definition: ERF_SAMUtils.H:38
amrex::Real dqia
Definition: ERF_SAMUtils.H:41
amrex::Real dpsi
Definition: ERF_SAMUtils.H:42

Referenced by sam_precip_cell_update().

Here is the caller graph for this function:

◆ sam_partition_cloud_phase()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMCloudPhaseChange sam_partition_cloud_phase ( const int &  SAM_moisture_type,
const amrex::Real tabs,
const amrex::Real qn,
const amrex::Real qcl,
const amrex::Real qci,
const amrex::Real  fac_cond,
const amrex::Real  fac_fus,
const amrex::Real  an,
const amrex::Real  bn 
)
noexcept
400 {
401  // Repartition cloud condensate between liquid and ice using omega_n while
402  // preserving total cloud condensate qn. The temperature increment accounts
403  // for fusion heating/cooling under the held-pressure source-step
404  // convention; no-ice mode collapses condensate into liquid.
405  SAMCloudPhaseChange result{};
406  result.qcl = qcl;
407  result.qci = qci;
408  result.tabs = tabs;
409  result.omn = sam_cloud_liquid_fraction(SAM_moisture_type, tabs, an, bn);
410 
411  if (SAM_moisture_type == 1) {
412  if (tabs >= tbgmax) {
413  result.omn = one;
414  result.delta_qi = qci;
415  result.qci = zero;
416  result.qcl += result.delta_qi;
417  result.tabs -= fac_fus * result.delta_qi;
418  } else if (tabs <= tbgmin) {
419  result.omn = zero;
420  result.delta_qc = qcl;
421  result.qcl = zero;
422  result.qci += result.delta_qc;
423  result.tabs += fac_fus * result.delta_qc;
424  } else {
425  result.delta_qc = qcl - qn * result.omn;
426  result.delta_qi = qci - qn * (one - result.omn);
427  result.qcl = qn * result.omn;
428  result.qci = qn * (one - result.omn);
429  result.tabs += fac_fus * result.delta_qc;
430  result.omn = sam_cloud_liquid_fraction(SAM_moisture_type, result.tabs, an, bn);
431  }
432  } else {
433  result.omn = one;
434  result.delta_qc = qcl - qn;
435  result.qcl = qn;
436  result.qci = zero;
437  result.tabs += fac_cond * result.delta_qc;
438  }
439 
440  result.qn = result.qcl + result.qci;
441  return result;
442 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_cloud_liquid_fraction(const int &SAM_moisture_type, const amrex::Real &tabs, const amrex::Real an, const amrex::Real bn) noexcept
Definition: ERF_SAMUtils.H:346
@ qcl
Definition: ERF_Kessler.H:32
@ qci
Definition: ERF_Morrison.H:38
Definition: ERF_SAMUtils.H:23
amrex::Real qcl
Definition: ERF_SAMUtils.H:29

Referenced by SAM::Cloud().

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

◆ sam_precip_cell_update()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMCellState sam_precip_cell_update ( SAMCellState  state,
const SAMCoefficientRow coeffs,
const SAMPrecipConfig config,
SAMPrecipCellDiagnostics diagnostics = nullptr 
)
noexcept
656 {
657  // Local SAM precipitation source update. This is a cell-local,
658  // held-pressure microphysics update; sedimentation and surface
659  // accumulation are handled in PrecipFall. Before sedimentation, the source
660  // terms exchange water among qv/qcl/qci/qpr/qps/qpg, conserve total water,
661  // and conserve the constant-pressure latent proxy
662  // tabs + fac_cond*qv - fac_fus*(qci + qps + qpg)
663  // up to limiter and roundoff effects.
664  if (diagnostics != nullptr) {
665  *diagnostics = {};
666  }
667 
668  state.qn = state.qcl + state.qci;
669  state.qt = state.qv + state.qn;
670  state.qp = state.qpr + state.qps + state.qpg;
671 
672  if (!config.enable_precip || state.qn + state.qp <= zero) {
673  return state;
674  }
675 
676  amrex::Real omn;
677  amrex::Real omp;
678  amrex::Real omg;
679  if (config.sam_moisture_type == 2) {
680  omn = one;
681  omp = one;
682  omg = zero;
683  } else {
684  omn = sam_cloud_liquid_fraction(config.sam_moisture_type,
685  state.tabs, a_bg, tbgmin * a_bg);
686  omp = sam_precip_rain_fraction(config.sam_moisture_type,
687  state.tabs);
688  omg = sam_graupel_fraction(config.sam_moisture_type,
689  state.tabs);
690  }
691 
692  if (diagnostics != nullptr) {
693  diagnostics->omn = omn;
694  diagnostics->omp = omp;
695  diagnostics->omg = omg;
696  }
697 
698  if (state.qn > zero) {
699  SAMPrecipSources source_terms =
700  sam_autoconversion_rates(config.dtn, state.qcl, state.qci, coeffs.coefice);
701  const SAMPrecipSources accretion_terms =
702  sam_accretion_rates(config.dtn, state.qcl, state.qci, state.qpr, state.qps, state.qpg,
703  config.powr1, config.pows1, config.powg1,
704  omp, omg,
705  coeffs.accrrc, coeffs.accrsc, coeffs.accrsi,
706  coeffs.accrgc, coeffs.accrgi);
707  if (diagnostics != nullptr) {
708  diagnostics->autoconversion = source_terms;
709  diagnostics->accretion = accretion_terms;
710  }
711 
712  source_terms.dprc = accretion_terms.dprc;
713  source_terms.dpsc = accretion_terms.dpsc;
714  source_terms.dpgc = accretion_terms.dpgc;
715  source_terms.dpsi = accretion_terms.dpsi;
716  source_terms.dpgi = accretion_terms.dpgi;
717  source_terms = sam_rescale_cloud_sinks(state.qcl, state.qci,
718  config.eps, source_terms);
719  if (diagnostics != nullptr) {
720  diagnostics->limited_sources = source_terms;
721  }
722 
723  source_terms = sam_partition_autoconverted_precip(source_terms, omp, omg);
724  if (diagnostics != nullptr) {
725  diagnostics->partitioned_sources = source_terms;
726  }
727 
728  const amrex::Real dqca = source_terms.dqca;
729  const amrex::Real dqia = source_terms.dqia;
730 
731  state.qcl -= source_terms.dqc;
732  state.qci -= source_terms.dqi;
733  state.qpr += source_terms.dqpr;
734  state.qps += source_terms.dqps;
735  state.qpg += source_terms.dqpg;
736 
737  state.qn = state.qcl + state.qci;
738  state.qt = state.qv + state.qn;
739  state.qp = state.qpr + state.qps + state.qpg;
740 
741  // Cloud-liquid accretion onto snow and graupel increases frozen mass
742  // and must contribute the same fusion-heating term to the local latent
743  // proxy as the autoconverted frozen branch.
744  state.tabs += config.fac_fus * (dqca * (one - omp) - dqia * omp
745  + source_terms.dpsc + source_terms.dpgc);
747  state.pres_mbar,
748  config.rdOcp);
749  }
750 
753  erf_qsatw(state.tabs, state.pres_mbar, qsatw);
754  erf_qsati(state.tabs, state.pres_mbar, qsati);
755  const amrex::Real qsat = sam_mixed_qsat(omn, qsatw, qsati);
756  if (diagnostics != nullptr) {
757  diagnostics->qsat = qsat;
758  }
759 
760  if (state.qp > zero && state.qv < qsat) {
761  SAMPrecipSources evaporation_terms =
762  sam_precip_evaporation_rates(state.qpr, state.qps, state.qpg,
763  config.powr2, config.pows2, config.powg2,
764  coeffs.evapr1, coeffs.evapr2,
765  coeffs.evaps1, coeffs.evaps2,
766  coeffs.evapg1, coeffs.evapg2);
767 
768  const amrex::Real supersat_factor = config.dtn * (one - state.qv / qsat);
769  evaporation_terms.dqpr *= supersat_factor;
770  evaporation_terms.dqps *= supersat_factor;
771  evaporation_terms.dqpg *= supersat_factor;
772  evaporation_terms = sam_apply_precip_evaporation_limiter(state.qpr,
773  state.qps,
774  state.qpg,
775  evaporation_terms);
776  if (diagnostics != nullptr) {
777  diagnostics->evaporation = evaporation_terms;
778  }
779 
780  state.qv += evaporation_terms.dqp;
781  state.qpr -= evaporation_terms.dqpr;
782  state.qps -= evaporation_terms.dqps;
783  state.qpg -= evaporation_terms.dqpg;
784 
785  state.qt = state.qv + state.qn;
786  state.qp = state.qpr + state.qps + state.qpg;
787 
788  // Rain evaporation cools with Lv/cp; snow and graupel sublimation cool
789  // with Ls/cp, preserving the same local latent proxy.
790  state.tabs -= config.fac_cond * evaporation_terms.dqpr
791  + config.fac_sub * (evaporation_terms.dqps + evaporation_terms.dqpg);
793  state.pres_mbar,
794  config.rdOcp);
795  }
796 
797  return state;
798 }
const auto config
Definition: ERF_InitCustomPert_CloudChamber.H:37
constexpr amrex::Real a_bg
Definition: ERF_MicrophysicsConstants.H:55
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void erf_qsatw(amrex::Real t, amrex::Real p, amrex::Real &qsatw)
Definition: ERF_MicrophysicsUtils.H:264
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void erf_qsati(amrex::Real t, amrex::Real p, amrex::Real &qsati)
Definition: ERF_MicrophysicsUtils.H:254
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_accretion_rates(const amrex::Real &dtn, const amrex::Real &qcc, const amrex::Real &qii, const amrex::Real &qpr, const amrex::Real &qps, const amrex::Real &qpg, const amrex::Real &powr1, const amrex::Real &pows1, const amrex::Real &powg1, const amrex::Real &omp, const amrex::Real &omg, const amrex::Real &accrrc_k, const amrex::Real &accrsc_k, const amrex::Real &accrsi_k, const amrex::Real &accrgc_k, const amrex::Real &accrgi_k) noexcept
Definition: ERF_SAMUtils.H:518
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_graupel_fraction(const int &SAM_moisture_type, const amrex::Real &tabs) noexcept
Definition: ERF_SAMUtils.H:379
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_precip_rain_fraction(const int &SAM_moisture_type, const amrex::Real &tabs) noexcept
Definition: ERF_SAMUtils.H:367
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_autoconversion_rates(const amrex::Real &dtn, const amrex::Real &qcc, const amrex::Real &qii, const amrex::Real &coefice_k) noexcept
Definition: ERF_SAMUtils.H:501
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_rescale_cloud_sinks(const amrex::Real &qcl, const amrex::Real &qci, const amrex::Real &eps, SAMPrecipSources result) noexcept
Definition: ERF_SAMUtils.H:568
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_apply_precip_evaporation_limiter(const amrex::Real &qpr, const amrex::Real &qps, const amrex::Real &qpg, SAMPrecipSources result) noexcept
Definition: ERF_SAMUtils.H:636
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_theta_from_stored_mbar_converted_to_pa(const amrex::Real &tabs, const amrex::Real &pres_mbar, const amrex::Real rdOcp) noexcept
Definition: ERF_SAMUtils.H:172
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_partition_autoconverted_precip(SAMPrecipSources result, const amrex::Real &omp, const amrex::Real &omg) noexcept
Definition: ERF_SAMUtils.H:598
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_mixed_qsat(const amrex::Real &omn, const amrex::Real &qsatw, const amrex::Real &qsati) noexcept
Definition: ERF_SAMUtils.H:445
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_precip_evaporation_rates(const amrex::Real &qpr, const amrex::Real &qps, const amrex::Real &qpg, const amrex::Real &powr2, const amrex::Real &pows2, const amrex::Real &powg2, const amrex::Real &evapr1_k, const amrex::Real &evapr2_k, const amrex::Real &evaps1_k, const amrex::Real &evaps2_k, const amrex::Real &evapg1_k, const amrex::Real &evapg2_k) noexcept
Definition: ERF_SAMUtils.H:612
amrex::Real coefice
Definition: ERF_SAMUtils.H:103
amrex::Real evaps2
Definition: ERF_SAMUtils.H:105
amrex::Real accrsi
Definition: ERF_SAMUtils.H:101
amrex::Real accrgc
Definition: ERF_SAMUtils.H:107
amrex::Real accrgi
Definition: ERF_SAMUtils.H:106
amrex::Real accrsc
Definition: ERF_SAMUtils.H:102
amrex::Real evapg1
Definition: ERF_SAMUtils.H:108
amrex::Real evapr1
Definition: ERF_SAMUtils.H:110
amrex::Real evapg2
Definition: ERF_SAMUtils.H:109
amrex::Real accrrc
Definition: ERF_SAMUtils.H:100
amrex::Real evapr2
Definition: ERF_SAMUtils.H:111
amrex::Real evaps1
Definition: ERF_SAMUtils.H:104
SAMPrecipSources limited_sources
Definition: ERF_SAMUtils.H:90
amrex::Real omg
Definition: ERF_SAMUtils.H:96
amrex::Real omp
Definition: ERF_SAMUtils.H:95
SAMPrecipSources partitioned_sources
Definition: ERF_SAMUtils.H:91
amrex::Real qsat
Definition: ERF_SAMUtils.H:93
SAMPrecipSources evaporation
Definition: ERF_SAMUtils.H:92
amrex::Real omn
Definition: ERF_SAMUtils.H:94
SAMPrecipSources autoconversion
Definition: ERF_SAMUtils.H:88
SAMPrecipSources accretion
Definition: ERF_SAMUtils.H:89
amrex::Real dqc
Definition: ERF_SAMUtils.H:44
amrex::Real dqi
Definition: ERF_SAMUtils.H:45

Referenced by SAM::Precip().

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

◆ sam_precip_component_face_state()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipComponentFaceState sam_precip_component_face_state ( const amrex::Array4< const amrex::Real > &  rho_array,
const amrex::Array4< const amrex::Real > &  tabs_array,
const amrex::Array4< const amrex::Real > &  qpr_array,
const amrex::Array4< const amrex::Real > &  qps_array,
const amrex::Array4< const amrex::Real > &  qpg_array,
const int &  i,
const int &  j,
const int &  k,
const int &  k_lo,
const int &  k_hi 
)
noexcept
975 {
976  // MUST MATCH: SAM PrecipFall bottom/interior/top face rules.
978  if (k == k_lo) {
979  result.rho_avg = rho_array(i,j,k);
980  result.tabs_avg = tabs_array(i,j,k);
981  result.qpr_avg = qpr_array(i,j,k);
982  result.qps_avg = qps_array(i,j,k);
983  result.qpg_avg = qpg_array(i,j,k);
984  } else if (k == k_hi + 1) {
985  result.rho_avg = rho_array(i,j,k-1);
986  result.tabs_avg = tabs_array(i,j,k-1);
987  result.qpr_avg = qpr_array(i,j,k-1);
988  result.qps_avg = qps_array(i,j,k-1);
989  result.qpg_avg = qpg_array(i,j,k-1);
990  } else {
991  result.rho_avg = myhalf * (rho_array(i,j,k-1) + rho_array(i,j,k));
992  result.tabs_avg = myhalf * (tabs_array(i,j,k-1) + tabs_array(i,j,k));
993  result.qpr_avg = myhalf * (qpr_array(i,j,k-1) + qpr_array(i,j,k));
994  result.qps_avg = myhalf * (qps_array(i,j,k-1) + qps_array(i,j,k));
995  result.qpg_avg = myhalf * (qpg_array(i,j,k-1) + qpg_array(i,j,k));
996  }
997  return result;
998 }
Definition: ERF_SAMUtils.H:125
amrex::Real rho_avg
Definition: ERF_SAMUtils.H:126

Referenced by SAM::PrecipFall().

Here is the caller graph for this function:

◆ sam_precip_component_fluxes_from_face_state()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipFluxComponents sam_precip_component_fluxes_from_face_state ( const SAMPrecipComponentFaceState face_state,
const amrex::Real vrain,
const amrex::Real vsnow,
const amrex::Real vgrau 
)
noexcept
1050 {
1051  SAMPrecipFluxComponents result{};
1052  if (face_state.qpr_avg > zero) {
1053  result.rain = vrain * std::pow(face_state.rho_avg * face_state.qpr_avg, one + crain);
1054  }
1055  if (face_state.qps_avg > zero) {
1056  result.snow = vsnow * std::pow(face_state.rho_avg * face_state.qps_avg, one + csnow);
1057  }
1058  if (face_state.qpg_avg > zero) {
1059  result.graupel = vgrau * std::pow(face_state.rho_avg * face_state.qpg_avg, one + cgrau);
1060  }
1061  return result;
1062 }
constexpr amrex::Real csnow
Definition: ERF_MicrophysicsConstants.H:70
constexpr amrex::Real cgrau
Definition: ERF_MicrophysicsConstants.H:71
constexpr amrex::Real crain
Definition: ERF_MicrophysicsConstants.H:69
amrex::Real qpr_avg
Definition: ERF_SAMUtils.H:128
amrex::Real qpg_avg
Definition: ERF_SAMUtils.H:130
amrex::Real qps_avg
Definition: ERF_SAMUtils.H:129
Definition: ERF_SAMUtils.H:146
amrex::Real rain
Definition: ERF_SAMUtils.H:147

Referenced by SAM::PrecipFall().

Here is the caller graph for this function:

◆ sam_precip_evaporation_rates()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_precip_evaporation_rates ( const amrex::Real qpr,
const amrex::Real qps,
const amrex::Real qpg,
const amrex::Real powr2,
const amrex::Real pows2,
const amrex::Real powg2,
const amrex::Real evapr1_k,
const amrex::Real evapr2_k,
const amrex::Real evaps1_k,
const amrex::Real evaps2_k,
const amrex::Real evapg1_k,
const amrex::Real evapg2_k 
)
noexcept
624 {
625  // Positive-domain evaporation/sublimation rate form for precipitating
626  // species: C1*sqrt(q_m) + C2*q_m^p. The derivative is singular at q_m = 0,
627  // so derivative checks only make sense away from zero.
628  SAMPrecipSources result{};
629  result.dqpr = evapr1_k * std::sqrt(qpr) + evapr2_k * std::pow(qpr, powr2);
630  result.dqps = evaps1_k * std::sqrt(qps) + evaps2_k * std::pow(qps, pows2);
631  result.dqpg = evapg1_k * std::sqrt(qpg) + evapg2_k * std::pow(qpg, powg2);
632  return result;
633 }

Referenced by sam_precip_cell_update().

Here is the caller graph for this function:

◆ sam_precip_face_donor_k()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int sam_precip_face_donor_k ( const int &  face_k,
const int &  k_lo,
const int &  k_hi 
)
noexcept
905 {
906  if (face_k <= k_lo) {
907  return k_lo;
908  }
909  if (face_k >= k_hi + 1) {
910  return k_hi;
911  }
912  return face_k;
913 }

Referenced by SAM::PrecipFall().

Here is the caller graph for this function:

◆ sam_precip_face_state()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipFaceState sam_precip_face_state ( const int &  SAM_moisture_type,
const amrex::Array4< const amrex::Real > &  rho_array,
const amrex::Array4< const amrex::Real > &  tabs_array,
const amrex::Array4< const amrex::Real > &  qp_array,
const int &  i,
const int &  j,
const int &  k,
const int &  k_lo,
const int &  k_hi 
)
noexcept
937 {
938  // MUST MATCH: SAM PrecipFall bottom/interior/top face rules.
939  SAMPrecipFaceState result{};
940  if (k == k_lo) {
941  result.rho_avg = rho_array(i,j,k);
942  result.tabs_avg = tabs_array(i,j,k);
943  result.qp_avg = qp_array(i,j,k);
944  } else if (k == k_hi + 1) {
945  result.rho_avg = rho_array(i,j,k-1);
946  result.tabs_avg = tabs_array(i,j,k-1);
947  result.qp_avg = qp_array(i,j,k-1);
948  } else {
949  result.rho_avg = myhalf * (rho_array(i,j,k-1) + rho_array(i,j,k));
950  result.tabs_avg = myhalf * (tabs_array(i,j,k-1) + tabs_array(i,j,k));
951  result.qp_avg = myhalf * (qp_array(i,j,k-1) + qp_array(i,j,k));
952  }
953  result.omp = sam_precip_rain_fraction(SAM_moisture_type, result.tabs_avg);
954  result.omg = sam_graupel_fraction(SAM_moisture_type, result.tabs_avg);
955  result.qrr = result.omp * result.qp_avg;
956  result.qss = (one - result.omp) * (one - result.omg) * result.qp_avg;
957  result.qgg = (one - result.omp) * result.omg * result.qp_avg;
958  return result;
959 }
Definition: ERF_SAMUtils.H:114
amrex::Real rho_avg
Definition: ERF_SAMUtils.H:115
Here is the call graph for this function:

◆ sam_precip_flux_components_density_corrected()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipFluxComponents sam_precip_flux_components_density_corrected ( const SAMPrecipFluxComponents precip_fluxes,
const amrex::Real rho_0,
const amrex::Real rho_avg 
)
noexcept
1076 {
1077  const amrex::Real density_correction = std::sqrt(rho_0 / rho_avg);
1078  return {
1079  precip_fluxes.rain * density_correction,
1080  precip_fluxes.snow * density_correction,
1081  precip_fluxes.graupel * density_correction};
1082 }
Real rho_0
Definition: ERF_InitCustomPert_ABL.H:18
amrex::Real snow
Definition: ERF_SAMUtils.H:148
amrex::Real graupel
Definition: ERF_SAMUtils.H:149

Referenced by SAM::PrecipFall(), and sam_surface_accumulation().

Here is the caller graph for this function:

◆ sam_precip_flux_components_from_face_state()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipFluxComponents sam_precip_flux_components_from_face_state ( const SAMPrecipFaceState face_state,
const amrex::Real vrain,
const amrex::Real vsnow,
const amrex::Real vgrau 
)
noexcept
1027 {
1028  SAMPrecipFluxComponents result{};
1029  if (face_state.qp_avg <= qp_threshold) {
1030  return result;
1031  }
1032 
1033  result.rain = face_state.omp * vrain * std::pow(face_state.rho_avg * face_state.qrr, one + crain);
1034  result.snow = (one - face_state.omp) * (one - face_state.omg)
1035  * vsnow * std::pow(face_state.rho_avg * face_state.qss, one + csnow);
1036  result.graupel = (one - face_state.omp) * face_state.omg
1037  * vgrau * std::pow(face_state.rho_avg * face_state.qgg, one + cgrau);
1038  return result;
1039 }
constexpr amrex::Real qp_threshold
Definition: ERF_MicrophysicsConstants.H:96
amrex::Real omg
Definition: ERF_SAMUtils.H:119
amrex::Real qss
Definition: ERF_SAMUtils.H:121
amrex::Real qrr
Definition: ERF_SAMUtils.H:120
amrex::Real qp_avg
Definition: ERF_SAMUtils.H:117
amrex::Real qgg
Definition: ERF_SAMUtils.H:122
amrex::Real omp
Definition: ERF_SAMUtils.H:118

Referenced by sam_surface_accumulation().

Here is the caller graph for this function:

◆ sam_precip_flux_density_corrected()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_precip_flux_density_corrected ( const amrex::Real precip_flux,
const amrex::Real rho_0,
const amrex::Real rho_avg 
)
noexcept
1068 {
1069  return precip_flux * std::sqrt(rho_0 / rho_avg);
1070 }

◆ sam_precip_flux_from_face_state()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_precip_flux_from_face_state ( const SAMPrecipFaceState face_state,
const amrex::Real vrain,
const amrex::Real vsnow,
const amrex::Real vgrau 
)
noexcept
1009 {
1010  if (face_state.qp_avg <= qp_threshold) {
1011  return zero;
1012  }
1013  return face_state.omp * vrain * std::pow(face_state.rho_avg * face_state.qrr, one + crain)
1014  + (one - face_state.omp)
1015  * ((one - face_state.omg) * vsnow * std::pow(face_state.rho_avg * face_state.qss, one + csnow)
1016  + face_state.omg * vgrau * std::pow(face_state.rho_avg * face_state.qgg, one + cgrau));
1017 }

◆ sam_precip_rain_fraction()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_precip_rain_fraction ( const int &  SAM_moisture_type,
const amrex::Real tabs 
)
noexcept
369 {
370  // Empirical precipitating rain fraction omega_p. No-ice mode forces rain
371  // fraction to one, and the result is clipped to [0, 1].
372  if (SAM_moisture_type == 2) {
373  return one;
374  }
375  return amrex::max(amrex::Real(0.0), amrex::min(amrex::Real(1.0), (tabs - tprmin) * a_pr));
376 }
constexpr amrex::Real tprmin
Definition: ERF_MicrophysicsConstants.H:50
constexpr amrex::Real a_pr
Definition: ERF_MicrophysicsConstants.H:56

Referenced by sam_precip_cell_update(), and sam_precip_face_state().

Here is the caller graph for this function:

◆ sam_primitive_to_cons()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void sam_primitive_to_cons ( const SAMPrimitiveCell primitive,
const amrex::Array4< amrex::Real > &  states_arr,
const int &  i,
const int &  j,
const int &  k 
)
noexcept
319 {
320  // Copy-out writes rho*theta and clipped moisture species back to the
321  // conserved state. Pressure is not stored here; it is diagnosed again on
322  // the next copy-in.
323  states_arr(i,j,k,RhoTheta_comp) = primitive.rho * primitive.theta;
324  states_arr(i,j,k,RhoQ1_comp) = primitive.rho * amrex::max(amrex::Real(0.0), primitive.qv);
325  states_arr(i,j,k,RhoQ2_comp) = primitive.rho * amrex::max(amrex::Real(0.0), primitive.qcl);
326  states_arr(i,j,k,RhoQ3_comp) = primitive.rho * amrex::max(amrex::Real(0.0), primitive.qci);
327  states_arr(i,j,k,RhoQ4_comp) = primitive.rho * amrex::max(amrex::Real(0.0), primitive.qpr);
328  states_arr(i,j,k,RhoQ5_comp) = primitive.rho * amrex::max(amrex::Real(0.0), primitive.qps);
329  states_arr(i,j,k,RhoQ6_comp) = primitive.rho * amrex::max(amrex::Real(0.0), primitive.qpg);
330 }

Referenced by SAM::Copy_Micro_to_State().

Here is the caller graph for this function:

◆ sam_rescale_cloud_sinks()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipSources sam_rescale_cloud_sinks ( const amrex::Real qcl,
const amrex::Real qci,
const amrex::Real eps,
SAMPrecipSources  result 
)
noexcept
572 {
573  // Proportional donor limiter. If requested liquid or ice sinks exceed
574  // available qcl/qci, all competing sinks from the same donor phase share
575  // one scale factor. This preserves source ratios while preventing negative
576  // qcl or qci. The eps denominator intentionally leaves only an epsilon-
577  // scale undershoot.
578  result.dqc = result.dqca + result.dprc + result.dpsc + result.dpgc;
579  result.dqi = result.dqia + result.dpsi + result.dpgi;
580 
581  const amrex::Real scalec = amrex::min(qcl, result.dqc) / (result.dqc + eps);
582  const amrex::Real scalei = amrex::min(qci, result.dqi) / (result.dqi + eps);
583 
584  result.dqca *= scalec;
585  result.dprc *= scalec;
586  result.dpsc *= scalec;
587  result.dpgc *= scalec;
588  result.dqia *= scalei;
589  result.dpsi *= scalei;
590  result.dpgi *= scalei;
591  result.dqc = result.dqca + result.dprc + result.dpsc + result.dpgc;
592  result.dqi = result.dqia + result.dpsi + result.dpgi;
593 
594  return result;
595 }

Referenced by sam_precip_cell_update().

Here is the caller graph for this function:

◆ sam_sedimentation_tendency()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_sedimentation_tendency ( const amrex::Real fz_hi,
const amrex::Real fz_lo,
const amrex::Real rho,
const amrex::Real dJinv,
const amrex::Real coef 
)
noexcept
1108 {
1109  return dJinv * (one / rho) * (fz_hi - fz_lo) * coef;
1110 }

Referenced by SAM::IceFall(), and SAM::PrecipFall().

Here is the caller graph for this function:

◆ sam_substep_count_from_reduced_flux()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int sam_substep_count_from_reduced_flux ( const amrex::Real reduced_flux,
const amrex::Real dt,
const amrex::Real dz 
)
noexcept
919 {
920  // Substeps follow the legacy reduced-flux rule based on the maximum
921  // density-corrected precip flux, not directly on a terminal fall speed.
922  // Property tests characterize this behavior before any intended change.
923  // MUST MATCH: SAM::CFL_MAX.
924  return static_cast<int>(std::ceil(reduced_flux * (dt / dz) / myhalf));
925 }
@ dz
Definition: ERF_AdvanceWDM6.cpp:272

Referenced by SAM::IceFall(), and SAM::PrecipFall().

Here is the caller graph for this function:

◆ sam_surface_accumulation()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMSurfaceAccumulation sam_surface_accumulation ( const SAMPrecipFaceState face_state,
const amrex::Real rho_0,
const amrex::Real vrain,
const amrex::Real vsnow,
const amrex::Real vgrau,
const amrex::Real dtn 
)
noexcept
1134 {
1135  const SAMPrecipFluxComponents face_fluxes =
1136  sam_precip_flux_components_from_face_state(face_state, vrain, vsnow, vgrau);
1137 
1140  dtn);
1141 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipFluxComponents sam_precip_flux_components_from_face_state(const SAMPrecipFaceState &face_state, const amrex::Real &vrain, const amrex::Real &vsnow, const amrex::Real &vgrau) noexcept
Definition: ERF_SAMUtils.H:1023
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMSurfaceAccumulation sam_surface_accumulation_from_component_fluxes(const SAMPrecipFluxComponents &component_fluxes, const amrex::Real &dtn) noexcept
Definition: ERF_SAMUtils.H:1116
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMPrecipFluxComponents sam_precip_flux_components_density_corrected(const SAMPrecipFluxComponents &precip_fluxes, const amrex::Real &rho_0, const amrex::Real &rho_avg) noexcept
Definition: ERF_SAMUtils.H:1073
Here is the call graph for this function:

◆ sam_surface_accumulation_from_component_fluxes()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE SAMSurfaceAccumulation sam_surface_accumulation_from_component_fluxes ( const SAMPrecipFluxComponents component_fluxes,
const amrex::Real dtn 
)
noexcept
1119 {
1120  SAMSurfaceAccumulation result{};
1121  result.rain = component_fluxes.rain * dtn / rhor * amrex::Real(1000.0);
1122  result.snow = component_fluxes.snow * dtn / rhos * amrex::Real(1000.0);
1123  result.graupel = component_fluxes.graupel * dtn / rhog * amrex::Real(1000.0);
1124  return result;
1125 }
Definition: ERF_SAMUtils.H:140
amrex::Real rain
Definition: ERF_SAMUtils.H:141

Referenced by SAM::PrecipFall(), and sam_surface_accumulation().

Here is the caller graph for this function:

◆ sam_theta_from_stored_mbar_converted_to_pa()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_theta_from_stored_mbar_converted_to_pa ( const amrex::Real tabs,
const amrex::Real pres_mbar,
const amrex::Real  rdOcp 
)
noexcept
175 {
176  // Do not replace this with getThgivenRandT(rho,T,qv): that would enforce a
177  // fixed-density EOS projection rather than the SAM source-step
178  // thermodynamic contract.
179  return getThgivenTandP(tabs, sam_mbar_to_pa(pres_mbar), rdOcp);
180 }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getThgivenTandP(const amrex::Real T, const amrex::Real P, const amrex::Real rdOcp)
Definition: ERF_EOS.H:18
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real sam_mbar_to_pa(const amrex::Real &pres_mbar) noexcept
Definition: ERF_SAMUtils.H:159

Referenced by SAM::Cloud(), and sam_precip_cell_update().

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