51 return exp(-r / h) * r;
56 return m_disk / (2._f *
PI *
sqr(h)) *
exp(-r / h);
61 return 1._f /
sqr(cosh(z / z0));
77 return sqr(v) *
exp(-0.5_f *
sqr(v) / sigma_r);
82 return r / (
sqr(a) *
pow<3>(1._f + r / a));
92 const Float k2 = (3._f /
radius) * a1_rad + (a2_rad - a1_rad) / dr;
107 const Interval radialRange(0._f, r_cutoff);
108 const Interval verticalRange(-z_cutoff, z_cutoff);
116 for (
Size i = 0; i < n_disk; ++i) {
120 const Float phi = rng() * 2._f *
PI;
132 const Float m = m_disk / n_disk;
154 for (
Size i = 0; i < n_halo; ++i) {
165 const Float m = m_halo / n_halo;
187 for (
Size i = 0; i < n_bulge; ++i) {
196 const Float m = m_bulge / n_bulge;
208 constexpr
Size MASS_BINS = 1000;
211 const Float dr = haloCutoff / MASS_BINS;
218 differentialDist.fill(0._f);
219 for (
Size i = 0; i < r.
size(); ++i) {
224 differentialDist[
min(binIdx, MASS_BINS - 1)] += m[i];
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 });
234 return cumulativeDist;
245 static void computeDiskVelocities(
IScheduler& scheduler,
253 const Float r_ref = 2.5_f * r0;
258 const Float dr = 1.e-3_f * r_cutoff;
259 const Float as = 0.25_f * r0;
268 gravity.build(scheduler, storage);
271 gravity.evalAll(scheduler, dv, stats);
276 while (count == 0._f) {
277 for (
Size i : sequence) {
280 const Float kappa = getEpicyclicFrequency(
gravity, r[i], dv[i], 0.05_f * annulus);
290 sigma = sigma * Q / count;
301 const Float vr2 = A * vz2 / (
PI * z0);
312 const Float kappa = getEpicyclicFrequency(
gravity, r[i], dv[i], dr);
320 const Float sigma2 = vr2 *
sqr(kappa) / (4._f *
sqr(omega));
326 v[i][
X] = vr * c - va * s;
327 v[i][
Y] = vr * s + va * c;
332 template <
typename TFunc>
333 static void computeSphericalVelocities(
UniformRng& rng,
338 const Float dr = massDist[1][0] - massDist[0][0];
343 const IndexSequence sequence = getPartSequence(storage, partId);
344 for (
Size i : sequence) {
351 for (
Size binIdx = firstBin; binIdx < massDist.size(); ++binIdx) {
352 vr2 += func(massDist[binIdx][0]) * dr * massDist[binIdx][1];
356 const Interval range(0._f, 0.95_f * v_esc);
367 static void computeHaloVelocities(
UniformRng& rng,
381 static void computeBulgeVelocities(
UniformRng& rng,
435 computeDiskVelocities(*scheduler, rng, settings, *builder);
436 computeHaloVelocities(rng, settings, massDist, *builder);
437 computeBulgeVelocities(rng, settings, massDist, *builder);
439 Storage storage = std::move(builder).release();
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
Barnes-Hut algorithm for computation of gravitational acceleration.
Simple gravity solver evaluating all particle pairs.
uint32_t Size
Integral type used to index arrays (by default).
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
Base class for all particle materials.
NAMESPACE_SPH_BEGIN constexpr INLINE T min(const T &f1, const T &f2)
Minimum & Maximum value.
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
INLINE T sqrt(const T f)
Return a squared root of a value.
constexpr INLINE Float pow< 3 >(const Float v)
INLINE auto abs(const T &f)
constexpr Float PI
Mathematical constants.
#define INLINE
Macros for conditional compilation based on selected compiler.
#define NAMESPACE_SPH_END
Tool to measure time spent in functions and profile the code.
#define MEASURE_SCOPE(name)
@ 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.
INLINE Float sampleNormalDistribution(TRng &rng, const Float mu, const Float sigma)
Generates a random number from normal distribution, using Box-Muller algorithm.
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.
INLINE void parallelFor(IScheduler &scheduler, const Size from, const Size to, TFunctor &&functor)
Executes a functor concurrently from all available threads.
StaticArray< T0 &, sizeof...(TArgs)+1 > tie(T0 &t0, TArgs &... rest)
Creates a static array from a list of l-value references.
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.
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
INLINE Float distance(const Vector &r, const Vector &axis)
Returns the distance of vector from given axis. The axis is assumed to be normalized.
Object providing safe access to continuous memory of data.
INLINE TCounter size() const
INLINE Iterator< StorageType > begin()
INLINE Iterator< StorageType > end()
Generic dynamically allocated resizable storage.
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
Wrapper of pointer that deletes the resource from destructor.
Multipole approximation of distance particle.
Interface for computing gravitational interactions of particles.
Interface that allows unified implementation of sequential and parallelized versions of algorithms.
Object representing a 1D interval of real numbers.
Simple (forward) iterator over continuous array of objects of type T.
Iterator useful for iterating over all entries in the settings.
Generic object containing various settings and parameters of the run.
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.
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.
Object holding various statistics about current run.
StorageBuilder(const Galaxy::IProgressCallbacks &callbacks)
const Galaxy::IProgressCallbacks & callbacks
Container storing all quantities used within the simulations.
void merge(Storage &&other)
Merges another storage into this object.
Quantity & insert(const QuantityId key, const OrderEnum order, const TValue &defaultValue)
Creates a quantity in the storage, given its key, value type and order.
StaticArray< Array< TValue > &, 3 > getAll(const QuantityId key)
Retrieves quantity buffers from the storage, given its key and value type.
Array< TValue > & getDt(const QuantityId key)
Retrieves a quantity derivative from the storage, given its key and value type.
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
INLINE Float diskSurfaceDensity(const Float r, const Float h, const Float m_disk)
Normalized surface density of a disk.
INLINE Float diskVerticalPdf(const Float z, const Float z0)
Vertical mass distribution of a disk.
INLINE Float bulgePdf(const Float r, const Float a)
Probability distribution function of a bulge.
INLINE Float velocityPdf(const Float v, const Float sigma_r)
Probability distribution function for velocities in halo and bulge.
INLINE Float diskSurfacePdf(const Float r, const Float h)
Mostly uses methods described in https://github.com/nmuldavin/NBodyIntegrator.
INLINE Float haloPdf(const Float r, const Float r0, const Float g0)
Probability distribution function of a halo.
INLINE Float maxHaloPdf(const Float r0, const Float g0)
Creating code components based on values from settings.
@ RUN_RNG_SEED
Seed for the random-number generator.
constexpr Float gravity
Gravitational constant (CODATA 2014)
SharedPtr< IScheduler > getScheduler(const RunSettings &settings=RunSettings::getDefaults())
Storage generateBulge(UniformRng &rng, const GalaxySettings &settings)
Storage generateDisk(UniformRng &rng, const GalaxySettings &settings)
Storage generateHalo(UniformRng &rng, const GalaxySettings &settings)
Storage generateIc(const RunSettings &globals, const GalaxySettings &settings, const IProgressCallbacks &callbacks)
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).