ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_MaterialProperties.H
Go to the documentation of this file.
1 #ifndef MATERIALPROPERTIES_H
2 #define MATERIALPROPERTIES_H
3 
4 #include <limits>
5 
6 #include <AMReX_Enum.H>
7 #include <AMReX_REAL.H>
8 #include <AMReX_Gpu.H>
9 #include <AMReX_MultiFab.H>
10 #include "ERF_NumericalConstants.H"
12 
13 /*! Materials */
14 namespace Species
15 {
16  AMREX_ENUM(Name,
17  H2O,
18  ice,
19  NaCl,
20  NH42SO4,
21  NH4HSO4,
22  soil,
23  water, // same as H2O, to test multispecies SDM
24  agua, // same as H2O, to test multispecies SDM
25  none
26  );
27 }
28 
29 /*! Functions for computing saturation pressure and vapour fraction */
30 namespace saturation_funcs
31 {
32  /*! \brief Null function for saturation pressure */
33  AMREX_GPU_HOST
34  void compute_saturation_pressure_null ( amrex::MultiFab&, const amrex::MultiFab& );
35  /*! \brief Compute saturation pressure for moist air */
36  AMREX_GPU_HOST
37  void compute_saturation_pressure_H2O ( amrex::MultiFab&, const amrex::MultiFab& );
38  /*! \brief Compute saturation pressure for icy air */
39  AMREX_GPU_HOST
40  void compute_saturation_pressure_ice ( amrex::MultiFab&, const amrex::MultiFab& );
41 
42  /*! \brief Null function for saturation vapour fraction */
43  AMREX_GPU_HOST
44  void compute_saturation_vapfrac_null ( amrex::MultiFab&,
45  const amrex::MultiFab&,
46  const amrex::MultiFab& );
47 
48  /*! \brief Compute saturation vapour fraction for moist air */
49  AMREX_GPU_HOST
50  void compute_saturation_vapfrac_H2O ( amrex::MultiFab&,
51  const amrex::MultiFab&,
52  const amrex::MultiFab& );
53  /*! \brief Compute saturation vapour fraction for icy air */
54  AMREX_GPU_HOST
55  void compute_saturation_vapfrac_ice ( amrex::MultiFab&,
56  const amrex::MultiFab&,
57  const amrex::MultiFab& );
58 }
59 
60 /**
61  * @brief Base structure containing material property constants and methods for GPU usage.
62  */
63 struct MaterialPropertiesCore { // For GPU
64 
65  static constexpr amrex::Real s_N_av = amrex::Real(6.02214076e23); /*!< Avogadro's number */
66  static constexpr amrex::Real s_kb = amrex::Real(1.380649e-23); /*!< Boltzmann constant [J K^{-1}] */
67 
68  /*! Molecular weight of air [kg mol^{-1}] */
69  static constexpr amrex::Real s_mol_weight_air = amrex::Real(0.0289647);
70  /*! Molecular length scale of air [m] */
71  static constexpr amrex::Real s_sigma_air = amrex::Real(3.62e-10);
72  /*! Temperature parameter for air [K] */
73  static constexpr amrex::Real s_eps_air_k = 97;
74 
75 #ifdef AMREX_USE_FLOAT
76  amrex::Real m_density = std::numeric_limits<float>::max(); /*!< density */
77  amrex::Real m_ionization = std::numeric_limits<float>::max(); /*!< ionization */
78  amrex::Real m_mol_weight = std::numeric_limits<float>::max(); /*!< molecular weight (condensate) */
79  amrex::Real m_lat_vap = std::numeric_limits<float>::max(); /*!< latent heat of vaporization */
80  amrex::Real m_lat_fus = std::numeric_limits<float>::max(); /*!< latent heat of fusion */
81  amrex::Real m_Rv = std::numeric_limits<float>::max(); /*!< gas constant for vapour of this material */
82  amrex::Real m_Tc = std::numeric_limits<float>::max(); /*!< critical temperature for surface tension */
83  amrex::Real m_Tb = std::numeric_limits<float>::max(); /*!< boiling temperature */
84  amrex::Real m_Nav_by_molweight = std::numeric_limits<float>::max(); /*!< Avogadro number by vapour mol. weight */
85 #else
86  amrex::Real m_density = std::numeric_limits<double>::max(); /*!< density */
87  amrex::Real m_ionization = std::numeric_limits<double>::max(); /*!< ionization */
88  amrex::Real m_mol_weight = std::numeric_limits<double>::max(); /*!< molecular weight (condensate) */
89  amrex::Real m_lat_vap = std::numeric_limits<double>::max(); /*!< latent heat of vaporization */
90  amrex::Real m_lat_fus = std::numeric_limits<double>::max(); /*!< latent heat of fusion */
91  amrex::Real m_Rv = std::numeric_limits<double>::max(); /*!< gas constant for vapour of this material */
92  amrex::Real m_Tc = std::numeric_limits<double>::max(); /*!< critical temperature for surface tension */
93  amrex::Real m_Tb = std::numeric_limits<double>::max(); /*!< boiling temperature */
94  amrex::Real m_Nav_by_molweight = std::numeric_limits<float>::max(); /*!< Avogadro number by vapour mol. weight */
95 #endif
96  /*! vector of molar heat capacity polynomial coeffs */
97  amrex::Real m_mol_Cp_coeffs[7] = { std::numeric_limits<amrex::Real>::max(),
98  std::numeric_limits<amrex::Real>::max(),
99  std::numeric_limits<amrex::Real>::max(),
100  std::numeric_limits<amrex::Real>::max(),
101  std::numeric_limits<amrex::Real>::max(),
102  std::numeric_limits<amrex::Real>::max(),
103  std::numeric_limits<amrex::Real>::max() };
104  bool m_is_soluble = false; /*!< is soluble in water? */
105  bool m_is_water = false; /*!< is this water? */
106  bool m_is_INP = false; /*!< can act as ice nucleating particle? */
107 
108  /*! \brief Return the molar heat capacity */
109  AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
111  {
112  auto retval = zero;
113  auto term = one;
114  for (auto i = 0; i < 7; i++) {
115  retval += (m_mol_Cp_coeffs[i] * term);
116  term *= a_T;
117  }
118  return retval;
119  }
120 
121  /*! \brief Compute the surface tension coeff given temperature */
122  AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
124  {
125  if (m_is_water) {
126  return amrex::Real(0.076148325); // N m^{-1}
127  } else {
128  auto term1 = amrex::Real(6.0) * std::cbrt(s_N_av);
129  auto term2 = std::cbrt((m_density/m_mol_weight)*(m_density/m_mol_weight));
130  auto retval = molarHeatCapacity(a_T)*(term2/term1)*(m_Tc - a_T);
131  return retval;
132  }
133  }
134 
135  /*! \brief Return the coeff of curvature given the temperature */
136  AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
137  amrex::Real coeffCurv( const amrex::Real a_T ) const
138  {
139  auto surf_tens = surfaceTension(a_T);
140  auto retval = 2 * surf_tens / (m_Rv * m_density);
141  return retval;
142  }
143 
144  /*! \brief Return the vapour pressure coefficient */
145  AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
147  {
148  auto retval = (amrex::Real(0.75)/PI)*(m_mol_weight/m_density);
149  if (m_is_water) {
150  retval = amrex::Real(4.3e-06);
151  }
152  return retval;
153  }
154 
155  /*! \brief Return the molecular diffusion coefficient given temperature and pressure */
156  AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
158  {
159  if (m_is_water) {
160 
161  return diffelq; // from ERF_Constants.H (amrex::Real(2.21e-05) [m^2 s^{-1}])
162 
163  } else {
164 
165  auto mol_weight_v = s_N_av/m_Nav_by_molweight;
166  auto sigma = amrex::Real(1.18e-8) * std::cbrt(mol_weight_v/m_density);
167  auto sigma_v_air = myhalf * (sigma + s_sigma_air);
168 
169  auto eps_v = amrex::Real(1.15) * m_Tb * s_kb;
170  auto eps_v_air = std::sqrt( eps_v * s_eps_air_k * s_kb);
171  auto T_star = a_T / (eps_v_air/s_kb);
172 
173  auto omegaD = amrex::Real(1.06036) / std::pow(T_star, amrex::Real(0.1561))
174  + amrex::Real(0.193) / std::exp(amrex::Real(0.47635)*T_star)
175  + amrex::Real(1.03587) / std::exp(amrex::Real(1.52996)*T_star)
176  + amrex::Real(1.76474) / std::exp(amrex::Real(3.89411)*T_star);
177 
178  auto term1 = 3 * std::sqrt( s_kb*a_T * s_kb*a_T * s_kb*a_T);
179  auto term2 = amrex::Real(8.0) * std::sqrt(2*PI) * a_P * sigma_v_air*sigma_v_air * omegaD;
180  auto term3 = std::sqrt( m_Nav_by_molweight + s_N_av/s_mol_weight_air );
181 
182  auto retval = term1*term3/term2;
183  return retval;
184  }
185  }
186 
187 };
188 
189 /*! Class for material properties */
191 
192  Species::Name m_name = Species::Name::none; /*!< name */
193 
194  /*! pointer to function to compute saturation pressure */
196 
197  /*! pointer to function to compute vapour fraction */
199 
200  /*! \brief Constructor */
201  AMREX_GPU_HOST_DEVICE
202  MaterialProperties ( const Species::Name& a_name );
203 
204  /*! \brief Copy constructor */
205  AMREX_GPU_HOST_DEVICE
206  MaterialProperties ( const MaterialProperties& a_matprop );
207 
208  /*! \brief Default destructor */
209  AMREX_GPU_HOST_DEVICE
210  ~MaterialProperties () = default;
211 
212  /*! \brief Print parameters */
213  AMREX_GPU_HOST
214  void print() const {
215  amrex::Print() << "Material properties of " << amrex::getEnumNameString(m_name) << ":\n";
216  amrex::Print() << " density: " << m_density << "\n";
217  amrex::Print() << " ionization: " << m_ionization << "\n";
218  amrex::Print() << " mol. weight: " << m_mol_weight << "\n";
219  amrex::Print() << " latent heat (vap.): " << m_lat_vap << "\n";
220  amrex::Print() << " latent heat (fus.): " << m_lat_fus << "\n";
221  amrex::Print() << " Rv: " << m_Rv << "\n";
222  amrex::Print() << " Tc: " << m_Tc << "\n";
223  amrex::Print() << " Tb: " << m_Tb << "\n";
224  amrex::Print() << " N_av/mol.weight: " << m_Nav_by_molweight << "\n";
225  amrex::Print() << " mol. Cp coeffs: ";
226  for (int i = 0; i < 7; i++) { amrex::Print() << m_mol_Cp_coeffs[i] << ", "; }
227  amrex::Print() << "\n";
228  }
229 
230  /*! \brief Set this material to H20 */
231  AMREX_GPU_HOST_DEVICE
232  void setProperties_H2O();
233  /*! \brief Set this material to ice */
234  AMREX_GPU_HOST_DEVICE
235  void setProperties_ice();
236  /*! \brief Set this material to water */
237  AMREX_GPU_HOST_DEVICE
238  void setProperties_water();
239  /*! \brief Set this material to agua */
240  AMREX_GPU_HOST_DEVICE
241  void setProperties_agua();
242  /*! \brief Set this material to NaCl */
243  AMREX_GPU_HOST_DEVICE
244  void setProperties_NaCl();
245  /*! \brief Set this material to ammonium sulfate */
246  AMREX_GPU_HOST_DEVICE
247  void setProperties_NH42SO4();
248  /*! \brief Set this material to ammonium bisulfate */
249  AMREX_GPU_HOST_DEVICE
250  void setProperties_NH4HSO4();
251  /*! \brief Set this material to soil */
252  AMREX_GPU_HOST_DEVICE
253  void setProperties_soil();
254 
255  /*! \brief Compute saturation pressure */
256  AMREX_GPU_HOST AMREX_FORCE_INLINE
257  void computeSaturationPressure ( amrex::MultiFab& a_e, const amrex::MultiFab& a_T) const
258  {
259  m_saturation_pressure_func(a_e, a_T);
260  }
261 
262  /*! \brief Compute saturation vapour fraction */
263  AMREX_GPU_HOST AMREX_FORCE_INLINE
264  void computeSaturationVapFrac ( amrex::MultiFab& a_S,
265  const amrex::MultiFab& a_T,
266  const amrex::MultiFab& a_p ) const
267  {
268  m_saturation_vapfrac_func(a_S, a_T, a_p);
269  }
270 };
271 
272 #endif
amrex::Real sigma
Definition: ERF_InitCustomPert_DataAssimilation_ISV.H:11
Physical constants and tuning parameters used only by the moisture and cloud-physics code.
constexpr amrex::Real diffelq
Definition: ERF_MicrophysicsConstants.H:102
Dimensionless numeric literals and pure mathematical constants.
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:30
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:29
constexpr amrex::Real myhalf
Definition: ERF_NumericalConstants.H:34
constexpr amrex::Real PI
Definition: ERF_NumericalConstants.H:39
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_MaterialProperties.H:15
AMREX_ENUM(Name, H2O, ice, NaCl, NH42SO4, NH4HSO4, soil, water, agua, none)
Definition: ERF_MaterialProperties.cpp:9
AMREX_GPU_HOST void compute_saturation_pressure_null(MultiFab &, const MultiFab &)
Definition: ERF_MaterialProperties.cpp:11
AMREX_GPU_HOST void compute_saturation_vapfrac_H2O(MultiFab &a_mf_sat_vapfrac, const MultiFab &a_mf_temperature, const MultiFab &a_mf_pressure)
Definition: ERF_MaterialProperties.cpp:64
AMREX_GPU_HOST void compute_saturation_vapfrac_null(MultiFab &, const MultiFab &, const MultiFab &)
Definition: ERF_MaterialProperties.cpp:54
AMREX_GPU_HOST void compute_saturation_pressure_H2O(MultiFab &a_mf_sat_pressure, const MultiFab &a_mf_temperature)
Definition: ERF_MaterialProperties.cpp:20
AMREX_GPU_HOST void compute_saturation_pressure_ice(MultiFab &a_mf_sat_pressure, const MultiFab &a_mf_temperature)
Definition: ERF_MaterialProperties.cpp:37
AMREX_GPU_HOST void compute_saturation_vapfrac_ice(MultiFab &a_mf_sat_vapfrac, const MultiFab &a_mf_temperature, const MultiFab &a_mf_pressure)
Definition: ERF_MaterialProperties.cpp:87
Base structure containing material property constants and methods for GPU usage.
Definition: ERF_MaterialProperties.H:63
amrex::Real m_mol_weight
Definition: ERF_MaterialProperties.H:88
bool m_is_water
Definition: ERF_MaterialProperties.H:105
bool m_is_INP
Definition: ERF_MaterialProperties.H:106
static constexpr amrex::Real s_sigma_air
Definition: ERF_MaterialProperties.H:71
amrex::Real m_mol_Cp_coeffs[7]
Definition: ERF_MaterialProperties.H:97
static constexpr amrex::Real s_mol_weight_air
Definition: ERF_MaterialProperties.H:69
static constexpr amrex::Real s_kb
Definition: ERF_MaterialProperties.H:66
amrex::Real m_Rv
Definition: ERF_MaterialProperties.H:91
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real molarHeatCapacity(const amrex::Real a_T) const
Return the molar heat capacity.
Definition: ERF_MaterialProperties.H:110
static constexpr amrex::Real s_eps_air_k
Definition: ERF_MaterialProperties.H:73
amrex::Real m_Nav_by_molweight
Definition: ERF_MaterialProperties.H:94
amrex::Real m_lat_fus
Definition: ERF_MaterialProperties.H:90
amrex::Real m_ionization
Definition: ERF_MaterialProperties.H:87
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real coeffCurv(const amrex::Real a_T) const
Return the coeff of curvature given the temperature.
Definition: ERF_MaterialProperties.H:137
amrex::Real m_Tb
Definition: ERF_MaterialProperties.H:93
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real coeffMolecularDiffusion(const amrex::Real a_T, const amrex::Real a_P) const
Return the molecular diffusion coefficient given temperature and pressure.
Definition: ERF_MaterialProperties.H:157
amrex::Real m_density
Definition: ERF_MaterialProperties.H:86
bool m_is_soluble
Definition: ERF_MaterialProperties.H:104
static constexpr amrex::Real s_N_av
Definition: ERF_MaterialProperties.H:65
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real coeffVPSolute() const
Return the vapour pressure coefficient.
Definition: ERF_MaterialProperties.H:146
amrex::Real m_lat_vap
Definition: ERF_MaterialProperties.H:89
amrex::Real m_Tc
Definition: ERF_MaterialProperties.H:92
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real surfaceTension(const amrex::Real a_T) const
Compute the surface tension coeff given temperature.
Definition: ERF_MaterialProperties.H:123
Definition: ERF_MaterialProperties.H:190
AMREX_GPU_HOST_DEVICE ~MaterialProperties()=default
Default destructor.
AMREX_GPU_HOST_DEVICE void setProperties_water()
Set this material to water.
Definition: ERF_MaterialProperties.cpp:212
AMREX_GPU_HOST AMREX_FORCE_INLINE void computeSaturationVapFrac(amrex::MultiFab &a_S, const amrex::MultiFab &a_T, const amrex::MultiFab &a_p) const
Compute saturation vapour fraction.
Definition: ERF_MaterialProperties.H:264
decltype(saturation_funcs::compute_saturation_pressure_null) * m_saturation_pressure_func
Definition: ERF_MaterialProperties.H:195
AMREX_GPU_HOST AMREX_FORCE_INLINE void computeSaturationPressure(amrex::MultiFab &a_e, const amrex::MultiFab &a_T) const
Compute saturation pressure.
Definition: ERF_MaterialProperties.H:257
AMREX_GPU_HOST_DEVICE void setProperties_ice()
Set this material to ice.
Definition: ERF_MaterialProperties.cpp:192
AMREX_GPU_HOST_DEVICE void setProperties_NH4HSO4()
Set this material to ammonium bisulfate.
Definition: ERF_MaterialProperties.cpp:248
AMREX_GPU_HOST_DEVICE void setProperties_soil()
Set this material to soil.
Definition: ERF_MaterialProperties.cpp:260
AMREX_GPU_HOST_DEVICE void setProperties_NH42SO4()
Set this material to ammonium sulfate.
Definition: ERF_MaterialProperties.cpp:236
AMREX_GPU_HOST_DEVICE MaterialProperties(const Species::Name &a_name)
Constructor.
Definition: ERF_MaterialProperties.cpp:116
AMREX_GPU_HOST void print() const
Print parameters.
Definition: ERF_MaterialProperties.H:214
AMREX_GPU_HOST_DEVICE void setProperties_NaCl()
Set this material to NaCl.
Definition: ERF_MaterialProperties.cpp:224
AMREX_GPU_HOST_DEVICE void setProperties_H2O()
Set this material to H20.
Definition: ERF_MaterialProperties.cpp:171
AMREX_GPU_HOST_DEVICE void setProperties_agua()
Set this material to agua.
Definition: ERF_MaterialProperties.cpp:218
Species::Name m_name
Definition: ERF_MaterialProperties.H:192
decltype(saturation_funcs::compute_saturation_vapfrac_null) * m_saturation_vapfrac_func
Definition: ERF_MaterialProperties.H:198