ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_SatAdj.H
Go to the documentation of this file.
1 #ifndef ERF_SATADJ_H
2 #define ERF_SATADJ_H
3 
4 /*
5  * Implementation saturation adjustment microphysics model
6  * The model transports qv and qc and does Newton iterations
7  * to complete condensation/evaporation.
8  */
9 
10 #include <string>
11 #include <vector>
12 #include <memory>
13 
14 #include <AMReX_FArrayBox.H>
15 #include <AMReX_Geometry.H>
16 #include <AMReX_MultiFabUtil.H>
17 #include <AMReX_GpuContainers.H>
18 
19 #include "ERF_EOS.H"
20 #include "ERF_Constants.H"
21 #include "ERF_MicrophysicsUtils.H"
22 #include "ERF_IndexDefines.H"
23 #include "ERF_DataStruct.H"
24 #include "ERF_NullMoist.H"
25 #include "ERF_TileNoZ.H"
26 
27 namespace MicVar_SatAdj {
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  qv, // cloud vapor
36  qc, // cloud water
37  NumVars
38  };
39 }
40 
41 class SatAdj : public NullMoist {
42 
43  using FabPtr = std::shared_ptr<amrex::MultiFab>;
44 
45 public:
46  // constructor
47  SatAdj () {}
48 
49  // destructor
50  virtual ~SatAdj () = default;
51 
52  // cloud physics
53  void AdvanceSatAdj (const SolverChoice& /*solverChoice*/);
54 
55  // Set up for first time
56  void
57  Define (SolverChoice& sc) override
58  {
59  m_fac_cond = lcond / sc.c_p;
60  m_rdOcp = sc.rdOcp;
61  }
62 
63  // init
64  void
65  Init (const amrex::MultiFab& cons_in,
66  const amrex::BoxArray& /*grids*/,
67  const amrex::Geometry& geom,
68  const amrex::Real& dt_advance,
69  std::unique_ptr<amrex::MultiFab>& /*z_phys_nd*/,
70  std::unique_ptr<amrex::MultiFab>& /*detJ_cc*/) override;
71 
72  // Copy state into micro vars
73  void
74  Copy_State_to_Micro (const amrex::MultiFab& cons_in) override;
75 
76  // Copy state into micro vars
77  void
78  Copy_Micro_to_State (amrex::MultiFab& cons_in) override;
79 
80  // update micro vars
81  void
82  Update_Micro_Vars (amrex::MultiFab& cons_in) override
83  {
84  this->Copy_State_to_Micro(cons_in);
85  }
86 
87  // update state vars
88  void
89  Update_State_Vars (amrex::MultiFab& cons_in) override
90  {
91  this->Copy_Micro_to_State(cons_in);
92  }
93 
94  // wrapper to advance micro vars
95  void
96  Advance (const amrex::Real& dt_advance,
97  const SolverChoice& solverChoice) override
98  {
99  dt = dt_advance;
100 
101  this->AdvanceSatAdj(solverChoice);
102  }
103 
104  amrex::MultiFab*
105  Qmoist_Ptr (const int& varIdx) override
106  {
107  AMREX_ALWAYS_ASSERT(varIdx < m_qmoist_size);
108  return mic_fab_vars[MicVarMap[varIdx]].get();
109  }
110 
111  int
112  Qmoist_Size () override { return SatAdj::m_qmoist_size; }
113 
114  int
115  Qstate_Size () override { return SatAdj::m_qstate_size; }
116 
117  void
119  std::vector<int>& a_idx,
120  std::vector<std::string>& a_names) const override
121  {
122  a_idx.clear();
123  a_names.clear();
124  }
125 
126  AMREX_GPU_HOST_DEVICE
127  AMREX_FORCE_INLINE
128  static amrex::Real
129  NewtonIterSat (int& i, int& j, int& k,
130  const amrex::Real& fac_cond,
131  const amrex::Array4<amrex::Real>& tabs_array,
132  const amrex::Array4<amrex::Real>& pres_array,
133  const amrex::Array4<amrex::Real>& qv_array,
134  const amrex::Array4<amrex::Real>& qc_array)
135  {
136  // Solution tolerance
137  amrex::Real tol = 1.0e-8;
138 
139  // Saturation moisture fractions
140  amrex::Real qsat, dqsat;
141 
142  // Newton iteration vars
143  int niter;
144  amrex::Real fff, dfff;
145  amrex::Real dtabs, delta_qv;
146 
147  // Initial guess for temperature & pressure
148  amrex::Real tabs = tabs_array(i,j,k);
149  amrex::Real pres = pres_array(i,j,k);
150 
151  niter = 0;
152  dtabs = 1;
153 
154  //==================================================
155  // Newton iteration to qv=qsat (cloud phase only)
156  //==================================================
157  do {
158  // Saturation moisture fractions
159  erf_qsatw(tabs, pres, qsat);
160  erf_dtqsatw(tabs, pres, dqsat);
161 
162  // Function for root finding:
163  // 0 = -T_new + T_old + L_eff/C_p * (qv - qsat)
164  fff = -tabs + tabs_array(i,j,k) + fac_cond*(qv_array(i,j,k) - qsat);
165 
166  // Derivative of function (T_new iterated on)
167  dfff = -1.0 - fac_cond*dqsat;
168 
169  // Update the temperature
170  dtabs = -fff/dfff;
171  tabs += dtabs;
172 
173  // Update iteration
174  niter = niter+1;
175  } while(std::abs(dtabs) > tol && niter < 20);
176 
177  // Update qsat from last iteration (dq = dq/dt * dt)
178  qsat += dqsat*dtabs;
179 
180  // Changes in each component
181  delta_qv = qv_array(i,j,k) - qsat;
182 
183  // Partition the change in non-precipitating q
184  qv_array(i,j,k) = qsat;
185  qc_array(i,j,k) += delta_qv;
186 
187  // Return to temperature
188  return tabs;
189  }
190 
191 private:
192  // Number of qmoist variables (qv, qc)
193  int m_qmoist_size = 2;
194 
195  // Number of qstate variables
196  int m_qstate_size = 2;
197 
198  // MicVar map (Qmoist indices -> MicVar enum)
199  amrex::Vector<int> MicVarMap;
200 
201  // geometry
202  amrex::Geometry m_geom;
203 
204  // timestep
205  amrex::Real dt;
206 
207  // constants
208  amrex::Real m_fac_cond;
209  amrex::Real m_rdOcp ;
210 
211  // independent variables
212  amrex::Array<FabPtr, MicVar_SatAdj::NumVars> mic_fab_vars;
213 };
214 #endif
constexpr amrex::Real lcond
Definition: ERF_Constants.H:66
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void erf_dtqsatw(amrex::Real t, amrex::Real p, amrex::Real &dtqsatw)
Definition: ERF_MicrophysicsUtils.H:170
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void erf_qsatw(amrex::Real t, amrex::Real p, amrex::Real &qsatw)
Definition: ERF_MicrophysicsUtils.H:158
Definition: ERF_NullMoist.H:8
Definition: ERF_SatAdj.H:41
amrex::Real m_fac_cond
Definition: ERF_SatAdj.H:208
int Qmoist_Size() override
Definition: ERF_SatAdj.H:112
void Update_Micro_Vars(amrex::MultiFab &cons_in) override
Definition: ERF_SatAdj.H:82
amrex::Geometry m_geom
Definition: ERF_SatAdj.H:202
void Qmoist_Restart_Vars(const SolverChoice &, std::vector< int > &a_idx, std::vector< std::string > &a_names) const override
Definition: ERF_SatAdj.H:118
amrex::Array< FabPtr, MicVar_SatAdj::NumVars > mic_fab_vars
Definition: ERF_SatAdj.H:212
amrex::Real m_rdOcp
Definition: ERF_SatAdj.H:209
SatAdj()
Definition: ERF_SatAdj.H:47
virtual ~SatAdj()=default
amrex::MultiFab * Qmoist_Ptr(const int &varIdx) override
Definition: ERF_SatAdj.H:105
int Qstate_Size() override
Definition: ERF_SatAdj.H:115
AMREX_GPU_HOST_DEVICE static AMREX_FORCE_INLINE amrex::Real NewtonIterSat(int &i, int &j, int &k, const amrex::Real &fac_cond, const amrex::Array4< amrex::Real > &tabs_array, const amrex::Array4< amrex::Real > &pres_array, const amrex::Array4< amrex::Real > &qv_array, const amrex::Array4< amrex::Real > &qc_array)
Definition: ERF_SatAdj.H:129
int m_qstate_size
Definition: ERF_SatAdj.H:196
std::shared_ptr< amrex::MultiFab > FabPtr
Definition: ERF_SatAdj.H:43
void Update_State_Vars(amrex::MultiFab &cons_in) override
Definition: ERF_SatAdj.H:89
void Copy_Micro_to_State(amrex::MultiFab &cons_in) override
Definition: ERF_UpdateSatAdj.cpp:12
void Init(const amrex::MultiFab &cons_in, const amrex::BoxArray &, const amrex::Geometry &geom, const amrex::Real &dt_advance, std::unique_ptr< amrex::MultiFab > &, std::unique_ptr< amrex::MultiFab > &) override
Definition: ERF_InitSatAdj.cpp:17
void Advance(const amrex::Real &dt_advance, const SolverChoice &solverChoice) override
Definition: ERF_SatAdj.H:96
amrex::Vector< int > MicVarMap
Definition: ERF_SatAdj.H:199
int m_qmoist_size
Definition: ERF_SatAdj.H:193
void AdvanceSatAdj(const SolverChoice &)
Definition: ERF_SatAdj.cpp:8
amrex::Real dt
Definition: ERF_SatAdj.H:205
void Define(SolverChoice &sc) override
Definition: ERF_SatAdj.H:57
void Copy_State_to_Micro(const amrex::MultiFab &cons_in) override
Definition: ERF_InitSatAdj.cpp:43
Definition: ERF_SatAdj.H:27
@ theta
Definition: ERF_SatAdj.H:31
@ rho
Definition: ERF_SatAdj.H:30
@ pres
Definition: ERF_SatAdj.H:33
@ NumVars
Definition: ERF_SatAdj.H:37
@ qv
Definition: ERF_SatAdj.H:35
@ tabs
Definition: ERF_SatAdj.H:32
@ qc
Definition: ERF_SatAdj.H:36
Definition: ERF_DataStruct.H:82
amrex::Real rdOcp
Definition: ERF_DataStruct.H:619
amrex::Real c_p
Definition: ERF_DataStruct.H:618