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 exponential PDF
181  amrex::Real lnval = params.lnmin + u * params.lnrng;
182  mass = std::exp(lnval);
183  mult_contribution = (params.numdens * params.cell_volume) * std::exp(-mass / params.delta);
184  } else {
185  // Constant multiplicity: true exponential distribution via inverse transform
186  // If U ~ Uniform(0,1), then -delta*ln(U) ~ Exponential(1/delta)
187  mass = -params.delta * std::log(u) + params.mass_min;
188  mult_contribution = 0.0; // Not used for constant multiplicity
189  }
190  break;
191  }
192 
193  case SDDistributionType::radius_log_normal:
194  case SDDistributionType::radius_lognormal_autorange: {
195  amrex::Real dry_r;
196  if (params.sampled_mult) {
197  // Sampled multiplicity: sample uniformly in log-space, weight by log-normal PDF
198  amrex::Real lnval = params.lnmin + u * params.lnrng;
199  dry_r = std::exp(lnval);
200  // Log-normal PDF contribution for multiplicity weighting
201  amrex::Real term = std::exp(-std::log(dry_r/params.radius_mean)*std::log(dry_r/params.radius_mean)
202  /(amrex::Real(2)*params.sigma*params.sigma));
203  mult_contribution = (params.numdens * params.cell_volume) / (params.sigma * std::sqrt(amrex::Real(2)*PI)) * term;
204  } else {
205  // Constant multiplicity: true log-normal via inverse CDF
206  // Map u from [0,1] to [cdf_min, cdf_max] for truncated distribution
207  amrex::Real u_trunc = params.cdf_min + u * (params.cdf_max - params.cdf_min);
208  // Inverse CDF: r = mu * exp(sigma * sqrt(2) * erfinv(2*u - 1))
209  amrex::Real z = SD_erfinv_gpu(amrex::Real(2) * u_trunc - amrex::Real(1)) * std::sqrt(amrex::Real(2));
210  dry_r = params.radius_mean * std::exp(params.sigma * z);
211  mult_contribution = 0.0; // Not used for constant multiplicity
212  }
213  mass = four_thirds_pi * dry_r * dry_r * dry_r * params.density;
214  break;
215  }
216  }
217  return mass;
218 }
219 
220 /*! \brief Super-droplets initial properties */
222 {
223  public:
224 
225  virtual ~SDInitProperties() = default;
226 
227  using MatVec = std::vector<std::unique_ptr<MaterialProperties>>;
228 
229  /*!< Initial number of super-droplets per cell */
230  int m_ppc = 1;
231  /*!< Whether particles_per_cell came from the input file. Published by
232  readInputs so callers do not have to read the key a second time --
233  a second read would find the default this one recorded. */
234  bool m_ppc_from_inputs = false;
235 
236  /*! Initial distribution type */
237  SDInitShape m_type = SDInitShape::uniform;
238 
239  /*!< Initial number density (m^{-3}) of physical particles */
241  /*!< Maximum multiplicity */
243  /*!< Apparent (bulk) density of initialized ice particles [kg m^-3];
244  <= 0 means use the solid-ice material density (a solid sphere) */
246 
247  /*! Minimum species mass */
248  std::vector<amrex::Real> m_mass_species_min;
249  /*! Maximum species mass */
250  std::vector<amrex::Real> m_mass_species_max;
251  /*! Mean species mass */
252  std::vector<amrex::Real> m_mass_species_mean;
253  /*! Minimum species dry radius */
254  std::vector<amrex::Real> m_radius_species_min;
255  /*! Maximum species dry radius */
256  std::vector<amrex::Real> m_radius_species_max;
257  /*! Mean species dry radius */
258  std::vector<amrex::Real> m_radius_species_mean;
259  /*! Standard deviation of species dry radius */
260  std::vector<amrex::Real> m_radius_species_geom_std;
261  /*! Initial distribution type for species */
262  std::vector<SDDistributionType> m_species_init_type;
263 
264  /*! Minimum aerosol mass */
265  std::vector<amrex::Real> m_mass_aerosol_min;
266  /*! Maximum aerosol mass */
267  std::vector<amrex::Real> m_mass_aerosol_max;
268  /*! Mean aerosol mass */
269  std::vector<amrex::Real> m_mass_aerosol_mean;
270  /*! Minimum aerosol dry radius */
271  std::vector<amrex::Real> m_radius_aerosol_min;
272  /*! Maximum aerosol dry radius */
273  std::vector<amrex::Real> m_radius_aerosol_max;
274  /*! Mean aerosol dry radius */
275  std::vector<amrex::Real> m_radius_aerosol_mean;
276  /*! Standard deviation of aerosol dry radius */
277  std::vector<amrex::Real> m_radius_aerosol_geom_std;
278  /*! Initial distribution type for aerosol */
279  std::vector<SDDistributionType> m_aerosol_init_type;
280 
281  /*! Number of species */
282  int m_num_species = 0;
283  /*! Number of aerosols */
284  int m_num_aerosols = 0;
285 
286  /*! box within which to place particles*/
287  amrex::RealBox m_particle_domain;
288  /*! Particle distribution shape parameters
289  Box shape, p1 -> lo end, p2 -> hi end
290  Bubble shape, p1 -> center, p2 -> radius */
291  amrex::Vector<amrex::Real> m_init_particle_p1;
292  amrex::Vector<amrex::Real> m_init_particle_p2;
293 
294  /*! multiplicity type */
295  SDMultiplicityType m_mult_type;
296 
297  /*! \brief Set default values for initialization parameters
298  * \param[in] a_geom Simulation geometry information
299  * \param[in] a_species_mat Vector of species material properties
300  * \param[in] a_aerosol_mat Vector of aerosol material properties
301  */
302  virtual void setDefaults ( const amrex::Geometry& a_geom,
303  const MatVec& a_species_mat,
304  const MatVec& a_aerosol_mat );
305 
306  /*! \brief Read super-droplets initialization parameters from input file
307  * \param[in] a_in Two-tier input resolver
308  * \param[in] a_key Key identifier for initialization parameters
309  * \param[in] a_geom Simulation geometry information
310  * \param[in] a_species_mat Vector of species material properties
311  * \param[in] a_aerosol_mat Vector of aerosol material properties
312  */
313  virtual void readInputs ( SDInputs& a_in,
314  const std::string& a_key,
315  const amrex::Geometry& a_geom,
316  const MatVec& a_species_mat,
317  const MatVec& a_aerosol_mat );
318 
319  /*! \brief Print super-droplets initialization parameters to screen
320  * \param[in] a_species_mat Vector of species material properties
321  * \param[in] a_aerosol_mat Vector of aerosol material properties
322  */
323  virtual void printParameters ( const MatVec& a_species_mat,
324  const MatVec& a_aerosol_mat ) const;
325 
326  /*! \brief Get a distribution with constant multiplicity
327  * \param[out] a_mass Output vector of particle masses
328  * \param[in] a_np Number of particles
329  * \param[in] a_density Density of the particle material
330  * \param[in] a_init_type Type of initialization distribution
331  * \param[in] a_mass_min Minimum mass value
332  * \param[in] a_mass_max Maximum mass value
333  * \param[in] a_mass_mean Mean mass value
334  * \param[in] a_radius_min Minimum radius value
335  * \param[in] a_radius_max Maximum radius value
336  * \param[in] a_radius_mean Mean radius value
337  * \param[in] a_radius_gstd Geometric standard deviation for radius
338  * \param[in,out] a_rng Random number generator
339  */
340  void getDistribution( amrex::Vector<amrex::Real>& a_mass,
341  int a_np,
342  amrex::Real a_density,
343  SDDistributionType a_init_type,
344  amrex::Real a_mass_min,
345  amrex::Real a_mass_max,
346  amrex::Real a_mass_mean,
347  amrex::Real a_radius_min,
348  amrex::Real a_radius_max,
349  amrex::Real a_radius_mean,
350  amrex::Real a_radius_gstd,
351  std::mt19937& a_rng ) const;
352 
353  /*! \brief Get a distribution with sampled multiplicity
354  * \param[out] a_mass Output vector of particle masses
355  * \param[out] a_mult Output vector of particle multiplicities
356  * \param[in] a_dV Cell volume
357  * \param[in] a_np Number of particles
358  * \param[in] a_density Density of the particle material
359  * \param[in] a_init_type Type of initialization distribution
360  * \param[in] a_mass_min Minimum mass value
361  * \param[in] a_mass_max Maximum mass value
362  * \param[in] a_mass_mean Mean mass value
363  * \param[in] a_radius_min Minimum radius value
364  * \param[in] a_radius_max Maximum radius value
365  * \param[in] a_radius_mean Mean radius value
366  * \param[in] a_radius_gstd Geometric standard deviation for radius
367  * \param[in,out] a_rng Random number generator
368  */
369  void getDistribution( amrex::Vector<amrex::Real>& a_mass,
370  amrex::Vector<amrex::Real>& a_mult,
371  amrex::Real a_dV,
372  int a_np,
373  amrex::Real a_density,
374  SDDistributionType a_init_type,
375  amrex::Real a_mass_min,
376  amrex::Real a_mass_max,
377  amrex::Real a_mass_mean,
378  amrex::Real a_radius_min,
379  amrex::Real a_radius_max,
380  amrex::Real a_radius_mean,
381  amrex::Real a_radius_gstd,
382  std::mt19937& a_rng ) const;
383 
384  /*! \brief Compute the aerosol mass distribution
385  * \param[out] a_mass Output vector of aerosol masses
386  * \param[in] a_idx Aerosol species index
387  * \param[in] a_np Number of particles
388  * \param[in] a_density Density of the aerosol material
389  * \param[in,out] a_rng Random number generator
390  */
391  void getAerosolDistribution ( amrex::Vector<amrex::Real>& a_mass,
392  const int a_idx,
393  const int a_np,
394  const amrex::Real a_density,
395  std::mt19937& a_rng ) const
396  {
397  getDistribution( a_mass,
398  a_np,
399  a_density,
400  m_aerosol_init_type[a_idx],
401  m_mass_aerosol_min[a_idx],
402  m_mass_aerosol_max[a_idx],
403  m_mass_aerosol_mean[a_idx],
404  m_radius_aerosol_min[a_idx],
405  m_radius_aerosol_max[a_idx],
406  m_radius_aerosol_mean[a_idx],
408  a_rng);
409  }
410 
411  /*! \brief Compute the aerosol mass distribution with sampled multiplicity
412  * \param[out] a_mass Output vector of aerosol masses
413  * \param[out] a_mult Output vector of particle multiplicities
414  * \param[in] a_dV Cell volume for scaling multiplicity
415  * \param[in] a_idx Aerosol species index
416  * \param[in] a_np Number of particles to generate
417  * \param[in] a_density Density of the aerosol material
418  * \param[in,out] a_rng Random number generator
419  */
420  void getAerosolDistribution ( amrex::Vector<amrex::Real>& a_mass,
421  amrex::Vector<amrex::Real>& a_mult,
422  amrex::Real a_dV,
423  int a_idx,
424  int a_np,
425  amrex::Real a_density,
426  std::mt19937& a_rng ) const
427  {
428  getDistribution( a_mass,
429  a_mult,
430  a_dV,
431  a_np,
432  a_density,
433  m_aerosol_init_type[a_idx],
434  m_mass_aerosol_min[a_idx],
435  m_mass_aerosol_max[a_idx],
436  m_mass_aerosol_mean[a_idx],
437  m_radius_aerosol_min[a_idx],
438  m_radius_aerosol_max[a_idx],
439  m_radius_aerosol_mean[a_idx],
441  a_rng);
442  }
443 
444  /*! \brief Compute the species mass distribution with constant multiplicity
445  * \param[out] a_mass Output vector of species masses
446  * \param[in] a_idx Species index
447  * \param[in] a_np Number of particles to generate
448  * \param[in] a_density Density of the species material
449  * \param[in,out] a_rng Random number generator
450  */
451  void getSpeciesDistribution ( amrex::Vector<amrex::Real>& a_mass,
452  const int a_idx,
453  const int a_np,
454  const amrex::Real a_density,
455  std::mt19937& a_rng ) const
456  {
457  getDistribution( a_mass,
458  a_np,
459  a_density,
460  m_species_init_type[a_idx],
461  m_mass_species_min[a_idx],
462  m_mass_species_max[a_idx],
463  m_mass_species_mean[a_idx],
464  m_radius_species_min[a_idx],
465  m_radius_species_max[a_idx],
466  m_radius_species_mean[a_idx],
468  a_rng);
469  }
470 
471  /*! \brief Compute the species mass distribution with sampled multiplicity
472  * \param[out] a_mass Output vector of species masses
473  * \param[out] a_mult Output vector of particle multiplicities
474  * \param[in] a_dV Cell volume for scaling multiplicity
475  * \param[in] a_idx Species index
476  * \param[in] a_np Number of particles to generate
477  * \param[in] a_density Density of the species material
478  * \param[in,out] a_rng Random number generator
479  */
480  void getSpeciesDistribution ( amrex::Vector<amrex::Real>& a_mass,
481  amrex::Vector<amrex::Real>& a_mult,
482  amrex::Real a_dV,
483  int a_idx,
484  int a_np,
485  amrex::Real a_density,
486  std::mt19937& a_rng ) const
487  {
488  getDistribution( a_mass,
489  a_mult,
490  a_dV,
491  a_np,
492  a_density,
493  m_species_init_type[a_idx],
494  m_mass_species_min[a_idx],
495  m_mass_species_max[a_idx],
496  m_mass_species_mean[a_idx],
497  m_radius_species_min[a_idx],
498  m_radius_species_max[a_idx],
499  m_radius_species_mean[a_idx],
501  a_rng);
502  }
503 
504  /*! \brief Get GPU-compatible distribution parameters for a species
505  * \param[in] a_idx Species index
506  * \param[in] a_density Density of the species material
507  * \param[in] a_cell_volume Cell volume for multiplicity scaling
508  * \param[in] a_sampled_mult Whether using sampled multiplicity mode
509  * \return SDDistributionParams structure for GPU use
510  */
512  int a_idx,
513  amrex::Real a_density,
514  amrex::Real a_cell_volume,
515  bool a_sampled_mult) const
516  {
517  return makeDistributionParams(
518  m_species_init_type[a_idx],
519  m_mass_species_min[a_idx],
520  m_mass_species_max[a_idx],
521  m_mass_species_mean[a_idx],
522  m_radius_species_min[a_idx],
523  m_radius_species_max[a_idx],
524  m_radius_species_mean[a_idx],
526  a_density,
527  a_cell_volume,
528  a_sampled_mult);
529  }
530 
531  /*! \brief Get GPU-compatible distribution parameters for an aerosol
532  * \param[in] a_idx Aerosol species index
533  * \param[in] a_density Density of the aerosol material
534  * \param[in] a_cell_volume Cell volume for multiplicity scaling
535  * \param[in] a_sampled_mult Whether using sampled multiplicity mode
536  * \return SDDistributionParams structure for GPU use
537  */
539  int a_idx,
540  amrex::Real a_density,
541  amrex::Real a_cell_volume,
542  bool a_sampled_mult) const
543  {
544  return makeDistributionParams(
545  m_aerosol_init_type[a_idx],
546  m_mass_aerosol_min[a_idx],
547  m_mass_aerosol_max[a_idx],
548  m_mass_aerosol_mean[a_idx],
549  m_radius_aerosol_min[a_idx],
550  m_radius_aerosol_max[a_idx],
551  m_radius_aerosol_mean[a_idx],
553  a_density,
554  a_cell_volume,
555  a_sampled_mult);
556  }
557 
558  /*! \brief Create GPU-compatible distribution parameters structure
559  * \param[in] a_init_type Distribution type
560  * \param[in] a_mass_min Minimum mass
561  * \param[in] a_mass_max Maximum mass
562  * \param[in] a_mass_mean Mean mass
563  * \param[in] a_radius_min Minimum radius
564  * \param[in] a_radius_max Maximum radius
565  * \param[in] a_radius_mean Mean radius
566  * \param[in] a_radius_gstd Geometric standard deviation
567  * \param[in] a_density Material density
568  * \param[in] a_cell_volume Cell volume
569  * \param[in] a_sampled_mult Whether using sampled multiplicity mode
570  * \return SDDistributionParams structure
571  */
573  SDDistributionType a_init_type,
574  amrex::Real a_mass_min,
575  amrex::Real a_mass_max,
576  amrex::Real a_mass_mean,
577  amrex::Real a_radius_min,
578  amrex::Real a_radius_max,
579  amrex::Real a_radius_mean,
580  amrex::Real a_radius_gstd,
581  amrex::Real a_density,
582  amrex::Real a_cell_volume,
583  bool a_sampled_mult) const;
584 
585  /*! \brief Determine whether multiplicity is sampled or constant
586  * \return True if multiplicity is sampled, false if constant
587  */
588  [[nodiscard]] inline bool sampledMultiplicity() const
589  {
590  return (m_mult_type == SDMultiplicityType::sampled);
591  }
592 
593  /*! \brief Calculate the volume of the particle domain
594  *
595  * For uniform distribution type, returns the box volume.
596  * For bubble distribution type, returns the volume of the bubble.
597  *
598  * \return Volume of the particle domain in cubic meters
599  */
600  [[nodiscard]] inline amrex::Real volume() const
601  {
602  amrex::Real vol = zero;
603  if (m_type == SDInitShape::uniform) {
604  vol = m_particle_domain.volume();
605  } else if (m_type == SDInitShape::bubble) {
606  const auto& radius = m_particle_domain.hi();
607  vol = four_thirds_pi*radius[0]*radius[1]*radius[2];
608  }
609  return vol;
610  }
611 
612  virtual int numSDPerCell (const amrex::Real) const = 0;
613  virtual amrex::Real numParticlesPerCell (const amrex::Real) const = 0;
614 
615  /*! \brief Per-box high-multiplicity injection (false for initialization
616  * and legacy per-cell injection). */
617  [[nodiscard]] virtual bool perBoxInjection () const { return false; }
618  /*! \brief Number of super-droplets to inject in the whole box this step. */
619  [[nodiscard]] virtual int injectBoxCount () const { return 0; }
620  /*! \brief Multiplicity of each super-droplet injected this step. */
621  [[nodiscard]] virtual amrex::Real injectMultiplicity () const { return zero; }
622  /*! \brief Reproducible seed for scattering this step's super-droplets. */
623  [[nodiscard]] virtual unsigned int injectSeed () const { return 0; }
624 };
625 
626 /*! \brief Super-droplets initialization structure */
628 {
629  public:
630 
631  virtual ~SDInjection() = default;
632 
633  /*!< Injection rate (number of physical particles per meter^3 second) */
635  /*!< Injection rate (number of SDs per meter^3 second) */
637 
638  /*!< Initial number density of super-droplets */
640 
641  /*!< Injection domain velocity */
642  amrex::Vector<amrex::Real> m_domain_vel = {zero,zero,zero};
643 
644  /*!< Start time for injection */
646 
647  /*!< Stop time for injection */
649 
650  /*!< Accumulated physical-particle number density [m^-3]. When the per-cell
651  injection rate is sub-unity, the fractional part is carried here until
652  it amounts to at least one super-droplet of unit multiplicity. */
654  /*!< Injection-level cell volume [m^3], set from geometry at read time */
656  /*!< Number of super-droplets to inject this step (0 = none). Per cell in
657  legacy mode; per box in per-box high-multiplicity mode. */
659  /*!< Integer multiplicity of each super-droplet injected this step */
661  /*!< Tolerance below 1 at which an accumulated injection fires */
663 
664  /*!< Minimum multiplicity for per-box injection (default 100) */
666  /*!< Per-box high-multiplicity injection mode (set when particles_per_cell
667  is not specified) */
668  bool m_perbox = false;
669  /*!< True when both sd_rate and min_multiplicity are explicitly specified */
670  bool m_both_specified = false;
671  /*!< Whether each knob was specified in any readInputs call (the
672  resolver reports this exactly, in a single pass). */
673  bool m_ppc_specified = false;
674  bool m_sd_specified = false;
675  bool m_mm_specified = false;
676  /*!< Effective SD injection rate [# m^-3 s^-1] used in per-box mode */
678  /*!< Injection-box volume [m^3], set from the box at read time */
680  /*!< Accumulated super-droplet count owed to the box (per-box mode) */
682  /*!< Count of injection events so far, used as a reproducible scatter seed */
683  unsigned int m_inject_count = 0;
684  /*!< Reproducible seed for scattering this step's super-droplets */
685  unsigned int m_inject_seed = 0;
686  /*!< Input prefix (e.g. injection.0) for diagnostic messages */
687  std::string m_prefix;
688 
689  /*! \brief Update time-dependent quantities for particle injection
690  *
691  * This function updates:
692  * 1. The accumulated physical-particle count, and the integer number of
693  * super-droplets and their integer multiplicity to inject this step
694  * 2. Position of the injection domain based on domain velocity
695  *
696  * The number of super-droplets per cell is the specified count (m_ppc, or
697  * derived from the SD rate). The physical-particle count accumulates from
698  * the injection rate; a step injects only once each of those super-droplets
699  * would carry at least unit multiplicity, with integer multiplicity
700  * max(round(num_par/num_sd), 1). This lets sub-unity per-step injection
701  * rates be honored automatically, with no separate opt-in.
702  *
703  * \param[in] a_dt Timestep size in seconds
704  * \param[in] a_active True while the injection time window is open
705  */
706  inline void updateDt (const double a_dt, const bool a_active)
707  {
708  using amrex::Real;
709 
710  if (m_perbox) {
711  // Per-box high-multiplicity injection: accumulate the box-level
712  // super-droplet and physical-particle counts. Inject floor(SD
713  // count) super-droplets at the implied multiplicity (= rate /
714  // eff_sd_rate) once at least one super-droplet is owed. This
715  // decouples the super-droplet count from the grid and bounds the
716  // population at physical/multiplicity.
717  if (a_active) {
719  m_numdens_accum += m_inj_rate * a_dt * m_box_volume; // physical count in box
720  }
721  if (a_active && m_sd_accum >= one - m_frac_tol) {
722  const int N = std::max(static_cast<int>(std::floor(m_sd_accum + m_frac_tol)), 1);
723  m_inject_mult = std::max(std::round(m_numdens_accum / N), one);
724  m_inject_num_sd = N;
725  m_sd_accum -= N;
728  } else {
729  m_inject_num_sd = 0;
731  }
732  } else {
733 
734  // Specified number of super-droplets per cell (m_ppc) or from the SD rate.
735  Real num_sd;
736  if (m_sd_inj_rate > 0) {
737  num_sd = std::max(Real(std::round(m_sd_inj_rate * a_dt * m_cell_volume)), one);
738  } else {
739  num_sd = std::max(Real(m_ppc), one);
740  }
741 
742  // Physical particles this step (per cell) and the resulting multiplicity.
743  const Real par_step = m_inj_rate * a_dt * m_cell_volume;
744  const Real mult_step = par_step / num_sd;
745 
746  if (!a_active) {
747  m_inject_num_sd = 0;
749  } else if (mult_step >= one) {
750  // Each super-droplet already carries at least unit multiplicity:
751  // inject the specified count every step (no accumulation).
752  m_inject_num_sd = static_cast<int>(num_sd);
753  m_inject_mult = std::max(std::round(mult_step), one);
755  } else {
756  // Sub-unity per-step multiplicity: accumulate the physical-particle
757  // count and inject only once it amounts to >= 1 multiplicity.
758  m_numdens_accum += m_inj_rate * a_dt;
759  const Real num_par = m_numdens_accum * m_cell_volume;
760  const Real mult = num_par / num_sd;
761  if (mult >= one - m_frac_tol) {
762  m_inject_mult = std::max(std::round(mult), one); // integer multiplicity
763  m_inject_num_sd = static_cast<int>(num_sd);
764  m_numdens_accum -= (num_sd * m_inject_mult) / m_cell_volume; // carry remainder
765  } else {
766  m_inject_num_sd = 0;
768  }
769  }
770 
771  }
772 
773  if (this->m_type == SDInitShape::uniform) {
774  amrex::Vector<amrex::Real> lo = {zero, zero, zero};
775  amrex::Vector<amrex::Real> hi = {zero, zero, zero};
776  for (int dir = 0; dir < AMREX_SPACEDIM; dir++) {
777  lo[dir] = this->m_particle_domain.lo(dir) + m_domain_vel[dir] * a_dt;
778  hi[dir] = this->m_particle_domain.hi(dir) + m_domain_vel[dir] * a_dt;
779  }
780  this->m_particle_domain.setLo(lo);
781  this->m_particle_domain.setHi(hi);
782  } else if (m_type == SDInitShape::bubble) {
783  amrex::Vector<amrex::Real> center = {zero, zero, zero};
784  for (int dir = 0; dir < AMREX_SPACEDIM; dir++) {
785  center[dir] = this->m_particle_domain.lo(dir) + m_domain_vel[dir] * a_dt;
786  }
787  this->m_particle_domain.setLo(center);
788  }
789  }
790 
791  /*! read super-droplets injection parameters */
793  const std::string&,
794  const amrex::Geometry&,
795  const MatVec&,
796  const MatVec& ) override
797  {
798  amrex::Abort("SDInjection::readInputs(): Do not use this interface");
799  }
800 
801  /*! \brief Read super-droplet injection parameters from input file
802  *
803  * This function reads injection-specific parameters like injection rate,
804  * timing parameters, and domain velocity.
805  *
806  * \param[in] a_in Two-tier input resolver
807  * \param[in] a_geom Simulation geometry information
808  * \param[in] a_species_mat Vector of species material properties
809  * \param[in] a_aerosol_mat Vector of aerosol material properties
810  * \param[in] a_dt Current timestep size
811  */
812  void readInputs ( SDInputs& a_in,
813  const amrex::Geometry& a_geom,
814  const MatVec& a_species_mat,
815  const MatVec& a_aerosol_mat,
816  const double a_dt );
817 
818  /*! print super-droplets injection parameters to screen */
819  void printParameters ( const MatVec&, const MatVec& ) const override;
820 
821  /*! \brief Number of super-droplets to inject per cell this step.
822  * Decided in updateDt() from the accumulated count (0 = inject nothing). */
823  [[nodiscard]] inline int numSDPerCell (const amrex::Real /*a_dv*/) const override
824  {
825  return m_inject_num_sd;
826  }
827 
828  /*! \brief Number of physical particles to inject per cell this step.
829  * Equals num_sd * integer-multiplicity, decided in updateDt(). */
830  [[nodiscard]] inline amrex::Real numParticlesPerCell (const amrex::Real /*a_dv*/) const override
831  {
833  }
834 
835  [[nodiscard]] inline bool perBoxInjection () const override { return m_perbox; }
836  [[nodiscard]] inline int injectBoxCount () const override { return m_inject_num_sd; }
837  [[nodiscard]] inline amrex::Real injectMultiplicity () const override { return m_inject_mult; }
838  [[nodiscard]] inline unsigned int injectSeed () const override { return m_inject_seed; }
839 
840 };
841 
842 /*! \brief Super-droplets initialization structure */
844 {
845  public:
846 
847  virtual ~SDInitialization() = default;
848 
849  /*!< Initial number density of super-droplets */
851 
852  /*! read super-droplets initialization parameters */
854  const std::string&,
855  const amrex::Geometry&,
856  const MatVec&,
857  const MatVec& ) override
858  {
859  amrex::Abort("SDInjection::readInputs(): Do not use this interface");
860  }
861 
862  /*! \brief Read super-droplet initialization parameters from input file
863  *
864  * This function reads initialization-specific parameters including
865  * distribution types, particle counts, and sizing parameters.
866  *
867  * \param[in] a_in Two-tier input resolver
868  * \param[in] a_geom Simulation geometry information
869  * \param[in] a_species_mat Vector of species material properties
870  * \param[in] a_aerosol_mat Vector of aerosol material properties
871  */
872  void readInputs ( SDInputs& a_in,
873  const amrex::Geometry& a_geom,
874  const MatVec& a_species_mat,
875  const MatVec& a_aerosol_mat );
876 
877  /*! print super-droplets initialization parameters to screen */
878  void printParameters ( const MatVec&, const MatVec& ) const override;
879 
880  /*! Compute number of super-droplets per grid cell */
881  [[nodiscard]] inline int numSDPerCell (const amrex::Real a_dv) const override
882  {
883  int num_sd_per_cell = 0;
884  if (m_numdens_sd_init >= 0) {
885  num_sd_per_cell = static_cast<int>(std::ceil(m_numdens_sd_init*a_dv));
886  } else {
887  num_sd_per_cell = this->m_ppc;
888  }
889  return num_sd_per_cell;
890  }
891 
892  /*! Compute number of physical particles per grid cell */
893  [[nodiscard]] inline amrex::Real numParticlesPerCell (const amrex::Real a_dv) const override
894  {
895  amrex::Real num_par_per_cell = zero;
896  if (this->m_numdens >= 0) {
897  num_par_per_cell = std::ceil(this->m_numdens*a_dv);
898  } else {
899  num_par_per_cell = 1;
900  }
901  return num_par_per_cell;
902  }
903 
904 };
905 
906 #endif
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 PI
Definition: ERF_NumericalConstants.H:39
constexpr amrex::Real four_thirds_pi
Definition: ERF_NumericalConstants.H:41
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:222
amrex::Real m_numdens
Definition: ERF_SDInitialization.H:240
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:391
amrex::Real volume() const
Calculate the volume of the particle domain.
Definition: ERF_SDInitialization.H:600
bool sampledMultiplicity() const
Determine whether multiplicity is sampled or constant.
Definition: ERF_SDInitialization.H:588
std::vector< amrex::Real > m_radius_aerosol_geom_std
Definition: ERF_SDInitialization.H:277
amrex::Real m_ice_app_density
Definition: ERF_SDInitialization.H:245
std::vector< amrex::Real > m_radius_species_max
Definition: ERF_SDInitialization.H:256
virtual unsigned int injectSeed() const
Reproducible seed for scattering this step's super-droplets.
Definition: ERF_SDInitialization.H:623
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:420
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:511
virtual bool perBoxInjection() const
Per-box high-multiplicity injection (false for initialization and legacy per-cell injection).
Definition: ERF_SDInitialization.H:617
SDMultiplicityType m_mult_type
Definition: ERF_SDInitialization.H:295
SDInitShape m_type
Definition: ERF_SDInitialization.H:237
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:291
int m_num_species
Definition: ERF_SDInitialization.H:282
std::vector< SDDistributionType > m_species_init_type
Definition: ERF_SDInitialization.H:262
std::vector< amrex::Real > m_mass_species_max
Definition: ERF_SDInitialization.H:250
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:578
std::vector< amrex::Real > m_radius_species_mean
Definition: ERF_SDInitialization.H:258
int m_ppc
Definition: ERF_SDInitialization.H:230
bool m_ppc_from_inputs
Definition: ERF_SDInitialization.H:234
amrex::Vector< amrex::Real > m_init_particle_p2
Definition: ERF_SDInitialization.H:292
std::vector< amrex::Real > m_radius_aerosol_min
Definition: ERF_SDInitialization.H:271
virtual int injectBoxCount() const
Number of super-droplets to inject in the whole box this step.
Definition: ERF_SDInitialization.H:619
int m_num_aerosols
Definition: ERF_SDInitialization.H:284
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:480
std::vector< amrex::Real > m_radius_aerosol_max
Definition: ERF_SDInitialization.H:273
std::vector< amrex::Real > m_radius_species_geom_std
Definition: ERF_SDInitialization.H:260
virtual ~SDInitProperties()=default
std::vector< amrex::Real > m_mass_species_min
Definition: ERF_SDInitialization.H:248
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:538
virtual int numSDPerCell(const amrex::Real) const =0
std::vector< SDDistributionType > m_aerosol_init_type
Definition: ERF_SDInitialization.H:279
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:242
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:252
std::vector< amrex::Real > m_radius_aerosol_mean
Definition: ERF_SDInitialization.H:275
std::vector< amrex::Real > m_radius_species_min
Definition: ERF_SDInitialization.H:254
virtual amrex::Real numParticlesPerCell(const amrex::Real) const =0
std::vector< amrex::Real > m_mass_aerosol_min
Definition: ERF_SDInitialization.H:265
virtual amrex::Real injectMultiplicity() const
Multiplicity of each super-droplet injected this step.
Definition: ERF_SDInitialization.H:621
std::vector< std::unique_ptr< MaterialProperties > > MatVec
Definition: ERF_SDInitialization.H:229
std::vector< amrex::Real > m_mass_aerosol_mean
Definition: ERF_SDInitialization.H:269
std::vector< amrex::Real > m_mass_aerosol_max
Definition: ERF_SDInitialization.H:267
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:287
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:451
Super-droplets initialization structure.
Definition: ERF_SDInitialization.H:844
amrex::Real m_numdens_sd_init
Definition: ERF_SDInitialization.H:850
int numSDPerCell(const amrex::Real a_dv) const override
Definition: ERF_SDInitialization.H:881
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:893
void readInputs(SDInputs &, const std::string &, const amrex::Geometry &, const MatVec &, const MatVec &) override
Definition: ERF_SDInitialization.H:853
Super-droplets initialization structure.
Definition: ERF_SDInitialization.H:628
amrex::Real m_numdens_accum
Definition: ERF_SDInitialization.H:653
unsigned int m_inject_seed
Definition: ERF_SDInitialization.H:685
int injectBoxCount() const override
Number of super-droplets to inject in the whole box this step.
Definition: ERF_SDInitialization.H:836
amrex::Real m_numdens_sd
Definition: ERF_SDInitialization.H:639
amrex::Real m_eff_sd_rate
Definition: ERF_SDInitialization.H:677
amrex::Real m_tstop
Definition: ERF_SDInitialization.H:648
amrex::Real m_inject_mult
Definition: ERF_SDInitialization.H:660
amrex::Real m_sd_inj_rate
Definition: ERF_SDInitialization.H:636
amrex::Real m_tstart
Definition: ERF_SDInitialization.H:645
void updateDt(const double a_dt, const bool a_active)
Update time-dependent quantities for particle injection.
Definition: ERF_SDInitialization.H:706
bool m_mm_specified
Definition: ERF_SDInitialization.H:675
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:830
bool m_sd_specified
Definition: ERF_SDInitialization.H:674
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:823
amrex::Real m_min_multiplicity
Definition: ERF_SDInitialization.H:665
int m_inject_num_sd
Definition: ERF_SDInitialization.H:658
amrex::Real injectMultiplicity() const override
Multiplicity of each super-droplet injected this step.
Definition: ERF_SDInitialization.H:837
bool m_ppc_specified
Definition: ERF_SDInitialization.H:673
void readInputs(SDInputs &, const std::string &, const amrex::Geometry &, const MatVec &, const MatVec &) override
Definition: ERF_SDInitialization.H:792
unsigned int injectSeed() const override
Reproducible seed for scattering this step's super-droplets.
Definition: ERF_SDInitialization.H:838
void printParameters(const MatVec &, const MatVec &) const override
Definition: ERF_SDInitialization.cpp:386
amrex::Real m_sd_accum
Definition: ERF_SDInitialization.H:681
amrex::Real m_box_volume
Definition: ERF_SDInitialization.H:679
amrex::Real m_frac_tol
Definition: ERF_SDInitialization.H:662
amrex::Real m_inj_rate
Definition: ERF_SDInitialization.H:634
unsigned int m_inject_count
Definition: ERF_SDInitialization.H:683
bool m_both_specified
Definition: ERF_SDInitialization.H:670
bool m_perbox
Definition: ERF_SDInitialization.H:668
amrex::Real m_cell_volume
Definition: ERF_SDInitialization.H:655
bool perBoxInjection() const override
Per-box high-multiplicity injection (false for initialization and legacy per-cell injection).
Definition: ERF_SDInitialization.H:835
virtual ~SDInjection()=default
std::string m_prefix
Definition: ERF_SDInitialization.H:687
amrex::Vector< amrex::Real > m_domain_vel
Definition: ERF_SDInitialization.H:642
@ T
Definition: ERF_IndexDefines.H:128
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