ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_Morrison.H
Go to the documentation of this file.
1 /*
2  * Implementation of a 2-moment microphysics model
3  * This model is based on the Morrison model as implemented in WRF (in Fortran)
4  */
5 #ifndef ERF_Morrison_H
6 #define ERF_Morrison_H
7 
8 #include <string>
9 #include <vector>
10 #include <memory>
11 
12 #include <AMReX_FArrayBox.H>
13 #include <AMReX_Geometry.H>
14 #include <AMReX_TableData.H>
15 #include <AMReX_MultiFabUtil.H>
16 
17 #include "ERF_Constants.H"
19 #include "ERF_MicrophysicsUtils.H"
20 #include "ERF_IndexDefines.H"
21 #include "ERF_DataStruct.H"
22 #include "ERF_NullMoist.H"
26 
27 namespace MicVar_Morr {
28  enum {
29  // independent variables
30  rho=0, // density
31  theta, // liquid/ice water potential temperature
32  tabs, // temperature
33  pres, // pressure
34  // non-precipitating vars
35  qt, // total cloud
36  qn, // cloud condensate (liquid + ice)
37  qv, // cloud vapor
38  qcl, // cloud water
39  qci, // cloud ice
40  // precipitating vars
41  qp, // total precip
42  qpr, // precip rain
43  qps, // precip ice
44  qpg, // graupel
45  // The "numbers" and the "accums" are written/read at checkpoint/restart
46  // number concentrations
47  nc, // cloud droplet number
48  nr, // rain number
49  ni, // cloud ice number
50  ns, // snow number
51  ng, // graupel number
52  // derived vars
53  rain_accum, // rain alone
54  snow_accum, // snow alone
55  graupel_accum, // graupel alone
56  precip_accum, // everything that fell, cloud water and cloud ice included
58  NumVars
59  };
60 }
61 
62 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
64  const amrex::Array4<const amrex::Real>& states,
65  const amrex::Array4<const amrex::Real>& base,
66  const amrex::Array4<amrex::Real>& rho,
67  const amrex::Array4<amrex::Real>& theta,
68  const amrex::Array4<amrex::Real>& qv,
69  const amrex::Array4<amrex::Real>& qc,
70  const amrex::Array4<amrex::Real>& qi,
71  const amrex::Array4<amrex::Real>& qn,
72  const amrex::Array4<amrex::Real>& qt,
73  const amrex::Array4<amrex::Real>& qpr,
74  const amrex::Array4<amrex::Real>& qps,
75  const amrex::Array4<amrex::Real>& qpg,
76  const amrex::Array4<amrex::Real>& qp,
77  const amrex::Array4<amrex::Real>& tabs,
78  const amrex::Array4<amrex::Real>& pres,
79  const amrex::Real rdOcp,
80  const bool use_anelastic_reference_pressure,
81  const int i, const int j, const int k) noexcept
82 {
83  const amrex::Real rho_value = states(i,j,k,Rho_comp);
84  const amrex::Real rho_theta = states(i,j,k,RhoTheta_comp);
85  rho(i,j,k) = rho_value;
86  theta(i,j,k) = rho_theta / rho_value;
87  qv(i,j,k) = amrex::max(amrex::Real(0.0), states(i,j,k,RhoQ1_comp) / rho_value);
88  qc(i,j,k) = amrex::max(amrex::Real(0.0), states(i,j,k,RhoQ2_comp) / rho_value);
89  qi(i,j,k) = amrex::max(amrex::Real(0.0), states(i,j,k,RhoQ3_comp) / rho_value);
90  qn(i,j,k) = qc(i,j,k) + qi(i,j,k);
91  qt(i,j,k) = qv(i,j,k) + qn(i,j,k);
92  qpr(i,j,k) = amrex::max(amrex::Real(0.0), states(i,j,k,RhoQ4_comp) / rho_value);
93  qps(i,j,k) = amrex::max(amrex::Real(0.0), states(i,j,k,RhoQ5_comp) / rho_value);
94  qpg(i,j,k) = amrex::max(amrex::Real(0.0), states(i,j,k,RhoQ6_comp) / rho_value);
95  qp(i,j,k) = qpr(i,j,k) + qps(i,j,k) + qpg(i,j,k);
96 
97  const amrex::Real p0 = use_anelastic_reference_pressure
98  ? base(i,j,k,BaseState::p0_comp) : amrex::Real(0.0);
100  rho_value, rho_theta, qv(i,j,k), rdOcp,
101  use_anelastic_reference_pressure, p0);
102  tabs(i,j,k) = thermo.temperature;
103  // Morrison's native pressure unit is Pa.
104  pres(i,j,k) = thermo.pressure_pa;
105 }
106 
107 // Components of Morrison's sedimentation face fluxes (m_sed), with the state they carry
108 namespace MorrSed {
109  enum {
110  qc = 0, // cloud water, rhoQ2
111  qi, // cloud ice, rhoQ3
112  qr, // rain, rhoQ4
113  qs, // snow, rhoQ5
114  qg, // graupel, rhoQ6
115  nc, // droplet number, rhoQ7
116  ni, // ice number, rhoQ8
117  nr, // rain number, rhoQ9
118  ns, // snow number, rhoQ10
119  ng, // graupel number, rhoQ11
120  NumComps
121  };
122 }
123 
124 class Morrison : public NullMoist {
125 
126  using FabPtr = std::shared_ptr<amrex::MultiFab>;
127 
128 public:
129  // constructor
130  Morrison () {}
131 
132  // destructor
133  virtual ~Morrison () = default;
134 
135  // Set up for first time
136  void
137  Define (SolverChoice& sc) override
138  {
140  m_rdOcp = sc.rdOcp;
141  m_do_cond = (!sc.uses_shoc_family());
143  }
144 
145  // init
146  void
147  Init (const amrex::MultiFab& cons_in,
148  const amrex::BoxArray& grids,
149  const amrex::Geometry& geom,
150  const amrex::Real& dt_advance,
151  std::unique_ptr<amrex::MultiFab>& z_phys_nd,
152  std::unique_ptr<amrex::MultiFab>& detJ_cc) override;
153 
154  // Import minimum dz at this level
155  void
156  Set_dzmin (const amrex::Real dz_min) override
157  {
158  m_dzmin = dz_min;
159  }
160 
161  // Copy state into micro vars
162  void
163  Copy_State_to_Micro (const amrex::MultiFab& cons_in) override;
164 
165  void
166  Copy_State_to_Micro (const amrex::MultiFab& cons_in,
167  const amrex::MultiFab* base_state);
168 
169  void
170  Update_Micro_Vars (amrex::MultiFab& cons_in,
171  const amrex::MultiFab* base_state) override;
172 
173  // Copy state into micro vars
174  void
175  Copy_Micro_to_State (amrex::MultiFab& cons_in) override;
176 
177  void
178  Update_Micro_Vars (amrex::MultiFab& cons_in) override
179  {
180  this->Copy_State_to_Micro(cons_in);
181  }
182 
183  void
184  Update_State_Vars (amrex::MultiFab& cons_in,
185  const amrex::MultiFab& /*z_phys_nd*/) override
186  {
187  this->Copy_Micro_to_State(cons_in);
188  }
189 
190  // wrapper to do all the updating
191  void
192  Advance (const amrex::Real& dt_advance,
193  const SolverChoice& sc) override;
194 
195  amrex::MultiFab*
196  Qmoist_Ptr (const int& varIdx) override
197  {
199  return mic_fab_vars[MicVarMap[varIdx]].get();
200  }
201 
202  int
203  Qmoist_Size () override { return Morrison::m_qmoist_size; }
204 
205  int
207 
208  int
210 
211  void
213  std::vector<int>& a_idx,
214  std::vector<std::string>& a_names) const override
215  {
216  a_idx.clear();
217  a_names.clear();
218 
219  // The ordering here needs to match that in
220  // MicVarMap = {MicVar_Morr::rain_accum, MicVar_Morr::snow_accum,
221  // MicVar_Morr::graupel_accum, MicVar_Morr::precip_accum};
222  //
223  a_idx.push_back(0); a_names.push_back("RainAccum");
224  a_idx.push_back(1); a_names.push_back("SnowAccum");
225  a_idx.push_back(2); a_names.push_back("GraupAccum");
226  a_idx.push_back(3); a_names.push_back("PrecipAccum");
227  }
228 
229  const SedimentationFlux* Sed_Flux () const override { return &m_sed; }
230 
232  Get_Surface_Precip_Accumulation_Ptrs (const int&) const override
233  {
235  sources.total = {mic_fab_vars[MicVar_Morr::precip_accum].get(), rhor / amrex::Real(1000.0)};
236  sources.rain = {mic_fab_vars[MicVar_Morr::rain_accum].get(), rhor / amrex::Real(1000.0)};
237 
238  if (m_moisture_type == MoistureType::Morrison) {
239  sources.snow = {mic_fab_vars[MicVar_Morr::snow_accum].get(), rhor / amrex::Real(1000.0)};
240  sources.graupel = {mic_fab_vars[MicVar_Morr::graupel_accum].get(), rhor / amrex::Real(1000.0)};
241  }
242 
243  return sources;
244  }
245 
246  void
247  GetPlotVarNames (amrex::Vector<std::string>& a_vec) const override;
248 
249  void
250  GetPlotVar (const std::string& a_name,
251  amrex::MultiFab& a_mf) const override;
252 
253  void
254  GetPlotVar (const std::string& a_name,
255  amrex::MultiFab& a_mf,
256  const int /*a_lev*/) const override
257  {
258  GetPlotVar(a_name, a_mf);
259  }
260 
261  // The body of Advance, run on grids in which no column is split between boxes.
262  // Public because nvcc rejects extended __device__ lambdas in private or protected members.
263  void
264  AdvanceColumns (const amrex::Real& dt_advance,
265  const SolverChoice& sc);
266 
267 private:
268  // Number of qmoist variables (rain_accum, snow_accum, graupel_accum, precip_accum)
269  int m_qmoist_size = 4;
270 
271  // Number of qstate variables
273 
274  // Number of qstate variables that are number concentrations
276 
277  // MicVar map (Qmoist indices -> MicVar enum)
278  amrex::Vector<int> MicVarMap;
279 
280  // geometry
281  amrex::Geometry m_geom;
282 
283  // constants
285  bool m_do_cond;
287 
288  // Minimum dz at this level
289  amrex::Real m_dzmin{0.0}; // set by Set_dzmin
290 
291  // Pointer to terrain data
292  amrex::MultiFab* m_z_phys_nd;
293  amrex::MultiFab* m_detJ_cc;
294 
295  // independent variables
296  amrex::Array<FabPtr, MicVar_Morr::NumVars> mic_fab_vars;
297 
298  // Full-column layout of this level's grids (see ERF_MicrophysicsColumns.H)
300 
301  // Sedimentation face fluxes of the most recent Advance, in the order of MorrSed
303 };
304 #endif
constexpr amrex::Real RdoCp
Definition: ERF_Constants.H:57
#define Rho_comp
Definition: ERF_IndexDefines.H:53
#define RhoQ4_comp
Definition: ERF_IndexDefines.H:69
#define RhoTheta_comp
Definition: ERF_IndexDefines.H:54
#define RhoQ2_comp
Definition: ERF_IndexDefines.H:67
#define RhoQ3_comp
Definition: ERF_IndexDefines.H:68
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:66
#define RhoQ6_comp
Definition: ERF_IndexDefines.H:71
#define RhoQ5_comp
Definition: ERF_IndexDefines.H:70
const Real rdOcp
Definition: ERF_InitCustomPert_ABL.H:72
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
Full-column layout for the column microphysics schemes (Morrison, WSM6, WDM6)
Physical constants and tuning parameters used only by the moisture and cloud-physics code.
constexpr amrex::Real rhor
Definition: ERF_MicrophysicsConstants.H:39
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 void morrison_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
Definition: ERF_Morrison.H:63
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_MicrophysicsColumns.H:33
Definition: ERF_Morrison.H:124
SedimentationFlux m_sed
Definition: ERF_Morrison.H:302
virtual ~Morrison()=default
amrex::Geometry m_geom
Definition: ERF_Morrison.H:281
Morrison()
Definition: ERF_Morrison.H:130
void Advance(const amrex::Real &dt_advance, const SolverChoice &sc) override
Definition: ERF_AdvanceMorrison.cpp:179
void GetPlotVarNames(amrex::Vector< std::string > &a_vec) const override
Populate a vector with names of all available Morrison plot variables.
Definition: ERF_Morrison_Plot.cpp:101
void Qmoist_Restart_Vars(const SolverChoice &, std::vector< int > &a_idx, std::vector< std::string > &a_names) const override
Definition: ERF_Morrison.H:212
int Qstate_Moist_Size() override
Definition: ERF_Morrison.H:206
int n_qstate_moist_size
Definition: ERF_Morrison.H:272
void Update_Micro_Vars(amrex::MultiFab &cons_in) override
Definition: ERF_Morrison.H:178
void GetPlotVar(const std::string &a_name, amrex::MultiFab &a_mf, const int) const override
Definition: ERF_Morrison.H:254
void Update_State_Vars(amrex::MultiFab &cons_in, const amrex::MultiFab &) override
Definition: ERF_Morrison.H:184
int Qstate_Moist_NumConc_Size() override
Definition: ERF_Morrison.H:209
void Set_dzmin(const amrex::Real dz_min) override
Definition: ERF_Morrison.H:156
void Copy_State_to_Micro(const amrex::MultiFab &cons_in) override
amrex::Real m_dzmin
Definition: ERF_Morrison.H:289
amrex::Vector< int > MicVarMap
Definition: ERF_Morrison.H:278
const SedimentationFlux * Sed_Flux() const override
The sedimentation face fluxes of the most recent Advance, or null for a scheme that does not sediment...
Definition: ERF_Morrison.H:229
amrex::MultiFab * Qmoist_Ptr(const int &varIdx) override
Definition: ERF_Morrison.H:196
void Copy_State_to_Micro(const amrex::MultiFab &cons_in, const amrex::MultiFab *base_state)
amrex::MultiFab * m_z_phys_nd
Definition: ERF_Morrison.H:292
void Copy_Micro_to_State(amrex::MultiFab &cons_in) override
Definition: ERF_UpdateMorrison.cpp:16
void Define(SolverChoice &sc) override
Definition: ERF_Morrison.H:137
amrex::MultiFab * m_detJ_cc
Definition: ERF_Morrison.H:293
void Update_Micro_Vars(amrex::MultiFab &cons_in, const amrex::MultiFab *base_state) override
void Init(const amrex::MultiFab &cons_in, const amrex::BoxArray &grids, const amrex::Geometry &geom, const amrex::Real &dt_advance, std::unique_ptr< amrex::MultiFab > &z_phys_nd, std::unique_ptr< amrex::MultiFab > &detJ_cc) override
Definition: ERF_InitMorrison.cpp:21
int Qmoist_Size() override
Definition: ERF_Morrison.H:203
void GetPlotVar(const std::string &a_name, amrex::MultiFab &a_mf) const override
MicrophysicsColumns m_columns
Definition: ERF_Morrison.H:299
int m_qmoist_size
Definition: ERF_Morrison.H:269
void AdvanceColumns(const amrex::Real &dt_advance, const SolverChoice &sc)
Definition: ERF_AdvanceMorrison.cpp:213
int n_qstate_moist_numconc_size
Definition: ERF_Morrison.H:275
SurfacePrecipAccumulationSources Get_Surface_Precip_Accumulation_Ptrs(const int &) const override
Definition: ERF_Morrison.H:232
MoistureType m_moisture_type
Definition: ERF_Morrison.H:286
amrex::Real m_rdOcp
Definition: ERF_Morrison.H:284
amrex::Array< FabPtr, MicVar_Morr::NumVars > mic_fab_vars
Definition: ERF_Morrison.H:296
std::shared_ptr< amrex::MultiFab > FabPtr
Definition: ERF_Morrison.H:126
bool m_do_cond
Definition: ERF_Morrison.H:285
Definition: ERF_NullMoist.H:11
void set_anelastic_reference_pressure_mode(const SolverChoice &sc)
Definition: ERF_NullMoist.H:171
@ p0_comp
Definition: ERF_IndexDefines.H:98
@ None
Definition: ERF_LSM_Types.H:6
Definition: ERF_Morrison.H:27
@ qv
Definition: ERF_Morrison.H:37
@ ng
Definition: ERF_Morrison.H:51
@ graupel_accum
Definition: ERF_Morrison.H:55
@ nc
Definition: ERF_Morrison.H:47
@ qpg
Definition: ERF_Morrison.H:44
@ pres
Definition: ERF_Morrison.H:33
@ nr
Definition: ERF_Morrison.H:48
@ qcl
Definition: ERF_Morrison.H:38
@ tabs
Definition: ERF_Morrison.H:32
@ theta
Definition: ERF_Morrison.H:31
@ qp
Definition: ERF_Morrison.H:41
@ ni
Definition: ERF_Morrison.H:49
@ ns
Definition: ERF_Morrison.H:50
@ omega
Definition: ERF_Morrison.H:57
@ qps
Definition: ERF_Morrison.H:43
@ qn
Definition: ERF_Morrison.H:36
@ rho
Definition: ERF_Morrison.H:30
@ qpr
Definition: ERF_Morrison.H:42
@ qci
Definition: ERF_Morrison.H:39
@ NumVars
Definition: ERF_Morrison.H:58
@ rain_accum
Definition: ERF_Morrison.H:53
@ precip_accum
Definition: ERF_Morrison.H:56
@ snow_accum
Definition: ERF_Morrison.H:54
@ qt
Definition: ERF_Morrison.H:35
Definition: ERF_Morrison.H:108
@ NumComps
Definition: ERF_Morrison.H:120
@ nr
Definition: ERF_Morrison.H:117
@ ng
Definition: ERF_Morrison.H:119
@ qg
Definition: ERF_Morrison.H:114
@ qr
Definition: ERF_Morrison.H:112
@ qi
Definition: ERF_Morrison.H:111
@ nc
Definition: ERF_Morrison.H:115
@ qs
Definition: ERF_Morrison.H:113
@ qc
Definition: ERF_Morrison.H:110
@ ns
Definition: ERF_Morrison.H:118
@ ni
Definition: ERF_Morrison.H:116
real(c_double), parameter p0
Definition: ERF_module_model_constants.F90:40
Definition: ERF_MicrophysicsUtils.H:22
amrex::Real pressure_pa
Definition: ERF_MicrophysicsUtils.H:23
amrex::Real temperature
Definition: ERF_MicrophysicsUtils.H:24
Definition: ERF_SedimentationFlux.H:38
Definition: ERF_DataStruct.H:715
MoistureType moisture_type
Moisture or microphysics model.
Definition: ERF_DataStruct.H:2942
amrex::Real rdOcp
Ratio of dry-air gas constant to c_p.
Definition: ERF_DataStruct.H:2738
bool uses_shoc_family() const noexcept
Query whether any SHOC-family PBL scheme is active.
Definition: ERF_DataStruct.H:2864
Definition: ERF_SurfacePrecipitation.H:34
SurfacePrecipAccumulationSource rain
Definition: ERF_SurfacePrecipitation.H:36
SurfacePrecipAccumulationSource snow
Definition: ERF_SurfacePrecipitation.H:37
SurfacePrecipAccumulationSource total
Definition: ERF_SurfacePrecipitation.H:35
SurfacePrecipAccumulationSource graupel
Definition: ERF_SurfacePrecipitation.H:38