chombo-discharge
Loading...
Searching...
No Matches
CD_RandomImplem.H
Go to the documentation of this file.
1/* chombo-discharge
2 * Copyright © 2021 SINTEF Energy Research.
3 * Please refer to Copyright.txt and LICENSE in the chombo-discharge root directory.
4 */
5
12#ifndef CD_RandomImplem_H
13#define CD_RandomImplem_H
14
15// Std includes
16#include <chrono>
17#include <omp.h>
18
19// Chombo includes
20#include <SPMD.H>
21#include <CH_Timer.H>
22#include <ParmParse.H>
23
24// Our includes
25#include <CD_Random.H>
26#include <CD_NamespaceHeader.H>
27
28inline void
30{
31 if (!s_seeded) {
32 ParmParse pp("Random");
33
34 if (pp.contains("seed")) {
35 int seed;
36 pp.get("seed", seed);
37 if (seed < 0) {
39 }
40 else {
42 }
43 }
44 else {
46 }
47
48 s_seeded = true;
49 }
50}
51
52inline void
54{
55#ifdef CH_MPI
56#ifdef _OPENMP
57#pragma omp parallel
58 {
60
61 s_rng = std::mt19937_64(seed);
62 }
63#else
64 const int seed = a_seed + procID();
65
66 s_rng = std::mt19937_64(seed);
67#endif
68#else
69#ifdef _OPENMP
70#pragma omp parallel
71 {
72 const int seed = a_seed + omp_get_thread_num();
73
74 s_rng = std::mt19937_64(seed);
75 }
76#else
77 const int seed = a_seed;
78
79 s_rng = std::mt19937_64(seed);
80#endif
81#endif
82
83 s_seeded = true;
84}
85
86inline void
88{
89 int seed = std::chrono::system_clock::now().time_since_epoch().count();
90
91 // Special hook for MPI -- master rank broadcasts the seed and everyone increments by their processor ID.
92#ifdef CH_MPI
94#endif
95
97}
98
99template <typename T, typename>
100inline T
102{
103 CH_TIME("Random::getPoisson");
104
105 CH_assert(s_seeded);
106
107 T ret = (T)0;
108
109 if (a_mean < 250.0) {
111
112 ret = poisson(s_rng);
113 }
114 else {
116
117 ret = (T)std::max(normal(s_rng), (Real)0.0);
118 }
119
120 return ret;
121}
122
123template <typename T, typename>
124inline T
125Random::getBinomial(const T a_N, const Real a_p) noexcept
126{
127 CH_TIME("Random::getBinomial");
128
129 CH_assert(s_seeded);
130
131 T ret = 0;
132
133 const bool useNormalApprox = (a_N > (T)9.0 * ((1.0 - a_p) / a_p)) && (a_N > (T)9.0 * a_p / (1.0 - a_p));
134
135 if (useNormalApprox) {
136 const Real mean = a_N * a_p;
137
139
140 ret = (T)std::max(normalDist(s_rng), (Real)0.0);
141 }
142 else {
144
145 ret = binomDist(s_rng);
146 }
147
148 return ret;
149}
150
151inline Real
153{
154 CH_TIME("Random::getUniformReal01");
155
156 CH_assert(s_seeded);
157
158 return s_uniform01(s_rng);
159}
160
161inline Real
163{
164 CH_TIME("Random::getUniformReal11");
165
166 CH_assert(s_seeded);
167
168 return s_uniform11(s_rng);
169}
170
171inline Real
173{
174 CH_TIME("Random::getNormal01");
175
176 CH_assert(s_seeded);
177
178 return s_normal01(s_rng);
179}
180
181inline RealVect
183{
184 CH_TIME("Random::getDirection");
185
186 CH_assert(s_seeded);
187
188 constexpr Real safety = 1.E-12;
189
190#if CH_SPACEDIM == 2
191 Real x1 = 2.0;
192 Real x2 = 2.0;
193 Real r = x1 * x1 + x2 * x2;
194 while (r >= 1.0 || r < safety) {
197 r = x1 * x1 + x2 * x2;
198 }
199
200 return RealVect(x1, x2) / sqrt(r);
201#elif CH_SPACEDIM == 3
202 Real x1 = 2.0;
203 Real x2 = 2.0;
204 Real r = x1 * x1 + x2 * x2;
205 while (r >= 1.0 || r < safety) {
208 r = x1 * x1 + x2 * x2;
209 }
210
211 const Real x = 2 * x1 * sqrt(1 - r);
212 const Real y = 2 * x2 * sqrt(1 - r);
213 const Real z = 1 - 2 * r;
214
215 return RealVect(x, y, z);
216#endif
217}
218
219template <typename T>
220inline Real
222{
223 CH_TIME("Random::get");
224
225 CH_assert(s_seeded);
226
227 return a_distribution(s_rng);
228}
229
230template <typename T>
231inline size_t
233{
234 CH_TIME("Random::getDiscrete");
235
236 CH_assert(s_seeded);
237
238 return a_distribution(s_rng);
239}
240
241inline RealVect
243 const RealVect a_lo,
244 const RealVect a_hi,
247 const Real a_dx,
248 const Real a_kappa) noexcept
249{
250 CH_TIME("Random::randomPosition(full)");
251
253
254 if (a_kappa < 1.0) { // Rejection sampling.
256 }
257 else { // Regular cell. Get a position.
259 }
260
261 // Convert from unit cell coordinates to physical coordinates.
262 pos = a_cellPos + pos * a_dx;
263
264 return pos;
265}
266
267inline RealVect
269 const RealVect a_hi,
271 const RealVect a_bndryNormal) noexcept
272{
273 CH_TIME("Random::randomPosition(partial)");
274
275 // Draw a position.
277 bool valid = (pos - a_bndryCentroid).dotProduct(a_bndryNormal) >= 0.0;
278
279 // Rejectino sampling.
280 while (!valid) {
282 valid = (pos - a_bndryCentroid).dotProduct(a_bndryNormal) >= 0.0;
283 }
284
285 return pos;
286}
287
288inline RealVect
290{
291 CH_TIME("Random::randomPosition(box)");
292
294
295 for (int dir = 0; dir < SpaceDim; dir++) {
297 }
298
299 return pos;
300}
301
302#include <CD_NamespaceFooter.H>
303
304#endif
File containing some useful static methods related to random number generation.
static Real get(T &a_distribution)
For getting a random number from a user-supplied distribution. T must be a distribution for which we ...
Definition CD_RandomImplem.H:221
static void setRandomSeed()
Set a random RNG seed.
Definition CD_RandomImplem.H:87
static RealVect getDirection()
Get a random direction in space.
Definition CD_RandomImplem.H:182
static Real getUniformReal11()
Get a uniform real number on the interval [-1,1].
Definition CD_RandomImplem.H:162
static size_t getDiscrete(T &a_distribution)
For getting a random number from a user-supplied distribution. T must be a distribution for which we ...
Definition CD_RandomImplem.H:232
static Real getUniformReal01()
Get a uniform real number on the interval [0,1].
Definition CD_RandomImplem.H:152
static Real getNormal01()
Get a number from a normal distribution centered on zero and variance 1.
Definition CD_RandomImplem.H:172
static void seed()
Seed the RNG.
Definition CD_RandomImplem.H:29
static void setSeed(const int a_seed)
Set the RNG seed.
Definition CD_RandomImplem.H:53
static T getPoisson(const Real a_mean)
Get Poisson distributed number.
Definition CD_RandomImplem.H:101
static T getBinomial(const T a_N, const Real a_p) noexcept
Get Poisson distributed number.
Definition CD_RandomImplem.H:125
static RealVect randomPosition(const RealVect a_lo, const RealVect a_hi) noexcept
Return a random position in the cube (a_lo, a_hi);.
Definition CD_RandomImplem.H:289
Base class for a tracer particle solver. This solver can advance particles in a pre-defined velocity ...
Definition CD_TracerParticleSolver.H:37
TracerParticleSolver()
Default constructor.
Definition CD_TracerParticleSolverImplem.H:25