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