SPH
Galaxy.cpp
Go to the documentation of this file.
1 #include "sph/initial/Galaxy.h"
2 #include "gravity/BarnesHut.h"
4 #include "gravity/Moments.h"
5 #include "math/rng/Rng.h"
6 #include "quantities/IMaterial.h"
7 #include "quantities/Quantity.h"
8 #include "quantities/Storage.h"
9 #include "system/Factory.h"
10 #include "system/Profiler.h"
11 #include "system/Settings.impl.h"
12 #include "system/Statistics.h"
13 
15 
16 //-----------------------------------------------------------------------------------------------------------
17 // Galaxy
18 //-----------------------------------------------------------------------------------------------------------
19 
20 // clang-format off
21 template<>
23  { GalaxySettingsId::DISK_PARTICLE_COUNT, "disk.particle_count", 10000, "" },
24  { GalaxySettingsId::DISK_RADIAL_CUTOFF, "disk.radial_cutoff", 7.5_f, "" },
25  { GalaxySettingsId::DISK_RADIAL_SCALE, "disk.radial_scale", 1._f, "" },
26  { GalaxySettingsId::DISK_VERTICAL_SCALE, "disk.vertical_scale", 0.2_f, "" },
27  { GalaxySettingsId::DISK_VERTICAL_CUTOFF, "disk.vertical_cutoff", 0.6_f, "" },
28  { GalaxySettingsId::DISK_TOOMRE_Q, "disk.toomre_q", 1.2_f, "" },
29  { GalaxySettingsId::DISK_MASS, "disk.mass", 1._f, "" },
30  { GalaxySettingsId::HALO_PARTICLE_COUNT, "halo.particle_count", 10000, "" },
31  { GalaxySettingsId::HALO_SCALE_LENGTH, "halo.scale_length", 10._f, "" },
32  { GalaxySettingsId::HALO_GAMMA, "halo.gamma", 2._f, "" },
33  { GalaxySettingsId::HALO_CUTOFF, "halo.cutoff", 15._f, "" },
34  { GalaxySettingsId::HALO_MASS, "halo.mass", 5._f, "" },
35  { GalaxySettingsId::BULGE_PARTICLE_COUNT, "bulge.particle_count", 10000, "" },
36  { GalaxySettingsId::BULGE_SCALE_LENGTH, "bulge.scale_length", 0.4_f, "" },
37  { GalaxySettingsId::BULGE_CUTOFF, "bulge.cutoff", 5._f, "" },
38  { GalaxySettingsId::BULGE_MASS, "bulge.mass", 0.6_f, "" },
39  { GalaxySettingsId::PARTICLE_RADIUS, "particle_radius", 0.01_f, "" },
40 });
41 // clang-format on
42 
43 // Explicit instantiation
44 template class Settings<GalaxySettingsId>;
46 
48 
50 INLINE Float diskSurfacePdf(const Float r, const Float h) {
51  return exp(-r / h) * r;
52 }
53 
55 INLINE Float diskSurfaceDensity(const Float r, const Float h, const Float m_disk) {
56  return m_disk / (2._f * PI * sqr(h)) * exp(-r / h);
57 }
58 
60 INLINE Float diskVerticalPdf(const Float z, const Float z0) {
61  return 1._f / sqr(cosh(z / z0));
62 }
63 
65 INLINE Float haloPdf(const Float r, const Float r0, const Float g0) {
66  return exp(-sqr(r / r0)) / (sqr(r) + sqr(g0)) * sqr(r);
67 }
68 
69 INLINE Float maxHaloPdf(const Float r0, const Float g0) {
70  const Float x2 = 0.5_f * (sqrt(sqr(g0) * (sqr(g0) + 4._f * sqr(r0))) - sqr(g0));
71  SPH_ASSERT(x2 > 0._f);
72  return haloPdf(sqrt(x2), r0, g0);
73 }
74 
76 INLINE Float velocityPdf(const Float v, const Float sigma_r) {
77  return sqr(v) * exp(-0.5_f * sqr(v) / sigma_r);
78 }
79 
81 INLINE Float bulgePdf(const Float r, const Float a) {
82  return r / (sqr(a) * pow<3>(1._f + r / a));
83 }
84 
85 static Float getEpicyclicFrequency(IGravity& gravity, const Vector& r, const Vector& dv1, const Float dr) {
86  const Float radius = sqrt(sqr(r[X]) + sqr(r[Y])) + EPS;
87  const Vector dv2 = gravity.eval(r * (1._f + dr));
88 
89  const Float a1_rad = (dv1[X] * r[X] + dv1[Y] * r[Y]) / radius;
90  const Float a2_rad = (dv2[X] * r[X] + dv2[Y] * r[Y]) / radius;
91 
92  const Float k2 = (3._f / radius) * a1_rad + (a2_rad - a1_rad) / dr;
93  return sqrt(abs(k2));
94 }
95 
97  MEASURE_SCOPE("Galaxy::generateDisk");
98 
99  Array<Vector> positions;
100  const Size n_disk = settings.get<int>(GalaxySettingsId::DISK_PARTICLE_COUNT);
101  const Float r_cutoff = settings.get<Float>(GalaxySettingsId::DISK_RADIAL_CUTOFF);
102  const Float r0 = settings.get<Float>(GalaxySettingsId::DISK_RADIAL_SCALE);
103  const Float z_cutoff = settings.get<Float>(GalaxySettingsId::DISK_VERTICAL_CUTOFF);
105  const Float h = settings.get<Float>(GalaxySettingsId::PARTICLE_RADIUS);
106 
107  const Interval radialRange(0._f, r_cutoff);
108  const Interval verticalRange(-z_cutoff, z_cutoff);
109 
110  // radial PDF is maximal at r = r0
111  const Float maxSurfacePdf = diskSurfacePdf(r0, r0);
112 
113  // vertical pdf is maximal at z = 0
114  const Float maxVerticalPdf = diskVerticalPdf(0, z0);
115 
116  for (Size i = 0; i < n_disk; ++i) {
117  const Float r = sampleDistribution(
118  rng, radialRange, maxSurfacePdf, [r0](const Float x) { return diskSurfacePdf(x, r0); });
119 
120  const Float phi = rng() * 2._f * PI;
121 
122  const Float z = sampleDistribution(
123  rng, verticalRange, maxVerticalPdf, [z0](const Float x) { return diskVerticalPdf(x, z0); });
124 
125  Vector pos = cylindricalToCartesian(r, phi, z);
126  pos[H] = h;
127  positions.push(pos);
128  }
129 
130 
131  const Float m_disk = settings.get<Float>(GalaxySettingsId::DISK_MASS);
132  const Float m = m_disk / n_disk;
133 
134  Storage storage(makeShared<NullMaterial>(BodySettings::getDefaults()));
135  storage.insert<Vector>(QuantityId::POSITION, OrderEnum::SECOND, std::move(positions));
137  storage.insert<Size>(QuantityId::FLAG, OrderEnum::ZERO, Size(PartEnum::DISK));
138  return storage;
139 }
140 
142  MEASURE_SCOPE("Galaxy::generateHalo");
143 
144  const Size n_halo = settings.get<int>(GalaxySettingsId::HALO_PARTICLE_COUNT);
145  const Float cutoff = settings.get<Float>(GalaxySettingsId::HALO_CUTOFF);
146  const Float r0 = settings.get<Float>(GalaxySettingsId::HALO_SCALE_LENGTH);
147  const Float g0 = settings.get<Float>(GalaxySettingsId::HALO_GAMMA);
148  const Float h = settings.get<Float>(GalaxySettingsId::PARTICLE_RADIUS);
149  const Interval range(0._f, cutoff);
150 
151  const Float maxPdf = maxHaloPdf(r0, g0);
152 
153  Array<Vector> positions;
154  for (Size i = 0; i < n_halo; ++i) {
155  const Float r = sampleDistribution(rng, range, maxPdf, [r0, g0](const Float x) { //
156  return haloPdf(x, r0, g0);
157  });
158 
159  Vector pos = sampleUnitSphere(rng) * r;
160  pos[H] = h;
161  positions.push(pos);
162  }
163 
164  const Float m_halo = settings.get<Float>(GalaxySettingsId::HALO_MASS);
165  const Float m = m_halo / n_halo;
166 
167  Storage storage(makeShared<NullMaterial>(BodySettings::getDefaults()));
168  storage.insert<Vector>(QuantityId::POSITION, OrderEnum::SECOND, std::move(positions));
170  storage.insert<Size>(QuantityId::FLAG, OrderEnum::ZERO, Size(PartEnum::HALO));
171  return storage;
172 }
173 
175  MEASURE_SCOPE("Galaxy::generateBulge");
176 
177  const Size n_bulge = settings.get<int>(GalaxySettingsId::HALO_PARTICLE_COUNT);
178  const Float cutoff = settings.get<Float>(GalaxySettingsId::BULGE_CUTOFF);
180  const Float h = settings.get<Float>(GalaxySettingsId::PARTICLE_RADIUS);
181  const Interval range(0._f, cutoff);
182 
183  // PDF is maximal at x=a/2
184  const Float maxPdf = bulgePdf(0.5_f * a, a);
185 
186  Array<Vector> positions;
187  for (Size i = 0; i < n_bulge; ++i) {
188  const Float r = sampleDistribution(rng, range, maxPdf, [a](const Float x) { return bulgePdf(x, a); });
189 
190  Vector pos = sampleUnitSphere(rng) * r;
191  pos[H] = h;
192  positions.push(pos);
193  }
194 
195  const Float m_bulge = settings.get<Float>(GalaxySettingsId::BULGE_MASS);
196  const Float m = m_bulge / n_bulge;
197 
198  Storage storage(makeShared<NullMaterial>(BodySettings::getDefaults()));
199  storage.insert<Vector>(QuantityId::POSITION, OrderEnum::SECOND, std::move(positions));
201  storage.insert<Size>(QuantityId::FLAG, OrderEnum::ZERO, Size(PartEnum::BULGE));
202  return storage;
203 }
204 
205 static Array<Pair<Float>> computeCumulativeMass(const GalaxySettings& settings, const Storage& storage) {
206  MEASURE_SCOPE("computeCumulativeMass");
207 
208  constexpr Size MASS_BINS = 1000;
209 
210  const Float haloCutoff = settings.get<Float>(GalaxySettingsId::HALO_CUTOFF);
211  const Float dr = haloCutoff / MASS_BINS;
212 
215 
216  Array<Pair<Float>> cumulativeDist;
217  Array<Float> differentialDist(MASS_BINS);
218  differentialDist.fill(0._f);
219  for (Size i = 0; i < r.size(); ++i) {
220  const Float radius = getLength(r[i]);
221  const Size binIdx = Size(radius * MASS_BINS / haloCutoff);
222  SPH_ASSERT(binIdx < MASS_BINS);
223 
224  differentialDist[min(binIdx, MASS_BINS - 1)] += m[i];
225  }
226 
227  Float massSum = 0._f;
228  for (Size binIdx = 0; binIdx < MASS_BINS; ++binIdx) {
229  const Float binRadius = (binIdx + 1) * dr;
230  massSum += differentialDist[binIdx];
231  cumulativeDist.push(Pair<Float>{ binRadius, massSum });
232  }
233 
234  return cumulativeDist;
235 }
236 
237 static IndexSequence getPartSequence(const Storage& storage, const Galaxy::PartEnum id) {
239  Iterator<const Size> iterFrom, iterTo;
240  std::tie(iterFrom, iterTo) = std::equal_range(flag.begin(), flag.end(), Size(id));
241  return IndexSequence(
242  Size(std::distance(flag.begin(), iterFrom)), Size(std::distance(flag.begin(), iterTo)));
243 }
244 
245 static void computeDiskVelocities(IScheduler& scheduler,
246  UniformRng& rng,
247  const GalaxySettings& settings,
248  Storage& storage) {
249  MEASURE_SCOPE("computeDiskVelocities");
250 
251  const Float r0 = settings.get<Float>(GalaxySettingsId::DISK_RADIAL_SCALE);
253  const Float r_ref = 2.5_f * r0;
254  const Float r_cutoff = settings.get<Float>(GalaxySettingsId::DISK_RADIAL_CUTOFF);
255  const Float m_disk = settings.get<Float>(GalaxySettingsId::DISK_MASS);
256  const Float Q = settings.get<Float>(GalaxySettingsId::DISK_TOOMRE_Q);
257  // const Float double as = 0.25 * h;
258  const Float dr = 1.e-3_f * r_cutoff;
259  const Float as = 0.25_f * r0;
260 
261  ArrayView<Vector> r, v, dv;
262  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
263 
264  const IndexSequence sequence = getPartSequence(storage, Galaxy::PartEnum::DISK);
265 
267  // BruteForceGravity gravity(SolidSphereKernel{}, 1._f);
268  gravity.build(scheduler, storage);
269  Statistics stats;
270  std::fill(dv.begin(), dv.end(), Vector(0._f));
271  gravity.evalAll(scheduler, dv, stats);
272 
273  Float sigma = 0._f;
274  Size count = 0;
275  Float annulus = dr;
276  while (count == 0._f) {
277  for (Size i : sequence) {
278  const Float radius = sqrt(sqr(r[i][X]) + sqr(r[i][Y]));
279  if (abs(radius - r_ref) < annulus) {
280  const Float kappa = getEpicyclicFrequency(gravity, r[i], dv[i], 0.05_f * annulus);
281  sigma += 3.36_f * diskSurfaceDensity(radius, r0, m_disk) / kappa;
282  count++;
283  }
284  }
285  // if no particle lies in the annulus, try again with larger value
286  annulus *= 2._f;
287  }
288  SPH_ASSERT(count > 0);
289 
290  sigma = sigma * Q / count;
291 
292  const Float A = sqr(sigma) / diskSurfaceDensity(r_ref, r0, m_disk);
293  SPH_ASSERT(A >= 0._f, A);
294 
295  parallelFor(scheduler, sequence, [&](const Size i) {
296  const Float radius = sqrt(sqr(r[i][X]) + sqr(r[i][Y]));
297  const Float vz2 = PI * z0 * diskSurfaceDensity(sqrt(sqr(radius) + 2._f * sqr(as)), r0, m_disk);
298  const Float vz = sampleNormalDistribution(rng, 0._f, vz2);
299  SPH_ASSERT(vz2 > 0._f);
300 
301  const Float vr2 = A * vz2 / (PI * z0);
302  const Float vr = sampleNormalDistribution(rng, 0._f, vr2);
303  SPH_ASSERT(vr2 > 0._f);
304 
305  const Vector a = dv[i];
306  const Float ar = (a[X] * r[i][X] + a[Y] * r[i][Y]) / radius;
307  SPH_ASSERT(isReal(ar));
308 
309  const Float omega = sqrt(abs(ar) / radius);
310  SPH_ASSERT(isReal(omega));
311 
312  const Float kappa = getEpicyclicFrequency(gravity, r[i], dv[i], dr);
313  SPH_ASSERT(isReal(kappa));
314 
315  // circular velocity
316  const Float v_c = omega * radius;
317  Float va = sqrt(abs(sqr(v_c) + vr2 * (1._f - sqr(kappa) / (4._f * sqr(omega)) - 2._f * radius / r0)));
318  SPH_ASSERT(isReal(va));
319 
320  const Float sigma2 = vr2 * sqr(kappa) / (4._f * sqr(omega));
321  va += sampleNormalDistribution(rng, 0._f, sigma2);
322 
323  // transform to cartesian coordinates
324  const Float c = r[i][X] / radius;
325  const Float s = r[i][Y] / radius;
326  v[i][X] = vr * c - va * s;
327  v[i][Y] = vr * s + va * c;
328  v[i][Z] = vz;
329  });
330 }
331 
332 template <typename TFunc>
333 static void computeSphericalVelocities(UniformRng& rng,
334  ArrayView<const Pair<Float>> massDist,
335  const Galaxy::PartEnum partId,
336  Storage& storage,
337  const TFunc& func) {
338  const Float dr = massDist[1][0] - massDist[0][0];
339 
342 
343  const IndexSequence sequence = getPartSequence(storage, partId);
344  for (Size i : sequence) {
345  const Float radius = getLength(r[i]);
346  const Size firstBin = Size(radius / dr);
347 
348  const Float v_esc = sqrt(2._f * massDist[firstBin][1] / radius);
349 
350  Float vr2 = 0._f;
351  for (Size binIdx = firstBin; binIdx < massDist.size(); ++binIdx) {
352  vr2 += func(massDist[binIdx][0]) * dr * massDist[binIdx][1];
353  }
354  vr2 /= func(radius) / sqr(radius);
355 
356  const Interval range(0._f, 0.95_f * v_esc);
357  const Float maxPdf = velocityPdf(sqrt(2._f * vr2), vr2);
358 
359  const Float u = sampleDistribution(rng, range, maxPdf, [vr2](const Float x) { //
360  return velocityPdf(x, vr2);
361  });
362 
363  v[i] = sampleUnitSphere(rng) * u;
364  }
365 }
366 
367 static void computeHaloVelocities(UniformRng& rng,
368  const GalaxySettings& settings,
369  ArrayView<const Pair<Float>> massDist,
370  Storage& storage) {
371  MEASURE_SCOPE("computeHaloVelocities");
372 
373  const Float r0 = settings.get<Float>(GalaxySettingsId::HALO_SCALE_LENGTH);
374  const Float g0 = settings.get<Float>(GalaxySettingsId::HALO_GAMMA);
375 
376  computeSphericalVelocities(rng, massDist, Galaxy::PartEnum::HALO, storage, [r0, g0](const Float x) { //
377  return haloPdf(x, r0, g0);
378  });
379 }
380 
381 static void computeBulgeVelocities(UniformRng& rng,
382  const GalaxySettings& settings,
383  ArrayView<const Pair<Float>> massDist,
384  Storage& storage) {
385  MEASURE_SCOPE("computeBulgeVelocities");
386 
388 
389  computeSphericalVelocities(rng, massDist, Galaxy::PartEnum::BULGE, storage, [a](const Float x) { //
390  return bulgePdf(x, a);
391  });
392 }
393 
395 public:
399 
400  const Size numParts = 8;
401 
402 public:
404  : callbacks(callbacks) {}
405 
408  ++partId;
409 
410  return storage;
411  }
412 
414  return &operator*();
415  }
416 
418  return std::move(storage);
419  }
420 };
421 
423  const GalaxySettings& settings,
424  const IProgressCallbacks& callbacks) {
425  const int seed = globals.get<int>(RunSettingsId::RUN_RNG_SEED);
426  UniformRng rng(seed);
427  SharedPtr<IScheduler> scheduler = Factory::getScheduler(globals);
428 
429  StorageBuilder builder(callbacks);
430  builder->merge(generateDisk(rng, settings));
431  builder->merge(generateHalo(rng, settings));
432  builder->merge(generateBulge(rng, settings));
433 
434  Array<Pair<Float>> massDist = computeCumulativeMass(settings, *builder);
435  computeDiskVelocities(*scheduler, rng, settings, *builder);
436  computeHaloVelocities(rng, settings, massDist, *builder);
437  computeBulgeVelocities(rng, settings, massDist, *builder);
438 
439  Storage storage = std::move(builder).release();
441  SPH_ASSERT(std::is_sorted(flag.begin(), flag.end()));
442  return storage;
443 }
444 
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
Barnes-Hut algorithm for computation of gravitational acceleration.
Simple gravity solver evaluating all particle pairs.
const float radius
Definition: CurveDialog.cpp:18
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
Definition: Globals.h:13
Base class for all particle materials.
NAMESPACE_SPH_BEGIN constexpr INLINE T min(const T &f1, const T &f2)
Minimum & Maximum value.
Definition: MathBasic.h:15
constexpr Float EPS
Definition: MathUtils.h:30
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
INLINE T sqrt(const T f)
Return a squared root of a value.
Definition: MathUtils.h:78
constexpr INLINE Float pow< 3 >(const Float v)
Definition: MathUtils.h:132
INLINE T exp(const T f)
Definition: MathUtils.h:269
INLINE auto abs(const T &f)
Definition: MathUtils.h:276
constexpr Float PI
Mathematical constants.
Definition: MathUtils.h:361
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define NAMESPACE_SPH_END
Definition: Object.h:12
Tool to measure time spent in functions and profile the code.
#define MEASURE_SCOPE(name)
Definition: Profiler.h:70
@ FLAG
ID of original body, used to implement discontinuities between bodies in SPH.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ MASS
Paricles masses, always a scalar quantity.
Holder of quantity values and their temporal derivatives.
@ SECOND
Quantity with 1st and 2nd derivative.
@ ZERO
Quantity without derivatives, or "zero order" of quantity.
Random number generators.
INLINE Vector sampleUnitSphere(TRng &rng)
Generates a random position on a unit sphere.
Definition: Rng.h:166
INLINE Float sampleNormalDistribution(TRng &rng, const Float mu, const Float sigma)
Generates a random number from normal distribution, using Box-Muller algorithm.
Definition: Rng.h:120
INLINE Float sampleDistribution(TRng &rng, const Interval &range, const Float upperBound, const TFunc &func)
Generates a random number from a generic distribution, using rejection sampling.
Definition: Rng.h:184
INLINE void parallelFor(IScheduler &scheduler, const Size from, const Size to, TFunctor &&functor)
Executes a functor concurrently from all available threads.
Definition: Scheduler.h:98
StaticArray< T0 &, sizeof...(TArgs)+1 > tie(T0 &t0, TArgs &... rest)
Creates a static array from a list of l-value references.
Definition: StaticArray.h:281
Statistics gathered and periodically displayed during the run.
Container for storing particle quantities and materials.
INLINE Vector cylindricalToCartesian(const Float r, const Float phi, const Float z)
Constructs a vector from cylindrical coordinates.
Definition: Vector.h:795
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
Definition: Vector.h:579
INLINE Float distance(const Vector &r, const Vector &axis)
Returns the distance of vector from given axis. The axis is assumed to be normalized.
Definition: Vector.h:827
@ H
Definition: Vector.h:25
@ Y
Definition: Vector.h:23
@ X
Definition: Vector.h:22
@ Z
Definition: Vector.h:24
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
INLINE TCounter size() const
Definition: ArrayView.h:101
INLINE Iterator< StorageType > begin()
Definition: ArrayView.h:55
INLINE Iterator< StorageType > end()
Definition: ArrayView.h:63
Generic dynamically allocated resizable storage.
Definition: Array.h:43
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
Definition: Array.h:306
Wrapper of pointer that deletes the resource from destructor.
Definition: AutoPtr.h:15
Multipole approximation of distance particle.
Definition: BarnesHut.h:43
Interface for computing gravitational interactions of particles.
Definition: IGravity.h:14
Interface that allows unified implementation of sequential and parallelized versions of algorithms.
Definition: Scheduler.h:27
Object representing a 1D interval of real numbers.
Definition: Interval.h:17
Simple (forward) iterator over continuous array of objects of type T.
Definition: Iterator.h:18
Iterator useful for iterating over all entries in the settings.
Definition: Settings.h:486
Generic object containing various settings and parameters of the run.
Definition: Settings.h:108
TValue get(const TEnum idx, std::enable_if_t<!std::is_enum< std::decay_t< TValue >>::value, int >=0) const
Returns a value of given type from the settings.
Definition: Settings.h:326
static const Settings & getDefaults()
\brief Returns a reference to object containing default values of all settings.
Gravity kernel of a solid sphere.
Array with fixed number of allocated elements.
Definition: StaticArray.h:19
Object holding various statistics about current run.
Definition: Statistics.h:22
StorageBuilder(const Galaxy::IProgressCallbacks &callbacks)
Definition: Galaxy.cpp:403
const Galaxy::IProgressCallbacks & callbacks
Definition: Galaxy.cpp:397
const Size numParts
Definition: Galaxy.cpp:400
Storage & operator*()
Definition: Galaxy.cpp:406
Storage storage
Definition: Galaxy.cpp:396
Storage release() &&
Definition: Galaxy.cpp:417
Storage * operator->()
Definition: Galaxy.cpp:413
Container storing all quantities used within the simulations.
Definition: Storage.h:230
void merge(Storage &&other)
Merges another storage into this object.
Definition: Storage.cpp:472
Quantity & insert(const QuantityId key, const OrderEnum order, const TValue &defaultValue)
Creates a quantity in the storage, given its key, value type and order.
Definition: Storage.cpp:270
StaticArray< Array< TValue > &, 3 > getAll(const QuantityId key)
Retrieves quantity buffers from the storage, given its key and value type.
Definition: Storage.cpp:163
Array< TValue > & getDt(const QuantityId key)
Retrieves a quantity derivative from the storage, given its key and value type.
Definition: Storage.cpp:217
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
Definition: Storage.cpp:191
Random number generator with uniform distribution.
Definition: Rng.h:16
INLINE Float diskSurfaceDensity(const Float r, const Float h, const Float m_disk)
Normalized surface density of a disk.
Definition: Galaxy.cpp:55
INLINE Float diskVerticalPdf(const Float z, const Float z0)
Vertical mass distribution of a disk.
Definition: Galaxy.cpp:60
INLINE Float bulgePdf(const Float r, const Float a)
Probability distribution function of a bulge.
Definition: Galaxy.cpp:81
INLINE Float velocityPdf(const Float v, const Float sigma_r)
Probability distribution function for velocities in halo and bulge.
Definition: Galaxy.cpp:76
INLINE Float diskSurfacePdf(const Float r, const Float h)
Mostly uses methods described in https://github.com/nmuldavin/NBodyIntegrator.
Definition: Galaxy.cpp:50
INLINE Float haloPdf(const Float r, const Float r0, const Float g0)
Probability distribution function of a halo.
Definition: Galaxy.cpp:65
INLINE Float maxHaloPdf(const Float r0, const Float g0)
Definition: Galaxy.cpp:69
Creating code components based on values from settings.
@ RUN_RNG_SEED
Seed for the random-number generator.
constexpr Float gravity
Gravitational constant (CODATA 2014)
Definition: Constants.h:29
SharedPtr< IScheduler > getScheduler(const RunSettings &settings=RunSettings::getDefaults())
Definition: Factory.cpp:178
Storage generateBulge(UniformRng &rng, const GalaxySettings &settings)
Definition: Galaxy.cpp:174
Storage generateDisk(UniformRng &rng, const GalaxySettings &settings)
Definition: Galaxy.cpp:96
Storage generateHalo(UniformRng &rng, const GalaxySettings &settings)
Definition: Galaxy.cpp:141
PartEnum
Definition: Galaxy.h:38
Storage generateIc(const RunSettings &globals, const GalaxySettings &settings, const IProgressCallbacks &callbacks)
Definition: Galaxy.cpp:422
virtual void onPart(const Storage &storage, const Size partId, const Size numParts) const =0
Called when computing new part of the galaxy (particle positions or velocities).