1 #ifndef SUPERDROPLETSMOIST_H
2 #define SUPERDROPLETSMOIST_H
4 #ifdef ERF_USE_PARTICLES
8 #include <AMReX_Enum.H>
9 #include <AMReX_Geometry.H>
10 #include <AMReX_iMultiFab.H>
11 #include <AMReX_MultiFabUtil.H>
32 namespace MicVar_SD_Species {
43 namespace MicVar_SD_Aerosols {
50 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
51 static int s_qt_idx (
const int a_i )
59 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
60 static int s_qv_idx (
const int a_i )
65 + MicVar_SD_Species::q_v;
68 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
69 static int s_qc_idx (
const int a_i )
74 + MicVar_SD_Species::q_c;
77 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
78 static int s_sr_idx (
const int a_i )
83 + MicVar_SD_Species::sr;
86 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
87 static int s_accum_idx (
const int a_i )
92 + MicVar_SD_Species::accum;
95 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
96 static int a_accum_idx (
const int a_ns,
103 + MicVar_SD_Aerosols::accum;
113 one_d_z, two_d_xz, two_d_yz, three_d
116 class SuperDropletsMoist :
public NullMoistLagrangian {
118 using FabPtr = std::shared_ptr<amrex::MultiFab>;
119 using MFPtr = std::unique_ptr<amrex::MultiFab>;
120 using BCTypeArr = amrex::GpuArray<ERF_BC, AMREX_SPACEDIM*2>;
128 m_qstate_moist_size = 3;
129 m_qstate_nonmoist_size = -1;
130 m_name =
"super_droplets_moisture";
138 virtual ~SuperDropletsMoist() =
default;
144 virtual void Init (
const amrex::MultiFab&,
145 const amrex::BoxArray&,
146 const amrex::Geometry&,
152 virtual void InitParticles (
const int, MFPtr& )
override;
155 virtual void RestartParticles ( amrex::ParGDBBase*,
const std::string& )
override;
158 virtual void FinishInit(
const int&,
160 const amrex::Vector<MFPtr>&)
override;
164 amrex::Abort(
"Do not use this advance() for Lagrangian microphysics.");
168 void SetCurrentLevel (
const int& a_lev)
override { m_current_lev = a_lev; }
171 int getDiagnosticsInterval ()
const override {
return m_diagnostics_iter; }
174 void EnsureMicFabVars (
const int a_lev,
const amrex::MultiFab& a_cons_vars);
177 amrex::iMultiFab buildFineMask (
const int a_lev)
const;
180 void InitLevel (
const int a_lev,
const amrex::MultiFab& a_cons_vars)
override;
191 const int& iteration,
193 amrex::Vector<amrex::Vector<amrex::MultiFab>>& cons_vars,
194 const amrex::Vector<MFPtr>& mf_array,
195 const BCTypeArr& bc_arr)
override;
202 virtual void Update_Micro_Vars (amrex::MultiFab& a_cons_vars)
override;
208 virtual void Update_State_Vars (amrex::MultiFab& a_cons_vars,
209 const amrex::MultiFab& a_z_phys_nd)
override;
212 virtual void AverageDownMicroVars (
const int finest_level)
override;
217 virtual void Copy_State_to_Micro (
const amrex::MultiFab& a_state)
override;
222 virtual void Copy_Micro_to_State (amrex::MultiFab& a_state)
override;
225 inline virtual amrex::MultiFab* Qmoist_Ptr (
const int& a_idx)
override
228 const int lev = m_current_lev;
229 if (lev < 0 || lev >=
static_cast<int>(m_mic_fab_vars.size()) ||
230 m_mic_var_map[a_idx] < 0 || m_mic_var_map[a_idx] >=
static_cast<int>(m_mic_fab_vars[lev].size())) {
233 return m_mic_fab_vars[lev][m_mic_var_map[a_idx]].get();
237 inline virtual int Qmoist_Size ()
override
239 return m_qmoist_size;
244 Get_Surface_Precip_Accumulation_Ptrs (
const int& a_lev)
const override
247 if (a_lev >= 0 && a_lev <
static_cast<int>(m_mic_fab_vars.size())) {
255 inline virtual int Qstate_Moist_Size ()
override
257 return m_qstate_moist_size;
261 inline virtual int Qstate_Moist_NumConc_Size ()
override
263 return m_qstate_moist_numconc_size;
267 inline virtual int Qstate_NonMoist_Size ()
override
270 return m_qstate_nonmoist_size;
274 inline virtual ERFPC* getParticleContainer()
override
276 return m_super_droplets;
279 inline virtual const std::string& getName()
const override
285 virtual void computeQcQrWater (
const amrex::MultiFab& a_z_phys_nd);
288 virtual void computeQcSpecies (
const amrex::MultiFab& a_z_phys_nd)
290 for (
int is = 1; is <
m_num_species; is++) { computeQcSpecies(is, a_z_phys_nd); }
294 virtual void computeQcSpecies (
const int a_i,
const amrex::MultiFab& a_z_phys_nd);
297 virtual void computeQc (
const int a_i,
const amrex::MultiFab& a_z_phys_nd)
299 if (a_i == m_idx_w) { computeQcQrWater(a_z_phys_nd); }
300 else { computeQcSpecies(a_i, a_z_phys_nd); }
304 virtual void computeQtWater ();
307 virtual void computeQtSpecies ()
309 for (
int is = 1; is <
m_num_species; is++) { computeQtSpecies(is); }
313 virtual void computeQtSpecies (
const int a_i);
316 virtual void computeQt (
const int a_i)
318 if (a_i == m_idx_w) { computeQtWater(); }
319 else { computeQtSpecies(a_i); }
323 virtual void rainAccumulation (
const amrex::MultiFab& a_z_phys_nd);
326 virtual void speciesAccumulation (
const amrex::MultiFab& a_z_phys_nd);
329 virtual void aerosolAccumulation (
const amrex::MultiFab& a_z_phys_nd);
332 void densityToRatio ( amrex::MultiFab&,
const int a_comp = 0 );
334 void ratioToDensity ( amrex::MultiFab&,
const int a_comp = 0 );
341 virtual void phaseChange (
const amrex::Real& a_dt,
342 const amrex::Vector<MFPtr>& a_z,
345 virtual void GetPlotVarNames (amrex::Vector<std::string>& a_names)
const override
348 a_names.push_back(
"qv_"+amrex::getEnumNameString(
m_species[v]));
349 a_names.push_back(
"qc_"+amrex::getEnumNameString(
m_species[v]));
350 a_names.push_back(
"qt_"+amrex::getEnumNameString(
m_species[v]));
351 a_names.push_back(
"sat_ratio_"+amrex::getEnumNameString(
m_species[v]));
352 a_names.push_back(
"accum_"+amrex::getEnumNameString(
m_species[v]));
354 for (
int v = 0; v < m_num_aerosols; v++) {
355 a_names.push_back(
"accum_"+amrex::getEnumNameString(m_aerosols[v]));
359 virtual void GetPlotVar (
const std::string& ,
360 amrex::MultiFab& )
const override
362 amrex::Abort(
"SuperDropletsMoist::GetPlotVar() requires a level argument");
365 virtual void GetPlotVar (
const std::string& a_name,
366 amrex::MultiFab& a_mf,
367 const int a_lev)
const override
370 AMREX_ASSERT(a_mf.nComp() >= 1);
372 const int lev = a_lev;
373 if (lev < 0 || lev >=
static_cast<int>(m_mic_fab_vars.size()) ||
374 m_mic_fab_vars[lev].empty()) {
378 const auto& lev_vec = m_mic_fab_vars[lev];
381 auto try_copy = [&](
const std::string& prefix,
int idx) ->
bool {
382 if (a_name == prefix) {
383 if (
idx >= 0 &&
idx <
static_cast<int>(lev_vec.size()) && lev_vec[
idx] &&
384 lev_vec[
idx]->boxArray() == a_mf.boxArray() &&
385 lev_vec[
idx]->DistributionMap() == a_mf.DistributionMap()) {
386 amrex::MultiFab::Copy(a_mf, *lev_vec[
idx],
387 0, 0, 1, amrex::IntVect::TheZeroVector());
396 std::string sp_name = amrex::getEnumNameString(
m_species[v]);
397 if (try_copy(
"qv_" + sp_name, s_qv_idx(v)) ||
398 try_copy(
"qc_" + sp_name, s_qc_idx(v)) ||
399 try_copy(
"qt_" + sp_name, s_qt_idx(v)) ||
400 try_copy(
"sat_ratio_" + sp_name, s_sr_idx(v)) ||
401 try_copy(
"accum_" + sp_name, s_accum_idx(v))) {
407 for (
int v = 0; v < m_num_aerosols; v++) {
408 std::string ae_name = amrex::getEnumNameString(m_aerosols[v]);
409 if (try_copy(
"accum_" + ae_name, a_accum_idx(
m_num_species, v))) {
return; }
412 amrex::Abort(
"SuperDropletsMoist::GetPlotVar() called with invalid name");
415 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
416 int q_qv_idx (
const int a_i )
419 return RhoQ1_comp + m_qstate_moist_size + 2*(a_i-1) + 0;
422 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
423 int q_qc_idx (
const int a_i )
426 return RhoQ1_comp + m_qstate_moist_size + 2*(a_i-1) + 1;
431 bool m_flag_phase_change;
432 bool m_flag_advection;
433 bool m_flag_coalescence;
440 bool m_init_phase_change;
444 int m_diagnostics_iter;
447 SDMoistInit m_init_type;
452 amrex::Geometry m_geom;
456 int m_qstate_moist_size;
459 int m_qstate_moist_numconc_size = 0;
462 int m_qstate_nonmoist_size;
465 amrex::Vector<int> m_mic_var_map;
468 amrex::Vector<amrex::Vector<FabPtr>> m_mic_fab_vars;
471 mutable int m_current_lev = 0;
478 std::vector<Species::Name> m_aerosols;
482 int m_num_substeps_phase_change;
485 bool m_kinematic_mode;
488 SDMSimulationDim m_dimensionality;
491 bool m_recycle_particles;
499 SuperDropletPC* m_super_droplets;
502 virtual void readInputs();
AMREX_ENUM(InitType, None, Input_Sounding, NCFile, WRFInput, Metgrid, Uniform, ConstantDensity, ConstantDensityLinearTheta, Isentropic, MoistBaseState, HindCast)
Initial-condition source used to populate the ERF state.
#define RhoQ1_comp
Definition: ERF_IndexDefines.H:42
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
rho
Definition: ERF_InitCustomPert_Bubble.H:107
int m_num_species
Definition: ERF_InitCustomPert_MultiSpeciesBubble.H:28
std::vector< std::string > m_species
Definition: ERF_InitCustomPert_MultiSpeciesBubble.H:27
Real q_t
Definition: ERF_InitCustomPert_SquallLine.H:24
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int idx(int i, int j, int k, int nx, int ny)
Definition: ERF_InitForEnsemble.cpp:365
Contains the Lagrangian moisture model base class.
amrex::Real Real
Definition: ERF_ShocInterface.H:19
virtual void Update_Micro_Vars(amrex::MultiFab &)
Definition: ERF_NullMoist.H:35
@ NumVars
Definition: ERF_NOAHMP_Fields.H:109
@ theta
Definition: ERF_SLM.H:20
@ rain_accum
Definition: ERF_Kessler.H:35
Definition: ERF_DataStruct.H:241
Definition: ERF_SurfacePrecipitation.H:21
SurfacePrecipAccumulationSource rain
Definition: ERF_SurfacePrecipitation.H:23