ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_SDInitialization.H
Go to the documentation of this file.
1 #ifndef SDINIT_H_
2 #define SDINIT_H_
3 
4 #include <string>
5 #include <vector>
6 #include <random>
7 
8 #include <AMReX_ParmParse.H>
9 #include <AMReX_Enum.H>
10 #include <AMReX_REAL.H>
11 #include <AMReX_RealBox.H>
12 #include <AMReX_Geometry.H>
13 #include <AMReX_Random.H>
14 #include <AMReX_GpuContainers.H>
15 
16 #include <limits>
17 #include <cmath>
18 #include "ERF_NumericalConstants.H"
19 #include "ERF_MaterialProperties.H"
20 
21 /**
22  * @brief Initial distribution shape for super-droplets.
23  */
24 AMREX_ENUM(SDInitShape,
25  uniform,
26  bubble,
27  null
28 );
29 
30 /*! \brief Distribution type enum for GPU compatibility */
31 AMREX_ENUM(SDDistributionType,
32  mass_constant,
33  mass_exponential,
34  radius_log_normal,
35  radius_lognormal_autorange
36 );
37 
38 /*! \brief List of super-droplet initializations */
39 namespace SupDropInit
40 {
41  /*! Maximum number of vapour/condensate species */
42  const int num_species_max = 10;
43 
44  /*! Maximum number of aerosols */
45  const int num_aerosols_max = 8;
46 }
47 
48 /**
49  * @brief Multiplicity type for super-droplet initialization.
50  */
51 AMREX_ENUM(SDMultiplicityType,
52  constant, sampled
53 );
54 
55 /*! \brief GPU-compatible structure holding distribution parameters */
56 /*! \brief Resolves a super-droplet input across the two input tiers.
57  *
58  * A property may be set once for every block under "<name>.<key>", or overridden
59  * for a single block under "<name>.<idx>.<key>". The common tier is what lets a
60  * property be shared, and is also what keeps input files written before multiple
61  * initializations were supported working unchanged.
62  *
63  * Precedence is per-block over common. a_val enters holding the default and leaves
64  * holding the resolved value. The return value reports whether the value came from
65  * the input file, so a caller can tell "the user set this" from "this is the
66  * default" without asking ParmParse whether a name is present.
67  *
68  * The resolved value is recorded under the per-block prefix so that it appears in
69  * job_info. That prefix is unique to this block, so the record cannot be read back
70  * by a later block as though the user had set it -- which is precisely what
71  * recording under the common prefix would do.
72  */
73 struct SDInputs
74 {
75  SDInputs (const std::string& a_common, const std::string& a_block)
76  : m_common(a_common), m_block(a_block),
77  m_common_name(a_common), m_block_name(a_block) {}
78 
79  template <typename T>
80  bool query (const std::string& a_key, T& a_val, const bool a_record = true)
81  {
82  bool from_inputs = m_block.query(a_key.c_str(), a_val);
83  if (!from_inputs) { from_inputs = m_common.query(a_key.c_str(), a_val); }
84  if (!from_inputs && a_record) { m_block.add(a_key.c_str(), a_val); }
85  return from_inputs;
86  }
87 
88  /*! Array-valued form, length taken from the input. */
89  template <typename T>
90  bool queryarr (const std::string& a_key, std::vector<T>& a_val)
91  {
92  bool from_inputs = m_block.queryarr(a_key.c_str(), a_val);
93  if (!from_inputs) { from_inputs = m_common.queryarr(a_key.c_str(), a_val); }
94  if (!from_inputs) { m_block.addarr(a_key.c_str(), a_val); }
95  return from_inputs;
96  }
97 
98  /*! Record a resolved value under the per-block prefix, for provenance only.
99  * Use where one of several alternative spellings of an input is in effect and
100  * only the effective one should be reported. */
101  template <typename T>
102  void record (const std::string& a_key, T& a_val) { m_block.add(a_key.c_str(), a_val); }
103 
104  /*! Array-valued form; a_num is the expected number of components. */
105  template <typename T>
106  bool queryarr (const std::string& a_key, std::vector<T>& a_val, const int a_num)
107  {
108  bool from_inputs = m_block.queryarr(a_key.c_str(), a_val, 0, a_num);
109  if (!from_inputs) { from_inputs = m_common.queryarr(a_key.c_str(), a_val, 0, a_num); }
110  if (!from_inputs) { m_block.addarr(a_key.c_str(), a_val); }
111  return from_inputs;
112  }
113 
114  amrex::ParmParse m_common; /*!< common tier: "<name>" */
115  amrex::ParmParse m_block; /*!< per-block tier: "<name>.<idx>" */
116  std::string m_common_name;
117  std::string m_block_name;
118 };
119 
121  SDDistributionType dist_type; /*!< Type of distribution */
122  amrex::Real mass_min; /*!< Minimum mass */
123  amrex::Real mass_max; /*!< Maximum mass */
124  amrex::Real mass_mean; /*!< Mean mass */
125  amrex::Real radius_min; /*!< Minimum radius */
126  amrex::Real radius_max; /*!< Maximum radius */
127  amrex::Real radius_mean; /*!< Mean radius (mu for log-normal) */
128  amrex::Real radius_gstd; /*!< Geometric std dev for radius */
129  amrex::Real density; /*!< Material density */
130  amrex::Real numdens; /*!< Number density for multiplicity */
131  amrex::Real cell_volume; /*!< Cell volume for multiplicity scaling */
132  // Pre-computed values for log-normal CDF inversion (truncated distribution)
133  amrex::Real cdf_min; /*!< CDF at radius_min */
134  amrex::Real cdf_max; /*!< CDF at radius_max */
135  amrex::Real sigma; /*!< log(radius_gstd) */
136  amrex::Real lnrng; /*!< log(radius_max) - log(radius_min) */
137  amrex::Real lnmin; /*!< log(radius_min) or log(mass_min) */
138  amrex::Real delta; /*!< mass_mean - mass_min for exponential */
139  int sampled_mult; /*!< 1 if sampled multiplicity, 0 if constant */
140 };
141 
142 /*! \brief Inverse error function approximation for GPU
143  * \param[in] x Input value in (-1, 1)
144  * \return Approximate inverse error function value
145  */
146 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
148  amrex::Real a = amrex::Real(0.147);
150  amrex::Real term = std::log(amrex::Real(1) - x * x + eps);
151  amrex::Real p1 = amrex::Real(2) / (PI * a) + term / amrex::Real(2);
152  amrex::Real p2 = term / a;
153  amrex::Real sign = (x >= 0) ? amrex::Real(1) : amrex::Real(-1);
154  return sign * std::sqrt(std::sqrt(p1 * p1 - p2) - p1);
155 }
156 
157 /*! \brief Generate mass from distribution parameters on GPU
158  * \param[in] params Distribution parameters
159  * \param[in] engine Random engine
160  * \param[out] mult_contribution Contribution to multiplicity (added, not set)
161  * \return Generated mass value
162  */
163 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
165  const amrex::RandomEngine& engine,
166  amrex::Real& mult_contribution)
167 {
168  using amrex::Random;
169  amrex::Real mass = 0.0;
170  amrex::Real u = Random(engine);
171 
172  switch (params.dist_type) {
173  case SDDistributionType::mass_constant:
174  mass = params.mass_mean;
175  mult_contribution = u; // Random [0,1] for later rescaling
176  break;
177 
178  case SDDistributionType::mass_exponential: {
179  if (params.sampled_mult) {
180  // Sampled multiplicity: sample uniformly in log-space, weight by the exponential PDF in ln(m)
181  amrex::Real lnval = params.lnmin + u * params.lnrng;
182  mass = std::exp(lnval);
183  mult_contribution = (params.numdens * params.cell_volume) * (mass / params.delta)
184  * std::exp(-(mass - params.mass_min) / params.delta);
185  } else {
186  // Constant multiplicity: true exponential distribution via inverse transform
187  // If U ~ Uniform(0,1), then -delta*ln(U) ~ Exponential(1/delta)
188  mass = -params.delta * std::log(u) + params.mass_min;
189  mult_contribution = 0.0; // Not used for constant multiplicity
190  }
191  break;
192  }
193 
194  case SDDistributionType::radius_log_normal:
195  case SDDistributionType::radius_lognormal_autorange: {
196  amrex::Real dry_r;
197  if (params.sampled_mult) {
198  // Sampled multiplicity: sample uniformly in log-space, weight by log-normal PDF
199  amrex::Real lnval = params.lnmin + u * params.lnrng;
200  dry_r = std::exp(lnval);
201  // Log-normal PDF contribution for multiplicity weighting
202  amrex::Real term = std::exp(-std::log(dry_r/params.radius_mean)*std::log(dry_r/params.radius_mean)
203  /(amrex::Real(2)*params.sigma*params.sigma));
204  mult_contribution = (params.numdens * params.cell_volume) / (params.sigma * std::sqrt(amrex::Real(2)*PI)) * term;
205  } else {
206  // Constant multiplicity: true log-normal via inverse CDF
207  // Map u from [0,1] to [cdf_min, cdf_max] for truncated distribution
208  amrex::Real u_trunc = params.cdf_min + u * (params.cdf_max - params.cdf_min);
209  // Inverse CDF: r = mu * exp(sigma * sqrt(2) * erfinv(2*u - 1))
210  amrex::Real z = SD_erfinv_gpu(amrex::Real(2) * u_trunc - amrex::Real(1)) * std::sqrt(amrex::Real(2));
211  dry_r = params.radius_mean * std::exp(params.sigma * z);
212  mult_contribution = 0.0; // Not used for constant multiplicity
213  }
214  mass = four_thirds_pi * dry_r * dry_r * dry_r * params.density;
215  break;
216  }
217  }
218  return mass;
219 }
220 
221 /*! \brief Super-droplets initial properties */
223 {
224  public:
225 
226  virtual ~SDInitProperties () = default;
227 
228  using MatVec = std::vector<std::unique_ptr<MaterialProperties>>;
229 
230  /*!< Initial number of super-droplets per cell */
231  int m_ppc = 1;
232  /*!< Whether particles_per_cell came from the input file. Published by
233  readInputs so callers do not have to read the key a second time --
234  a second read would find the default this one recorded. */
235  bool m_ppc_from_inputs = false;
236 
237  /*! Initial distribution type */
238  SDInitShape m_type = SDInitShape::uniform;
239 
240  /*!< Initial number density (m^{-3}) of physical particles */
242  /*!< Maximum multiplicity */
244  /*!< Apparent (bulk) density of initialized ice particles [kg m^-3];
245  <= 0 means use the solid-ice material density (a solid sphere) */
247 
248  /*! Minimum species mass */
249  std::vector<amrex::Real> m_mass_species_min;
250  /*! Maximum species mass */
251  std::vector<amrex::Real> m_mass_species_max;
252  /*! Mean species mass */
253  std::vector<amrex::Real> m_mass_species_mean;
254  /*! Minimum species dry radius */
255  std::vector<amrex::Real> m_radius_species_min;
256  /*! Maximum species dry radius */
257  std::vector<amrex::Real> m_radius_species_max;
258  /*! Mean species dry radius */
259  std::vector<amrex::Real> m_radius_species_mean;
260  /*! Standard deviation of species dry radius */
261  std::vector<amrex::Real> m_radius_species_geom_std;
262  /*! Initial distribution type for species */
263  std::vector<SDDistributionType> m_species_init_type;
264 
265  /*! Minimum aerosol mass */
266  std::vector<amrex::Real> m_mass_aerosol_min;
267  /*! Maximum aerosol mass */
268  std::vector<amrex::Real> m_mass_aerosol_max;
269  /*! Mean aerosol mass */
270  std::vector<amrex::Real> m_mass_aerosol_mean;
271  /*! Minimum aerosol dry radius */
272  std::vector<amrex::Real> m_radius_aerosol_min;
273  /*! Maximum aerosol dry radius */
274  std::vector<amrex::Real> m_radius_aerosol_max;
275  /*! Mean aerosol dry radius */
276  std::vector<amrex::Real> m_radius_aerosol_mean;
277  /*! Standard deviation of aerosol dry radius */
278  std::vector<amrex::Real> m_radius_aerosol_geom_std;
279  /*! Initial distribution type for aerosol */
280  std::vector<SDDistributionType> m_aerosol_init_type;
281 
282  /*! Number of species */
283  int m_num_species = 0;
284  /*! Number of aerosols */
285  int m_num_aerosols = 0;
286 
287  /*! box within which to place particles*/
288  amrex::RealBox m_particle_domain;
289  /*! Particle distribution shape parameters
290  Box shape, p1 -> lo end, p2 -> hi end
291  Bubble shape, p1 -> center, p2 -> radius */
292  amrex::Vector<amrex::Real> m_init_particle_p1;
293  amrex::Vector<amrex::Real> m_init_particle_p2;
294 
295  /*! multiplicity type */
296  SDMultiplicityType m_mult_type;
297 
298  /*! \brief Set default values for initialization parameters
299  * \param[in] a_geom Simulation geometry information
300  * \param[in] a_species_mat Vector of species material properties
301  * \param[in] a_aerosol_mat Vector of aerosol material properties
302  */
303  virtual void setDefaults ( const amrex::Geometry& a_geom,
304  const MatVec& a_species_mat,
305  const MatVec& a_aerosol_mat );
306 
307  /*! \brief Read super-droplets initialization parameters from input file
308  * \param[in] a_in Two-tier input resolver
309  * \param[in] a_key Key identifier for initialization parameters
310  * \param[in] a_geom Simulation geometry information
311  * \param[in] a_species_mat Vector of species material properties
312  * \param[in] a_aerosol_mat Vector of aerosol material properties
313  */
314  virtual void readInputs ( SDInputs& a_in,
315  const std::string& a_key,
316  const amrex::Geometry& a_geom,
317  const MatVec& a_species_mat,
318  const MatVec& a_aerosol_mat );
319 
320  /*! \brief Print super-droplets initialization parameters to screen
321  * \param[in] a_species_mat Vector of species material properties
322  * \param[in] a_aerosol_mat Vector of aerosol material properties
323  */
324  virtual void printParameters ( const MatVec& a_species_mat,
325  const MatVec& a_aerosol_mat ) const;
326 
327  /*! \brief Get a distribution with constant multiplicity
328  * \param[out] a_mass Output vector of particle masses
329  * \param[in] a_np Number of particles
330  * \param[in] a_density Density of the particle material
331  * \param[in] a_init_type Type of initialization distribution
332  * \param[in] a_mass_min Minimum mass value
333  * \param[in] a_mass_max Maximum mass value
334  * \param[in] a_mass_mean Mean mass value
335  * \param[in] a_radius_min Minimum radius value
336  * \param[in] a_radius_max Maximum radius value
337  * \param[in] a_radius_mean Mean radius value
338  * \param[in] a_radius_gstd Geometric standard deviation for radius
339  * \param[in,out] a_rng Random number generator
340  */
341  void getDistribution ( amrex::Vector<amrex::Real>& a_mass,
342  int a_np,
343  amrex::Real a_density,
344  SDDistributionType a_init_type,
345  amrex::Real a_mass_min,
346  amrex::Real a_mass_max,
347  amrex::Real a_mass_mean,
348  amrex::Real a_radius_min,
349  amrex::Real a_radius_max,
350  amrex::Real a_radius_mean,
351  amrex::Real a_radius_gstd,
352  std::mt19937& a_rng ) const;
353 
354  /*! \brief Get a distribution with sampled multiplicity
355  * \param[out] a_mass Output vector of particle masses
356  * \param[out] a_mult Output vector of particle multiplicities
357  * \param[in] a_dV Cell volume
358  * \param[in] a_np Number of particles
359  * \param[in] a_density Density of the particle material
360  * \param[in] a_init_type Type of initialization distribution
361  * \param[in] a_mass_min Minimum mass value
362  * \param[in] a_mass_max Maximum mass value
363  * \param[in] a_mass_mean Mean mass value
364  * \param[in] a_radius_min Minimum radius value
365  * \param[in] a_radius_max Maximum radius value
366  * \param[in] a_radius_mean Mean radius value
367  * \param[in] a_radius_gstd Geometric standard deviation for radius
368  * \param[in,out] a_rng Random number generator
369  */
370  void getDistribution ( amrex::Vector<amrex::Real>& a_mass,
371  amrex::Vector<amrex::Real>& a_mult,
372  amrex::Real a_dV,
373  int a_np,
374  amrex::Real a_density,
375  SDDistributionType a_init_type,
376  amrex::Real a_mass_min,
377  amrex::Real a_mass_max,
378  amrex::Real a_mass_mean,
379  amrex::Real a_radius_min,
380  amrex::Real a_radius_max,
381  amrex::Real a_radius_mean,
382  amrex::Real a_radius_gstd,
383  std::mt19937& a_rng ) const;
384 
385  /*! \brief Compute the aerosol mass distribution
386  * \param[out] a_mass Output vector of aerosol masses
387  * \param[in] a_idx Aerosol species index
388  * \param[in] a_np Number of particles
389  * \param[in] a_density Density of the aerosol material
390  * \param[in,out] a_rng Random number generator
391  */
392  void getAerosolDistribution ( amrex::Vector<amrex::Real>& a_mass,
393  const int a_idx,
394  const int a_np,
395  const amrex::Real a_density,
396  std::mt19937& a_rng ) const
397  {
398  getDistribution( a_mass,
399  a_np,
400  a_density,
401  m_aerosol_init_type[a_idx],
402  m_mass_aerosol_min[a_idx],
403  m_mass_aerosol_max[a_idx],
404  m_mass_aerosol_mean[a_idx],
405  m_radius_aerosol_min[a_idx],
406  m_radius_aerosol_max[a_idx],
407  m_radius_aerosol_mean[a_idx],
409  a_rng);
410  }
411 
412  /*! \brief Compute the aerosol mass distribution with sampled multiplicity
413  * \param[out] a_mass Output vector of aerosol masses
414  * \param[out] a_mult Output vector of particle multiplicities
415  * \param[in] a_dV Cell volume for scaling multiplicity
416  * \param[in] a_idx Aerosol species index
417  * \param[in] a_np Number of particles to generate
418  * \param[in] a_density Density of the aerosol material
419  * \param[in,out] a_rng Random number generator
420  */
421  void getAerosolDistribution ( amrex::Vector<amrex::Real>& a_mass,
422  amrex::Vector<amrex::Real>& a_mult,
423  amrex::Real a_dV,
424  int a_idx,
425  int a_np,
426  amrex::Real a_density,
427  std::mt19937& a_rng ) const
428  {
429  getDistribution( a_mass,
430  a_mult,
431  a_dV,
432  a_np,
433  a_density,
434  m_aerosol_init_type[a_idx],
435  m_mass_aerosol_min[a_idx],
436  m_mass_aerosol_max[a_idx],
437  m_mass_aerosol_mean[a_idx],
438  m_radius_aerosol_min[a_idx],
439  m_radius_aerosol_max[a_idx],
440  m_radius_aerosol_mean[a_idx],
442  a_rng);
443  }
444 
445  /*! \brief Compute the species mass distribution with constant multiplicity
446  * \param[out] a_mass Output vector of species masses
447  * \param[in] a_idx Species index
448  * \param[in] a_np Number of particles to generate
449  * \param[in] a_density Density of the species material
450  * \param[in,out] a_rng Random number generator
451  */
452  void getSpeciesDistribution ( amrex::Vector<amrex::Real>& a_mass,
453  const int a_idx,
454  const int a_np,
455  const amrex::Real a_density,
456  std::mt19937& a_rng ) const
457  {
458  getDistribution( a_mass,
459  a_np,
460  a_density,
461  m_species_init_type[a_idx],
462  m_mass_species_min[a_idx],
463  m_mass_species_max[a_idx],
464  m_mass_species_mean[a_idx],
465  m_radius_species_min[a_idx],
466  m_radius_species_max[a_idx],
467  m_radius_species_mean[a_idx],
469  a_rng);
470  }
471 
472  /*! \brief Compute the species mass distribution with sampled multiplicity
473  * \param[out] a_mass Output vector of species masses
474  * \param[out] a_mult Output vector of particle multiplicities
475  * \param[in] a_dV Cell volume for scaling multiplicity
476  * \param[in] a_idx Species index
477  * \param[in] a_np Number of particles to generate
478  * \param[in] a_density Density of the species material
479  * \param[in,out] a_rng Random number generator
480  */
481  void getSpeciesDistribution ( amrex::Vector<amrex::Real>& a_mass,
482  amrex::Vector<amrex::Real>& a_mult,
483  amrex::Real a_dV,
484  int a_idx,
485  int a_np,
486  amrex::Real a_density,
487  std::mt19937& a_rng ) const
488  {
489  getDistribution( a_mass,
490  a_mult,
491  a_dV,
492  a_np,
493  a_density,
494  m_species_init_type[a_idx],
495  m_mass_species_min[a_idx],
496  m_mass_species_max[a_idx],
497  m_mass_species_mean[a_idx],
498  m_radius_species_min[a_idx],
499  m_radius_species_max[a_idx],
500  m_radius_species_mean[a_idx],
502  a_rng);
503  }
504 
505  /*! \brief Get GPU-compatible distribution parameters for a species
506  * \param[in] a_idx Species index
507  * \param[in] a_density Density of the species material
508  * \param[in] a_cell_volume Cell volume for multiplicity scaling
509  * \param[in] a_sampled_mult Whether using sampled multiplicity mode
510  * \return SDDistributionParams structure for GPU use
511  */
513  int a_idx,
514  amrex::Real a_density,
515  amrex::Real a_cell_volume,
516  bool a_sampled_mult) const
517  {
518  return makeDistributionParams(
519  m_species_init_type[a_idx],
520  m_mass_species_min[a_idx],
521  m_mass_species_max[a_idx],
522  m_mass_species_mean[a_idx],
523  m_radius_species_min[a_idx],
524  m_radius_species_max[a_idx],
525  m_radius_species_mean[a_idx],
527  a_density,
528  a_cell_volume,
529  a_sampled_mult);
530  }
531 
532  /*! \brief Get GPU-compatible distribution parameters for an aerosol
533  * \param[in] a_idx Aerosol species index
534  * \param[in] a_density Density of the aerosol material
535  * \param[in] a_cell_volume Cell volume for multiplicity scaling
536  * \param[in] a_sampled_mult Whether using sampled multiplicity mode
537  * \return SDDistributionParams structure for GPU use
538  */
540  int a_idx,
541  amrex::Real a_density,
542  amrex::Real a_cell_volume,
543  bool a_sampled_mult) const
544  {
545  return makeDistributionParams(
546  m_aerosol_init_type[a_idx],
547  m_mass_aerosol_min[a_idx],
548  m_mass_aerosol_max[a_idx],
549  m_mass_aerosol_mean[a_idx],
550  m_radius_aerosol_min[a_idx],
551  m_radius_aerosol_max[a_idx],
552  m_radius_aerosol_mean[a_idx],
554  a_density,
555  a_cell_volume,
556  a_sampled_mult);
557  }
558 
559  /*! \brief Create GPU-compatible distribution parameters structure
560  * \param[in] a_init_type Distribution type
561  * \param[in] a_mass_min Minimum mass
562  * \param[in] a_mass_max Maximum mass
563  * \param[in] a_mass_mean Mean mass
564  * \param[in] a_radius_min Minimum radius
565  * \param[in] a_radius_max Maximum radius
566  * \param[in] a_radius_mean Mean radius
567  * \param[in] a_radius_gstd Geometric standard deviation
568  * \param[in] a_density Material density
569  * \param[in] a_cell_volume Cell volume
570  * \param[in] a_sampled_mult Whether using sampled multiplicity mode
571  * \return SDDistributionParams structure
572  */
574  SDDistributionType a_init_type,
575  amrex::Real a_mass_min,
576  amrex::Real a_mass_max,
577  amrex::Real a_mass_mean,
578  amrex::Real a_radius_min,
579  amrex::Real a_radius_max,
580  amrex::Real a_radius_mean,
581  amrex::Real a_radius_gstd,
582  amrex::Real a_density,
583  amrex::Real a_cell_volume,
584  bool a_sampled_mult) const;
585 
586  /*! \brief Determine whether multiplicity is sampled or constant
587  * \return True if multiplicity is sampled, false if constant
588  */
589  [[nodiscard]] inline bool sampledMultiplicity () const
590  {
591  return (m_mult_type == SDMultiplicityType::sampled);
592  }
593 
594  /*! \brief Calculate the volume of the particle domain
595  *
596  * For uniform distribution type, returns the box volume.
597  * For bubble distribution type, returns the volume of the bubble.
598  *
599  * \return Volume of the particle domain in cubic meters
600  */
601  [[nodiscard]] inline amrex::Real volume () const
602  {
603  amrex::Real vol = zero;
604  if (m_type == SDInitShape::uniform) {
605  vol = m_particle_domain.volume();
606  } else if (m_type == SDInitShape::bubble) {
607  const auto& radius = m_particle_domain.hi();
608  vol = four_thirds_pi*radius[0]*radius[1]*radius[2];
609  }
610  return vol;
611  }
612 
613  virtual int numSDPerCell (const amrex::Real) const = 0;
614  virtual amrex::Real numParticlesPerCell (const amrex::Real) const = 0;
615 
616  /*! \brief Per-box high-multiplicity injection (false for initialization
617  * and legacy per-cell injection). */
618  [[nodiscard]] virtual bool perBoxInjection () const { return false; }
619  /*! \brief Number of super-droplets to inject in the whole box this step. */
620  [[nodiscard]] virtual int injectBoxCount () const { return 0; }
621  /*! \brief Multiplicity of each super-droplet injected this step. */
622  [[nodiscard]] virtual amrex::Real injectMultiplicity () const { return zero; }
623  /*! \brief Reproducible seed for scattering this step's super-droplets. */
624  [[nodiscard]] virtual unsigned int injectSeed () const { return 0; }
625 };
626 
627 /*! \brief Super-droplets initialization structure */
629 {
630  public:
631 
632  virtual ~SDInjection () = default;
633 
634  /*!< Injection rate (number of physical particles per meter^3 second) */
636  /*!< Injection rate (number of SDs per meter^3 second) */
638 
639  /*!< Initial number density of super-droplets */
641 
642  /*!< Injection domain velocity */
643  amrex::Vector<amrex::Real> m_domain_vel = {zero,zero,zero};
644 
645  /*!< Start time for injection */
647 
648  /*!< Stop time for injection */
650 
651  /*!< Accumulated physical-particle number density [m^-3]. When the per-cell
652  injection rate is sub-unity, the fractional part is carried here until
653  it amounts to at least one super-droplet of unit multiplicity. */
655  /*!< Injection-level cell volume [m^3], set from geometry at read time */
657  /*!< Number of super-droplets to inject this step (0 = none). Per cell in
658  legacy mode; per box in per-box high-multiplicity mode. */
660  /*!< Integer multiplicity of each super-droplet injected this step */
662  /*!< Tolerance below 1 at which an accumulated injection fires */
664 
665  /*!< Minimum multiplicity for per-box injection (default 100) */
667  /*!< Per-box high-multiplicity injection mode (set when particles_per_cell
668  is not specified) */
669  bool m_perbox = false;
670  /*!< True when both sd_rate and min_multiplicity are explicitly specified */
671  bool m_both_specified = false;
672  /*!< Whether each knob was specified in any readInputs call (the
673  resolver reports this exactly, in a single pass). */
674  bool m_ppc_specified = false;
675  bool m_sd_specified = false;
676  bool m_mm_specified = false;
677  /*!< Effective SD injection rate [# m^-3 s^-1] used in per-box mode */
679  /*!< Injection-box volume [m^3], set from the box at read time */
681  /*!< Accumulated super-droplet count owed to the box (per-box mode) */
683  /*!< Count of injection events so far, used as a reproducible scatter seed */
684  unsigned int m_inject_count = 0;
685  /*!< Reproducible seed for scattering this step's super-droplets */
686  unsigned int m_inject_seed = 0;
687  /*!< Input prefix (e.g. injection.0) for diagnostic messages */
688  std::string m_prefix;
689 
690  /*! \brief Update time-dependent quantities for particle injection
691  *
692  * This function updates:
693  * 1. The accumulated physical-particle count, and the integer number of
694  * super-droplets and their integer multiplicity to inject this step
695  * 2. Position of the injection domain based on domain velocity
696  *
697  * The number of super-droplets per cell is the specified count (m_ppc, or
698  * derived from the SD rate). The physical-particle count accumulates from
699  * the injection rate; a step injects only once each of those super-droplets
700  * would carry at least unit multiplicity, with integer multiplicity
701  * max(round(num_par/num_sd), 1). This lets sub-unity per-step injection
702  * rates be honored automatically, with no separate opt-in.
703  *
704  * \param[in] a_dt Timestep size in seconds
705  * \param[in] a_active True while the injection time window is open
706  */
707  inline void updateDt (const double a_dt, const bool a_active)
708  {
709  using amrex::Real;
710 
711  if (m_perbox) {
712  // Per-box high-multiplicity injection: accumulate the box-level
713  // super-droplet and physical-particle counts. Inject floor(SD
714  // count) super-droplets at the implied multiplicity (= rate /
715  // eff_sd_rate) once at least one super-droplet is owed. This
716  // decouples the super-droplet count from the grid and bounds the
717  // population at physical/multiplicity.
718  if (a_active) {
720  m_numdens_accum += m_inj_rate * a_dt * m_box_volume; // physical count in box
721  }
722  if (a_active && m_sd_accum >= one - m_frac_tol) {
723  const int N = std::max(static_cast<int>(std::floor(m_sd_accum + m_frac_tol)), 1);
724  m_inject_mult = std::max(std::round(m_numdens_accum / N), one);
725  m_inject_num_sd = N;
726  m_sd_accum -= N;
729  } else {
730  m_inject_num_sd = 0;
732  }
733  } else {
734 
735  // Specified number of super-droplets per cell (m_ppc) or from the SD rate.
736  Real num_sd;
737  if (m_sd_inj_rate > 0) {
738  num_sd = std::max(Real(std::round(m_sd_inj_rate * a_dt * m_cell_volume)), one);
739  } else {
740  num_sd = std::max(Real(m_ppc), one);
741  }
742 
743  // Physical particles this step (per cell) and the resulting multiplicity.
744  const Real par_step = m_inj_rate * a_dt * m_cell_volume;
745  const Real mult_step = par_step / num_sd;
746 
747  if (!a_active) {
748  m_inject_num_sd = 0;
750  } else if (mult_step >= one) {
751  // Each super-droplet already carries at least unit multiplicity:
752  // inject the specified count every step (no accumulation).
753  m_inject_num_sd = static_cast<int>(num_sd);
754  m_inject_mult = std::max(std::round(mult_step), one);
756  } else {
757  // Sub-unity per-step multiplicity: accumulate the physical-particle
758  // count and inject only once it amounts to >= 1 multiplicity.
759  m_numdens_accum += m_inj_rate * a_dt;
760  const Real num_par = m_numdens_accum * m_cell_volume;
761  const Real mult = num_par / num_sd;
762  if (mult >= one - m_frac_tol) {
763  m_inject_mult = std::max(std::round(mult), one); // integer multiplicity
764  m_inject_num_sd = static_cast<int>(num_sd);
765  m_numdens_accum -= (num_sd * m_inject_mult) / m_cell_volume; // carry remainder
766  } else {
767  m_inject_num_sd = 0;
769  }
770  }
771 
772  }
773 
774  if (this->m_type == SDInitShape::uniform) {
775  amrex::Vector<amrex::Real> lo = {zero, zero, zero};
776  amrex::Vector<amrex::Real> hi = {zero, zero, zero};
777  for (int dir = 0; dir < AMREX_SPACEDIM; dir++) {
778  lo[dir] = this->m_particle_domain.lo(dir) + m_domain_vel[dir] * a_dt;
779  hi[dir] = this->m_particle_domain.hi(dir) + m_domain_vel[dir] * a_dt;
780  }
781  this->m_particle_domain.setLo(lo);
782  this->m_particle_domain.setHi(hi);
783  } else if (m_type == SDInitShape::bubble) {
784  amrex::Vector<amrex::Real> center = {zero, zero, zero};
785  for (int dir = 0; dir < AMREX_SPACEDIM; dir++) {
786  center[dir] = this->m_particle_domain.lo(dir) + m_domain_vel[dir] * a_dt;
787  }
788  this->m_particle_domain.setLo(center);
789  }
790  }
791 
792  /*! read super-droplets injection parameters */
794  const std::string&,
795  const amrex::Geometry&,
796  const MatVec&,
797  const MatVec& ) override
798  {
799  amrex::Abort("SDInjection::readInputs(): Do not use this interface");
800  }
801 
802  /*! \brief Read super-droplet injection parameters from input file
803  *
804  * This function reads injection-specific parameters like injection rate,
805  * timing parameters, and domain velocity.
806  *
807  * \param[in] a_in Two-tier input resolver
808  * \param[in] a_geom Simulation geometry information
809  * \param[in] a_species_mat Vector of species material properties
810  * \param[in] a_aerosol_mat Vector of aerosol material properties
811  * \param[in] a_dt Current timestep size
812  */
813  void readInputs ( SDInputs& a_in,
814  const amrex::Geometry& a_geom,
815  const MatVec& a_species_mat,
816  const MatVec& a_aerosol_mat,
817  const double a_dt );
818 
819  /*! print super-droplets injection parameters to screen */
820  void printParameters ( const MatVec&, const MatVec& ) const override;
821 
822  /*! \brief Number of super-droplets to inject per cell this step.
823  * Decided in updateDt() from the accumulated count (0 = inject nothing). */
824  [[nodiscard]] inline int numSDPerCell (const amrex::Real /*a_dv*/) const override
825  {
826  return m_inject_num_sd;
827  }
828 
829  /*! \brief Number of physical particles to inject per cell this step.
830  * Equals num_sd * integer-multiplicity, decided in updateDt(). */
831  [[nodiscard]] inline amrex::Real numParticlesPerCell (const amrex::Real /*a_dv*/) const override
832  {
834  }
835 
836  [[nodiscard]] inline bool perBoxInjection () const override { return m_perbox; }
837  [[nodiscard]] inline int injectBoxCount () const override { return m_inject_num_sd; }
838  [[nodiscard]] inline amrex::Real injectMultiplicity () const override { return m_inject_mult; }
839  [[nodiscard]] inline unsigned int injectSeed () const override { return m_inject_seed; }
840 
841 };
842 
843 /*! \brief Super-droplets initialization structure */
845 {
846  public:
847 
848  virtual ~SDInitialization () = default;
849 
850  /*!< Initial number density of super-droplets */
852 
853  /*! read super-droplets initialization parameters */
855  const std::string&,
856  const amrex::Geometry&,
857  const MatVec&,
858  const MatVec& ) override
859  {
860  amrex::Abort("SDInjection::readInputs(): Do not use this interface");
861  }
862 
863  /*! \brief Read super-droplet initialization parameters from input file
864  *
865  * This function reads initialization-specific parameters including
866  * distribution types, particle counts, and sizing parameters.
867  *
868  * \param[in] a_in Two-tier input resolver
869  * \param[in] a_geom Simulation geometry information
870  * \param[in] a_species_mat Vector of species material properties
871  * \param[in] a_aerosol_mat Vector of aerosol material properties
872  */
873  void readInputs ( SDInputs& a_in,
874  const amrex::Geometry& a_geom,
875  const MatVec& a_species_mat,
876  const MatVec& a_aerosol_mat );
877 
878  /*! print super-droplets initialization parameters to screen */
879  void printParameters ( const MatVec&, const MatVec& ) const override;
880 
881  /*! Compute number of super-droplets per grid cell */
882  [[nodiscard]] inline int numSDPerCell (const amrex::Real a_dv) const override
883  {
884  int num_sd_per_cell = 0;
885  if (m_numdens_sd_init >= 0) {
886  num_sd_per_cell = static_cast<int>(std::ceil(m_numdens_sd_init*a_dv));
887  } else {
888  num_sd_per_cell = this->m_ppc;
889  }
890  return num_sd_per_cell;
891  }
892 
893  /*! Compute number of physical particles per grid cell */
894  [[nodiscard]] inline amrex::Real numParticlesPerCell (const amrex::Real a_dv) const override
895  {
896  amrex::Real num_par_per_cell = zero;
897  if (this->m_numdens >= 0) {
898  num_par_per_cell = std::ceil(this->m_numdens*a_dv);
899  } else {
900  num_par_per_cell = 1;
901  }
902  return num_par_per_cell;
903  }
904 
905 };
906 
907 #endif
Dimensionless numeric literals and pure mathematical constants.
constexpr amrex::Real one
Definition: ERF_NumericalConstants.H:37
constexpr amrex::Real zero
Definition: ERF_NumericalConstants.H:36
constexpr amrex::Real PI
Definition: ERF_NumericalConstants.H:46
constexpr amrex::Real four_thirds_pi
Definition: ERF_NumericalConstants.H:48
AMREX_ENUM(SDInitShape, uniform, bubble, null)
Initial distribution shape for super-droplets.
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real SD_sample_mass_gpu(const SDDistributionParams &params, const amrex::RandomEngine &engine, amrex::Real &mult_contribution)
Generate mass from distribution parameters on GPU.
Definition: ERF_SDInitialization.H:164
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real SD_erfinv_gpu(const amrex::Real x)
Inverse error function approximation for GPU.
Definition: ERF_SDInitialization.H:147
std::vector< std::unique_ptr< MaterialProperties > > MatVec
Definition: ERF_SDInitialization.cpp:4
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Super-droplets initial properties.
Definition: ERF_SDInitialization.H:223
amrex::Real m_numdens
Definition: ERF_SDInitialization.H:241
void getAerosolDistribution(amrex::Vector< amrex::Real > &a_mass, const int a_idx, const int a_np, const amrex::Real a_density, std::mt19937 &a_rng) const
Compute the aerosol mass distribution.
Definition: ERF_SDInitialization.H:392
amrex::Real volume() const
Calculate the volume of the particle domain.
Definition: ERF_SDInitialization.H:601
bool sampledMultiplicity() const
Determine whether multiplicity is sampled or constant.
Definition: ERF_SDInitialization.H:589
std::vector< amrex::Real > m_radius_aerosol_geom_std
Definition: ERF_SDInitialization.H:278
amrex::Real m_ice_app_density
Definition: ERF_SDInitialization.H:246
std::vector< amrex::Real > m_radius_species_max
Definition: ERF_SDInitialization.H:257
virtual unsigned int injectSeed() const
Reproducible seed for scattering this step's super-droplets.
Definition: ERF_SDInitialization.H:624
void getAerosolDistribution(amrex::Vector< amrex::Real > &a_mass, amrex::Vector< amrex::Real > &a_mult, amrex::Real a_dV, int a_idx, int a_np, amrex::Real a_density, std::mt19937 &a_rng) const
Compute the aerosol mass distribution with sampled multiplicity.
Definition: ERF_SDInitialization.H:421
SDDistributionParams getSpeciesDistParams(int a_idx, amrex::Real a_density, amrex::Real a_cell_volume, bool a_sampled_mult) const
Get GPU-compatible distribution parameters for a species.
Definition: ERF_SDInitialization.H:512
virtual bool perBoxInjection() const
Per-box high-multiplicity injection (false for initialization and legacy per-cell injection).
Definition: ERF_SDInitialization.H:618
SDMultiplicityType m_mult_type
Definition: ERF_SDInitialization.H:296
SDInitShape m_type
Definition: ERF_SDInitialization.H:238
virtual void printParameters(const MatVec &a_species_mat, const MatVec &a_aerosol_mat) const
Print super-droplets initialization parameters to screen.
Definition: ERF_SDInitialization.cpp:285
amrex::Vector< amrex::Real > m_init_particle_p1
Definition: ERF_SDInitialization.H:292
int m_num_species
Definition: ERF_SDInitialization.H:283
std::vector< SDDistributionType > m_species_init_type
Definition: ERF_SDInitialization.H:263
std::vector< amrex::Real > m_mass_species_max
Definition: ERF_SDInitialization.H:251
SDDistributionParams makeDistributionParams(SDDistributionType a_init_type, amrex::Real a_mass_min, amrex::Real a_mass_max, amrex::Real a_mass_mean, amrex::Real a_radius_min, amrex::Real a_radius_max, amrex::Real a_radius_mean, amrex::Real a_radius_gstd, amrex::Real a_density, amrex::Real a_cell_volume, bool a_sampled_mult) const
Create GPU-compatible distribution parameters structure.
Definition: ERF_SDInitialization.cpp:579
std::vector< amrex::Real > m_radius_species_mean
Definition: ERF_SDInitialization.H:259
int m_ppc
Definition: ERF_SDInitialization.H:231
bool m_ppc_from_inputs
Definition: ERF_SDInitialization.H:235
amrex::Vector< amrex::Real > m_init_particle_p2
Definition: ERF_SDInitialization.H:293
std::vector< amrex::Real > m_radius_aerosol_min
Definition: ERF_SDInitialization.H:272
virtual int injectBoxCount() const
Number of super-droplets to inject in the whole box this step.
Definition: ERF_SDInitialization.H:620
int m_num_aerosols
Definition: ERF_SDInitialization.H:285
void getSpeciesDistribution(amrex::Vector< amrex::Real > &a_mass, amrex::Vector< amrex::Real > &a_mult, amrex::Real a_dV, int a_idx, int a_np, amrex::Real a_density, std::mt19937 &a_rng) const
Compute the species mass distribution with sampled multiplicity.
Definition: ERF_SDInitialization.H:481
std::vector< amrex::Real > m_radius_aerosol_max
Definition: ERF_SDInitialization.H:274
std::vector< amrex::Real > m_radius_species_geom_std
Definition: ERF_SDInitialization.H:261
virtual ~SDInitProperties()=default
std::vector< amrex::Real > m_mass_species_min
Definition: ERF_SDInitialization.H:249
SDDistributionParams getAerosolDistParams(int a_idx, amrex::Real a_density, amrex::Real a_cell_volume, bool a_sampled_mult) const
Get GPU-compatible distribution parameters for an aerosol.
Definition: ERF_SDInitialization.H:539
virtual int numSDPerCell(const amrex::Real) const =0
std::vector< SDDistributionType > m_aerosol_init_type
Definition: ERF_SDInitialization.H:280
virtual void readInputs(SDInputs &a_in, const std::string &a_key, const amrex::Geometry &a_geom, const MatVec &a_species_mat, const MatVec &a_aerosol_mat)
Read super-droplets initialization parameters from input file.
Definition: ERF_SDInitialization.cpp:76
amrex::Real m_max_multiplicity
Definition: ERF_SDInitialization.H:243
virtual void setDefaults(const amrex::Geometry &a_geom, const MatVec &a_species_mat, const MatVec &a_aerosol_mat)
Set default values for initialization parameters.
Definition: ERF_SDInitialization.cpp:6
std::vector< amrex::Real > m_mass_species_mean
Definition: ERF_SDInitialization.H:253
std::vector< amrex::Real > m_radius_aerosol_mean
Definition: ERF_SDInitialization.H:276
std::vector< amrex::Real > m_radius_species_min
Definition: ERF_SDInitialization.H:255
virtual amrex::Real numParticlesPerCell(const amrex::Real) const =0
std::vector< amrex::Real > m_mass_aerosol_min
Definition: ERF_SDInitialization.H:266
virtual amrex::Real injectMultiplicity() const
Multiplicity of each super-droplet injected this step.
Definition: ERF_SDInitialization.H:622
std::vector< std::unique_ptr< MaterialProperties > > MatVec
Definition: ERF_SDInitialization.H:230
std::vector< amrex::Real > m_mass_aerosol_mean
Definition: ERF_SDInitialization.H:270
std::vector< amrex::Real > m_mass_aerosol_max
Definition: ERF_SDInitialization.H:268
void getDistribution(amrex::Vector< amrex::Real > &a_mass, int a_np, amrex::Real a_density, SDDistributionType a_init_type, amrex::Real a_mass_min, amrex::Real a_mass_max, amrex::Real a_mass_mean, amrex::Real a_radius_min, amrex::Real a_radius_max, amrex::Real a_radius_mean, amrex::Real a_radius_gstd, std::mt19937 &a_rng) const
Get a distribution with constant multiplicity.
Definition: ERF_SDInitialization.cpp:415
amrex::RealBox m_particle_domain
Definition: ERF_SDInitialization.H:288
void getSpeciesDistribution(amrex::Vector< amrex::Real > &a_mass, const int a_idx, const int a_np, const amrex::Real a_density, std::mt19937 &a_rng) const
Compute the species mass distribution with constant multiplicity.
Definition: ERF_SDInitialization.H:452
Super-droplets initialization structure.
Definition: ERF_SDInitialization.H:845
amrex::Real m_numdens_sd_init
Definition: ERF_SDInitialization.H:851
int numSDPerCell(const amrex::Real a_dv) const override
Definition: ERF_SDInitialization.H:882
void printParameters(const MatVec &, const MatVec &) const override
Definition: ERF_SDInitialization.cpp:377
virtual ~SDInitialization()=default
amrex::Real numParticlesPerCell(const amrex::Real a_dv) const override
Definition: ERF_SDInitialization.H:894
void readInputs(SDInputs &, const std::string &, const amrex::Geometry &, const MatVec &, const MatVec &) override
Definition: ERF_SDInitialization.H:854
Super-droplets initialization structure.
Definition: ERF_SDInitialization.H:629
amrex::Real m_numdens_accum
Definition: ERF_SDInitialization.H:654
unsigned int m_inject_seed
Definition: ERF_SDInitialization.H:686
int injectBoxCount() const override
Number of super-droplets to inject in the whole box this step.
Definition: ERF_SDInitialization.H:837
amrex::Real m_numdens_sd
Definition: ERF_SDInitialization.H:640
amrex::Real m_eff_sd_rate
Definition: ERF_SDInitialization.H:678
amrex::Real m_tstop
Definition: ERF_SDInitialization.H:649
amrex::Real m_inject_mult
Definition: ERF_SDInitialization.H:661
amrex::Real m_sd_inj_rate
Definition: ERF_SDInitialization.H:637
amrex::Real m_tstart
Definition: ERF_SDInitialization.H:646
void updateDt(const double a_dt, const bool a_active)
Update time-dependent quantities for particle injection.
Definition: ERF_SDInitialization.H:707
bool m_mm_specified
Definition: ERF_SDInitialization.H:676
amrex::Real numParticlesPerCell(const amrex::Real) const override
Number of physical particles to inject per cell this step. Equals num_sd * integer-multiplicity,...
Definition: ERF_SDInitialization.H:831
bool m_sd_specified
Definition: ERF_SDInitialization.H:675
int numSDPerCell(const amrex::Real) const override
Number of super-droplets to inject per cell this step. Decided in updateDt() from the accumulated cou...
Definition: ERF_SDInitialization.H:824
amrex::Real m_min_multiplicity
Definition: ERF_SDInitialization.H:666
int m_inject_num_sd
Definition: ERF_SDInitialization.H:659
amrex::Real injectMultiplicity() const override
Multiplicity of each super-droplet injected this step.
Definition: ERF_SDInitialization.H:838
bool m_ppc_specified
Definition: ERF_SDInitialization.H:674
void readInputs(SDInputs &, const std::string &, const amrex::Geometry &, const MatVec &, const MatVec &) override
Definition: ERF_SDInitialization.H:793
unsigned int injectSeed() const override
Reproducible seed for scattering this step's super-droplets.
Definition: ERF_SDInitialization.H:839
void printParameters(const MatVec &, const MatVec &) const override
Definition: ERF_SDInitialization.cpp:386
amrex::Real m_sd_accum
Definition: ERF_SDInitialization.H:682
amrex::Real m_box_volume
Definition: ERF_SDInitialization.H:680
amrex::Real m_frac_tol
Definition: ERF_SDInitialization.H:663
amrex::Real m_inj_rate
Definition: ERF_SDInitialization.H:635
unsigned int m_inject_count
Definition: ERF_SDInitialization.H:684
bool m_both_specified
Definition: ERF_SDInitialization.H:671
bool m_perbox
Definition: ERF_SDInitialization.H:669
amrex::Real m_cell_volume
Definition: ERF_SDInitialization.H:656
bool perBoxInjection() const override
Per-box high-multiplicity injection (false for initialization and legacy per-cell injection).
Definition: ERF_SDInitialization.H:836
virtual ~SDInjection()=default
std::string m_prefix
Definition: ERF_SDInitialization.H:688
amrex::Vector< amrex::Real > m_domain_vel
Definition: ERF_SDInitialization.H:643
@ T
Definition: ERF_IndexDefines.H:168
List of super-droplet initializations.
Definition: ERF_SDInitialization.H:40
const int num_aerosols_max
Definition: ERF_SDInitialization.H:45
const int num_species_max
Definition: ERF_SDInitialization.H:42
real(c_double), parameter epsilon
Definition: ERF_module_model_constants.F90:12
Definition: ERF_SDInitialization.H:120
amrex::Real numdens
Definition: ERF_SDInitialization.H:130
amrex::Real mass_mean
Definition: ERF_SDInitialization.H:124
amrex::Real sigma
Definition: ERF_SDInitialization.H:135
amrex::Real delta
Definition: ERF_SDInitialization.H:138
amrex::Real cdf_max
Definition: ERF_SDInitialization.H:134
amrex::Real radius_mean
Definition: ERF_SDInitialization.H:127
amrex::Real mass_max
Definition: ERF_SDInitialization.H:123
amrex::Real lnmin
Definition: ERF_SDInitialization.H:137
amrex::Real cell_volume
Definition: ERF_SDInitialization.H:131
amrex::Real lnrng
Definition: ERF_SDInitialization.H:136
amrex::Real radius_gstd
Definition: ERF_SDInitialization.H:128
amrex::Real density
Definition: ERF_SDInitialization.H:129
amrex::Real radius_min
Definition: ERF_SDInitialization.H:125
amrex::Real radius_max
Definition: ERF_SDInitialization.H:126
int sampled_mult
Definition: ERF_SDInitialization.H:139
SDDistributionType dist_type
Definition: ERF_SDInitialization.H:121
amrex::Real cdf_min
Definition: ERF_SDInitialization.H:133
amrex::Real mass_min
Definition: ERF_SDInitialization.H:122
GPU-compatible structure holding distribution parameters.
Definition: ERF_SDInitialization.H:74
std::string m_block_name
Definition: ERF_SDInitialization.H:117
SDInputs(const std::string &a_common, const std::string &a_block)
Definition: ERF_SDInitialization.H:75
bool queryarr(const std::string &a_key, std::vector< T > &a_val)
Definition: ERF_SDInitialization.H:90
std::string m_common_name
Definition: ERF_SDInitialization.H:116
amrex::ParmParse m_common
Definition: ERF_SDInitialization.H:114
void record(const std::string &a_key, T &a_val)
Definition: ERF_SDInitialization.H:102
bool queryarr(const std::string &a_key, std::vector< T > &a_val, const int a_num)
Definition: ERF_SDInitialization.H:106
amrex::ParmParse m_block
Definition: ERF_SDInitialization.H:115
bool query(const std::string &a_key, T &a_val, const bool a_record=true)
Definition: ERF_SDInitialization.H:80