21 : rng(
std::move(rng)) {}
36 for (
Size i = 0; i < 1e5 * n && found < n; ++i) {
54 Size particlesPerRegion = n;
55 while (particlesPerRegion > 1000) {
58 particlesPerRegion = n / numRegions;
75 const Vector step(findStep(bounds, n));
76 for (
Size i = 0; i < 1e5 * n && found < n; ++i) {
77 bounds.
iterate(step, [h, &step, &vecs, &found, &domain, &boxRng](
const Vector& r) {
78 const Box box(r, r + step);
100 const Float particleDensity =
Float(n) / volume;
108 const Box box(boundingBox.
lower() + 0.5_f * step, boundingBox.
upper());
113 vecs.push(std::move(v));
128 , progressCallback(progressCallback) {}
136 const Float particleDensity =
Float(n) / volume;
141 const Float dy =
sqrt(3._f) * 0.5_f * dx;
146 const Vector step(dx, dy, dz);
149 :
Box(boundingBox.
lower() + 0.5_f * step, boundingBox.
upper());
151 const Float deltaX = 0.5_f * dx;
152 const Float deltaY =
sqrt(3._f) / 6._f * dx;
153 const Size progressStep = progressCallback ?
max(n / 1000, 1u) :
Size(-1);
156 if (idxs[2] % 2 == 0) {
157 if (idxs[1] % 2 == 1) {
161 if (idxs[1] % 2 == 0) {
168 vecs.push(std::move(v));
170 if (vecs.size() % progressStep == 0) {
171 progressCallback(Float(vecs.size()) / n);
175 if (flags.
has(Options::SORTED)) {
177 std::sort(vecs.begin(), vecs.end(), [&box](
Vector& v1,
Vector& v2) {
179 const Vector vr1 = (v1 - box.lower()) / box.size();
180 const Vector vr2 = (v2 - box.lower()) / box.size();
181 return morton(vr1) > morton(vr2);
184 if (flags.
has(Options::CENTER)) {
187 for (
const Vector& v : vecs) {
192 Vector delta = domain.getCenter() - com;
210 class ForwardingDomain :
public IDomain {
215 explicit ForwardingDomain(
const IDomain& domain)
241 return domain.
getSubset(vs, output, type);
254 const Float eps = 0.05_f)
const override {
270 template <
typename TDensity>
271 static auto renormalizeDensity(
const IDomain& domain,
Size& n,
const Size error, TDensity& density) {
275 auto actDensity = [&domain, &density, &multiplier](
const Vector& v) {
277 return multiplier * density(v);
286 for (particleCnt = mc.integrate(actDensity);
abs(particleCnt - n) > error;) {
287 const Float ratio = n /
max(particleCnt, 1._f);
290 particleCnt = mc.integrate(actDensity);
295 n =
Size(particleCnt);
297 return [&domain, &density, multiplier](
const Vector& v) {
299 return multiplier * density(v);
310 template <
typename TDensity>
316 for (
Size i = 0; i <
N; ++i) {
318 const Float n = density(pos);
331 const Size expectedN,
340 Storage storage = generateInitial(domain,
N, actDensity);
347 finder.
build(scheduler, r);
351 const Float kernelRadius = 2._f;
355 VerboseLogGuard guard(
"DiehlDistribution::generate - iteration " + std::to_string(k));
366 bc.initialize(storage);
370 finder.
build(scheduler, r);
376 const Float rhoi = actDensity(r[i]);
378 const Float neighbourRadius = kernelRadius /
root<3>(rhoi);
379 finder.
findAll(i, neighbourRadius, neighsTl);
381 for (
Size j = 0; j < neighsTl.size(); ++j) {
382 const Size k = neighsTl[j].index;
383 const Vector diff = r[k] - r[i];
386 const Float rhok = (k >=
N) ? rhoi : actDensity(r[k]);
387 if (rhoi == 0._f || rhok == 0._f) {
393 if (lengthSqr > h * h || lengthSqr == 0) {
396 const Float hSqrInv = 1._f / (h * h);
399 const Vector diffUnit = diff / length;
403 deltas[i] += diffUnit *
min(t, h);
412 for (
Size i = 0; i < deltas.
size(); ++i) {
417 bc.finalize(storage);
425 for (
Size i = 0; i <
N; ++i) {
454 for (
Size i = 0; i < numShells; ++i) {
455 shells[i] =
sqr((i + 1) * h);
461 for (
Size i = 0; i < numShells; ++i) {
469 for (
Float r = h; r <= R; r += h, shellIdx++) {
474 for (
Size k = 1; k < m; ++k) {
477 phi += 3.8_f /
sqrt(m * (1._f -
sqr(hk)));
499 for (
Size i = 0; i < n; ++i) {
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
Filling spatial domain with SPH particles.
Object defining computational domain.
INLINE Float maxElement(const T &value)
Returns maximum element, simply the value iself by default.
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.
#define VERBOSE_LOG
Helper macro, creating.
constexpr INLINE T max(const T &f1, const T &f2)
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 Float root< 3 >(const Float f)
INLINE auto ceil(const T &f)
INLINE auto abs(const T &f)
constexpr Float PI
Mathematical constants.
#define NAMESPACE_SPH_END
Wrapper of type value of which may or may not be present.
const NothingType NOTHING
Tool to measure time spent in functions and profile the code.
#define PROFILE_SCOPE(name)
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
Holder of quantity values and their temporal derivatives.
@ ZERO
Quantity without derivatives, or "zero order" of quantity.
INLINE Vector sampleUnitSphere(TRng &rng)
Generates a random position on a unit sphere.
AutoPtr< RngWrapper< TRng > > makeRng(TArgs &&... args)
INLINE void parallelFor(IScheduler &scheduler, const Size from, const Size to, TFunctor &&functor)
Executes a functor concurrently from all available threads.
Container for storing particle quantities and materials.
Template for thread-local storage.
Objects for generating random vectors.
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
INLINE Float getSqrLength(const Vector &v)
BasicVector< Float > Vector
INLINE Vector sphericalToCartesian(const Float r, const Float theta, const Float phi)
Constructs a vector from spherical coordinates.
static AffineMatrix rotateAxis(const Vector &axis, const Float angle)
Object providing safe access to continuous memory of data.
Generic dynamically allocated resizable storage.
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
void fill(const T &t)
Sets all elements of the array to given value.
INLINE TCounter size() const noexcept
Helper object defining three-dimensional interval (box).
INLINE const Vector & lower() const
Returns lower bounds of the box.
INLINE const Vector & upper() const
Returns upper bounds of the box.
INLINE Vector size() const
Returns box dimensions.
void iterateWithIndices(const Vector &step, TFunctor &&functor) const
Execute functor for all possible values of vector (with constant stepping), passing auxiliary indices...
INLINE Float volume() const
Returns the volume of the box.
void iterate(const Vector &step, TFunctor &&functor) const
Execute functor for all possible values of vector (with constant stepping)
virtual Array< Vector > generate(IScheduler &scheduler, const Size n, const IDomain &domain) const override
Generates the requested number of particles in the domain.
DiehlDistribution(const DiehlParams ¶ms)
Constructs the distribution.
virtual Array< Vector > generate(IScheduler &scheduler, const Size n, const IDomain &domain) const override
Returns generated particle distribution.
virtual Size findAll(const Size index, const Float radius, Array< NeighbourRecord > &neighbours) const override
Finds all neighbours within given radius from the point given by index.
constexpr INLINE bool has(const TEnum flag) const
Checks if the object has a given flag.
Adds ghost particles symmetrically for each SPH particle close to boundary.
HexagonalPacking(const Flags< Options > flags=Options::CENTER)
virtual Array< Vector > generate(IScheduler &scheduler, const Size n, const IDomain &domain) const override
Generates the requested number of particles in the domain.
@ SPH5_COMPATIBILITY
Generates the grid to match code SPH5 for 1-1 comparison.
Base class for computational domains.
virtual Float getSurfaceArea() const =0
Returns the surface area of the domain.
virtual void getSubset(ArrayView< const Vector > vs, Array< Size > &output, const SubsetType type) const =0
Returns an array of indices, marking vectors with given property by their index.
virtual void getDistanceToBoundary(ArrayView< const Vector > vs, Array< Float > &distances) const =0
Returns distances of particles lying close to the boundary.
virtual Box getBoundingBox() const =0
Returns the bounding box of the domain.
virtual Float getVolume() const =0
Returns the total volume of the domain.
virtual void project(ArrayView< Vector > vs, Optional< ArrayView< Size >> indices=NOTHING) const =0
Projects vectors outside of the domain onto its boundary.
virtual void addGhosts(ArrayView< const Vector > vs, Array< Ghost > &ghosts, const Float eta=2._f, const Float eps=0.05_f) const =0
Duplicates positions located close to the boundary, placing copies ("ghosts") symmetrically to the ot...
virtual bool contains(const Vector &v) const =0
Checks if the given point lies inside the domain.
virtual Vector getCenter() const =0
Returns the center of the domain.
Interface that allows unified implementation of sequential and parallelized versions of algorithms.
void build(IScheduler &scheduler, ArrayView< const Vector > points, Flags< FinderFlag > flags=FinderFlag::MAKE_RANK)
Constructs the struct with an array of vectors.
Helper object for storing three (possibly four) int or bool values.
Object for integrating a generic three-dimensional scalar function.
virtual Array< Vector > generate(IScheduler &scheduler, const Size n, const IDomain &domain) const override
Generates the requested number of particles in the domain.
Wrapper of type value of which may or may not be present.
virtual Array< Vector > generate(IScheduler &scheduler, const Size n, const IDomain &domain) const override
Generates the requested number of particles in the domain.
ParametrizedSpiralingDistribution(const Size seed)
virtual Array< Vector > generate(IScheduler &scheduler, const Size n, const IDomain &domain) const override
Generates the requested number of particles in the domain.
RandomDistribution(AutoPtr< IRng > &&rng)
Creates a random distribution given random number generator.
Container storing all quantities used within the simulations.
Quantity & insert(const QuantityId key, const OrderEnum order, const TValue &defaultValue)
Creates a quantity in the storage, given its key, value type and order.
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
virtual Array< Vector > generate(IScheduler &scheduler, const Size n, const IDomain &domain) const override
Generates the requested number of particles in the domain.
StratifiedDistribution(const Size seed)
Template for storing a copy of a value for every thread in given scheduler.
Generic generator of random vectors using sampling with given PDF.
Wrapper for generating random vectors.
RAII guard writing called functions and their durations to a special verbose logger.
Overload of std::swap for Sph::Array.
Parameters of DiehlDistribution.
Float small
Normalization value to prevent division by zero for overlapping particles.
DensityFunc particleDensity
Function specifies the particle density in space.
Size numOfIters
Number of iterations.
Float strength
Magnitude of a repulsive force between particles that moves them to their final locations.
Function< bool(Size iter, ArrayView< const Vector > r)> onIteration
Optional callback executed once every iteration.
Size maxDifference
Allowed difference between the expected and actual number of particles.