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"
25 
26 namespace MicVar_Morr {
27  enum {
28  // independent variables
29  rho=0, // density
30  theta, // liquid/ice water potential temperature
31  tabs, // temperature
32  pres, // pressure
33  // non-precipitating vars
34  qt, // total cloud
35  qn, // cloud condensate (liquid + ice)
36  qv, // cloud vapor
37  qcl, // cloud water
38  qci, // cloud ice
39  // precipitating vars
40  qp, // total precip
41  qpr, // precip rain
42  qps, // precip ice
43  qpg, // graupel
44  // The "numbers" and the "accums" are written/read at checkpoint/restart
45  // number concentrations
46  nc, // cloud droplet number
47  nr, // rain number
48  ni, // cloud ice number
49  ns, // snow number
50  ng, // graupel number
51  // derived vars
56  NumVars
57  };
58 }
59 
60 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
62  const amrex::Array4<const amrex::Real>& states,
63  const amrex::Array4<const amrex::Real>& base,
64  const amrex::Array4<amrex::Real>& rho,
65  const amrex::Array4<amrex::Real>& theta,
66  const amrex::Array4<amrex::Real>& qv,
67  const amrex::Array4<amrex::Real>& qc,
68  const amrex::Array4<amrex::Real>& qi,
69  const amrex::Array4<amrex::Real>& qn,
70  const amrex::Array4<amrex::Real>& qt,
71  const amrex::Array4<amrex::Real>& qpr,
72  const amrex::Array4<amrex::Real>& qps,
73  const amrex::Array4<amrex::Real>& qpg,
74  const amrex::Array4<amrex::Real>& qp,
75  const amrex::Array4<amrex::Real>& tabs,
76  const amrex::Array4<amrex::Real>& pres,
77  const amrex::Real rdOcp,
78  const bool use_anelastic_reference_pressure,
79  const int i, const int j, const int k) noexcept
80 {
81  const amrex::Real rho_value = states(i,j,k,Rho_comp);
82  const amrex::Real rho_theta = states(i,j,k,RhoTheta_comp);
83  rho(i,j,k) = rho_value;
84  theta(i,j,k) = rho_theta / rho_value;
85  qv(i,j,k) = amrex::max(amrex::Real(0.0), states(i,j,k,RhoQ1_comp) / rho_value);
86  qc(i,j,k) = amrex::max(amrex::Real(0.0), states(i,j,k,RhoQ2_comp) / rho_value);
87  qi(i,j,k) = amrex::max(amrex::Real(0.0), states(i,j,k,RhoQ3_comp) / rho_value);
88  qn(i,j,k) = qc(i,j,k) + qi(i,j,k);
89  qt(i,j,k) = qv(i,j,k) + qn(i,j,k);
90  qpr(i,j,k) = amrex::max(amrex::Real(0.0), states(i,j,k,RhoQ4_comp) / rho_value);
91  qps(i,j,k) = amrex::max(amrex::Real(0.0), states(i,j,k,RhoQ5_comp) / rho_value);
92  qpg(i,j,k) = amrex::max(amrex::Real(0.0), states(i,j,k,RhoQ6_comp) / rho_value);
93  qp(i,j,k) = qpr(i,j,k) + qps(i,j,k) + qpg(i,j,k);
94 
95  const amrex::Real p0 = use_anelastic_reference_pressure
96  ? base(i,j,k,BaseState::p0_comp) : amrex::Real(0.0);
98  rho_value, rho_theta, qv(i,j,k), rdOcp,
99  use_anelastic_reference_pressure, p0);
100  tabs(i,j,k) = thermo.temperature;
101  // Morrison's native pressure unit is Pa.
102  pres(i,j,k) = thermo.pressure_pa;
103 }
104 
105 class Morrison : public NullMoist {
106 
107  using FabPtr = std::shared_ptr<amrex::MultiFab>;
108 
109 public:
110  // constructor
111  Morrison () {}
112 
113  // destructor
114  virtual ~Morrison () = default;
115 
116  // Set up for first time
117  void
118  Define (SolverChoice& sc) override
119  {
121  m_rdOcp = sc.rdOcp;
122  m_do_cond = (!sc.uses_shoc_family());
124  }
125 
126  // init
127  void
128  Init (const amrex::MultiFab& cons_in,
129  const amrex::BoxArray& grids,
130  const amrex::Geometry& geom,
131  const amrex::Real& dt_advance,
132  std::unique_ptr<amrex::MultiFab>& z_phys_nd,
133  std::unique_ptr<amrex::MultiFab>& detJ_cc) override;
134 
135  // Import minimum dz at this level
136  void
137  Set_dzmin (const amrex::Real dz_min) override
138  {
139  m_dzmin = dz_min;
140  }
141 
142  // Copy state into micro vars
143  void
144  Copy_State_to_Micro (const amrex::MultiFab& cons_in) override;
145 
146  void
147  Copy_State_to_Micro (const amrex::MultiFab& cons_in,
148  const amrex::MultiFab* base_state);
149 
150  void
151  Update_Micro_Vars (amrex::MultiFab& cons_in,
152  const amrex::MultiFab* base_state) override;
153 
154  // Copy state into micro vars
155  void
156  Copy_Micro_to_State (amrex::MultiFab& cons_in) override;
157 
158  void
159  Update_Micro_Vars (amrex::MultiFab& cons_in) override
160  {
161  this->Copy_State_to_Micro(cons_in);
162  }
163 
164  void
165  Update_State_Vars (amrex::MultiFab& cons_in,
166  const amrex::MultiFab& /*z_phys_nd*/) override
167  {
168  this->Copy_Micro_to_State(cons_in);
169  }
170 
171  // wrapper to do all the updating
172  void
173  Advance (const amrex::Real& dt_advance,
174  const SolverChoice& sc) override;
175 
176  amrex::MultiFab*
177  Qmoist_Ptr (const int& varIdx) override
178  {
180  return mic_fab_vars[MicVarMap[varIdx]].get();
181  }
182 
183  int
184  Qmoist_Size () override { return Morrison::m_qmoist_size; }
185 
186  int
188 
189  int
191 
192  void
194  std::vector<int>& a_idx,
195  std::vector<std::string>& a_names) const override
196  {
197  a_idx.clear();
198  a_names.clear();
199 
200  // The ordering here needs to match that in
201  // MicVarMap = {MicVar_Morr::rain_accum, MicVar_Morr::snow_accum, MicVar_Morr::graup_accum};
202  //
203  a_idx.push_back(0); a_names.push_back("RainAccum");
204  a_idx.push_back(1); a_names.push_back("SnowAccum");
205  a_idx.push_back(2); a_names.push_back("GraupAccum");
206  }
207 
209  Get_Surface_Precip_Accumulation_Ptrs (const int&) const override
210  {
212  sources.total = {mic_fab_vars[MicVar_Morr::rain_accum].get(), rhor / amrex::Real(1000.0)};
213 
214  if (m_moisture_type == MoistureType::Morrison) {
215  sources.snow = {mic_fab_vars[MicVar_Morr::snow_accum].get(), rhor / amrex::Real(1000.0)};
216  sources.graupel = {mic_fab_vars[MicVar_Morr::graup_accum].get(), rhor / amrex::Real(1000.0)};
217  }
218 
219  return sources;
220  }
221 
222  void
223  GetPlotVarNames (amrex::Vector<std::string>& a_vec) const override;
224 
225  void
226  GetPlotVar (const std::string& a_name,
227  amrex::MultiFab& a_mf) const override;
228 
229  void
230  GetPlotVar (const std::string& a_name,
231  amrex::MultiFab& a_mf,
232  const int /*a_lev*/) const override
233  {
234  GetPlotVar(a_name, a_mf);
235  }
236 
237 private:
238  // Number of qmoist variables (rain_accum, snow_accum, graup_accum)
239  int m_qmoist_size = 3;
240 
241  // Number of qstate variables
243 
244  // Number of qstate variables that are number concentrations
246 
247  // MicVar map (Qmoist indices -> MicVar enum)
248  amrex::Vector<int> MicVarMap;
249 
250  // geometry
251  amrex::Geometry m_geom;
252 
253  // constants
255  bool m_do_cond;
256  MoistureType m_moisture_type = MoistureType::None;
257 
258  // Minimum dz at this level
259  amrex::Real m_dzmin{0.0}; // set by Set_dzmin
260 
261  // Pointer to terrain data
262  amrex::MultiFab* m_z_phys_nd;
263  amrex::MultiFab* m_detJ_cc;
264 
265  // independent variables
266  amrex::Array<FabPtr, MicVar_Morr::NumVars> mic_fab_vars;
267 };
268 #endif
constexpr amrex::Real RdoCp
Definition: ERF_Constants.H:41
#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
const Real rdOcp
Definition: ERF_InitCustomPert_ABL.H:72
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
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:61
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_Morrison.H:105
virtual ~Morrison()=default
amrex::Geometry m_geom
Definition: ERF_Morrison.H:251
Morrison()
Definition: ERF_Morrison.H:111
void Advance(const amrex::Real &dt_advance, const SolverChoice &sc) override
Definition: ERF_AdvanceMorrison.cpp:177
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:193
int Qstate_Moist_Size() override
Definition: ERF_Morrison.H:187
int n_qstate_moist_size
Definition: ERF_Morrison.H:242
void Update_Micro_Vars(amrex::MultiFab &cons_in) override
Definition: ERF_Morrison.H:159
void GetPlotVar(const std::string &a_name, amrex::MultiFab &a_mf, const int) const override
Definition: ERF_Morrison.H:230
void Update_State_Vars(amrex::MultiFab &cons_in, const amrex::MultiFab &) override
Definition: ERF_Morrison.H:165
int Qstate_Moist_NumConc_Size() override
Definition: ERF_Morrison.H:190
void Set_dzmin(const amrex::Real dz_min) override
Definition: ERF_Morrison.H:137
void Copy_State_to_Micro(const amrex::MultiFab &cons_in) override
amrex::Real m_dzmin
Definition: ERF_Morrison.H:259
amrex::Vector< int > MicVarMap
Definition: ERF_Morrison.H:248
amrex::MultiFab * Qmoist_Ptr(const int &varIdx) override
Definition: ERF_Morrison.H:177
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:262
void Copy_Micro_to_State(amrex::MultiFab &cons_in) override
Definition: ERF_UpdateMorrison.cpp:16
void Define(SolverChoice &sc) override
Definition: ERF_Morrison.H:118
amrex::MultiFab * m_detJ_cc
Definition: ERF_Morrison.H:263
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:184
void GetPlotVar(const std::string &a_name, amrex::MultiFab &a_mf) const override
int m_qmoist_size
Definition: ERF_Morrison.H:239
int n_qstate_moist_numconc_size
Definition: ERF_Morrison.H:245
SurfacePrecipAccumulationSources Get_Surface_Precip_Accumulation_Ptrs(const int &) const override
Definition: ERF_Morrison.H:209
MoistureType m_moisture_type
Definition: ERF_Morrison.H:256
amrex::Real m_rdOcp
Definition: ERF_Morrison.H:254
amrex::Array< FabPtr, MicVar_Morr::NumVars > mic_fab_vars
Definition: ERF_Morrison.H:266
std::shared_ptr< amrex::MultiFab > FabPtr
Definition: ERF_Morrison.H:107
bool m_do_cond
Definition: ERF_Morrison.H:255
Definition: ERF_NullMoist.H:10
void set_anelastic_reference_pressure_mode(const SolverChoice &sc)
Definition: ERF_NullMoist.H:155
@ p0_comp
Definition: ERF_IndexDefines.H:77
Definition: ERF_Morrison.H:26
@ qv
Definition: ERF_Morrison.H:36
@ ng
Definition: ERF_Morrison.H:50
@ nc
Definition: ERF_Morrison.H:46
@ qpg
Definition: ERF_Morrison.H:43
@ pres
Definition: ERF_Morrison.H:32
@ nr
Definition: ERF_Morrison.H:47
@ qcl
Definition: ERF_Morrison.H:37
@ tabs
Definition: ERF_Morrison.H:31
@ theta
Definition: ERF_Morrison.H:30
@ qp
Definition: ERF_Morrison.H:40
@ ni
Definition: ERF_Morrison.H:48
@ ns
Definition: ERF_Morrison.H:49
@ omega
Definition: ERF_Morrison.H:55
@ qps
Definition: ERF_Morrison.H:42
@ qn
Definition: ERF_Morrison.H:35
@ graup_accum
Definition: ERF_Morrison.H:54
@ rho
Definition: ERF_Morrison.H:29
@ qpr
Definition: ERF_Morrison.H:41
@ qci
Definition: ERF_Morrison.H:38
@ NumVars
Definition: ERF_Morrison.H:56
@ rain_accum
Definition: ERF_Morrison.H:52
@ snow_accum
Definition: ERF_Morrison.H:53
@ qt
Definition: ERF_Morrison.H:34
@ qc
Definition: ERF_SatAdj.H:42
@ qi
Definition: ERF_WDM6.H:28
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_DataStruct.H:662
MoistureType moisture_type
Moisture or microphysics model.
Definition: ERF_DataStruct.H:2237
amrex::Real rdOcp
Ratio of dry-air gas constant to c_p.
Definition: ERF_DataStruct.H:2062
bool uses_shoc_family() const noexcept
Query whether any SHOC-family PBL scheme is active.
Definition: ERF_DataStruct.H:2177
Definition: ERF_SurfacePrecipitation.H:34
SurfacePrecipAccumulationSource snow
Definition: ERF_SurfacePrecipitation.H:37
SurfacePrecipAccumulationSource total
Definition: ERF_SurfacePrecipitation.H:35
SurfacePrecipAccumulationSource graupel
Definition: ERF_SurfacePrecipitation.H:38