SPH
GradHSolver.cpp
Go to the documentation of this file.
3 #include "quantities/Quantity.h"
4 
6 
8  ArrayView<const Float> p, m, rho;
10 
11 public:
12  virtual void create(Accumulated& results) override {
14  }
15 
16  virtual void initialize(const Storage& input, Accumulated& results) override {
19  }
20 
21  virtual void evalAsymmetric(const Size i,
22  ArrayView<const Size> neighs,
24  ArrayView<const Vector> gradj) override {
25  SPH_ASSERT(neighs.size() == gradi.size() && neighs.size() == gradj.size());
26  for (Size k = 0; k < neighs.size(); ++k) {
27  const Size j = neighs[k];
28  const Vector f = p[i] / sqr(rho[i]) * gradi[k] + p[j] / sqr(rho[j]) * gradj[k];
29  SPH_ASSERT(isReal(f));
30  dv[i] -= m[j] * f;
31  }
32  }
33 };
34 
39 class GradH {
40 private:
43  ArrayView<Float> omega;
44 
45 public:
46  explicit GradH(Storage& storage) {
47  omega = storage.getValue<Float>(QuantityId::GRAD_H);
48  rho = storage.getValue<Float>(QuantityId::DENSITY);
49  r = storage.getValue<Vector>(QuantityId::POSITION);
50  }
51 
52  void eval(const LutKernel<DIMENSIONS>& kernel, const Size i, ArrayView<const NeighbourRecord> neighs) {
53  Float sum = 0._f;
54  for (const NeighbourRecord& n : neighs) {
55  const Size j = n.index;
56  const Vector r_ji = r[j] - r[i];
57  const Float h_j = r[j][H];
58  const Float dWij_dh =
59  -dot(r_ji, kernel.grad(r_ji, h_j)) - DIMENSIONS / h_j * kernel.value(r_ji, h_j);
60  sum += dWij_dh;
61  }
62  // add term for i=j (right?)
63  sum += -DIMENSIONS / r[i][H] * kernel.value(Vector(0._f), r[i][H]);
64 
65  omega[i] = 1._f + r[i][H] / (3._f * rho[i]) * sum;
66  // For const smoothing lengths, omega should be 1. Possibly relax this assert if the real values are
67  // outside the expected range.
68  SPH_ASSERT(isReal(omega[i]) && omega[i] > 0.5_f && omega[i] < 2._f);
69  }
70 };
71 
73  const RunSettings& settings,
74  const EquationHolder& basicTerms,
75  Array<AutoPtr<IAsymmetricTerm>>&& asymmetricTerms)
76  : AsymmetricSolver(scheduler, settings, basicTerms)
77  , secondData(scheduler) {
78  for (auto& term : asymmetricTerms) {
79  term->setAsymmetricDerivatives(asymmetricDerivatives);
80  }
81 }
82 
83 void GradHSolver::create(Storage& storage, IMaterial& material) const {
84  AsymmetricSolver::create(storage, material);
85 
87 }
88 
89 void GradHSolver::loop(Storage& storage, Statistics& UNUSED(stats)) {
90  // initialize all asymmetric derivatives
91  for (auto& deriv : asymmetricDerivatives) {
92  deriv->initialize(storage, derivatives.getAccumulated());
93  }
94 
96  const IBasicFinder& finder = *getFinder(r);
97 
98  // find the maximum search radius
99  Float maxH = 0._f;
100  for (Size i = 0; i < r.size(); ++i) {
101  maxH = max(maxH, r[i][H]);
102  }
103  const Float radius = maxH * kernel.radius();
104 
105  // compute the grad-h terms
106  GradH gradH(storage);
107  auto preFunctor = [this, radius, &finder, &gradH](const Size i, ThreadData& data) {
108  finder.findAll(i, radius, data.neighs);
109  gradH.eval(kernel, i, data.neighs);
110  };
111  parallelFor(scheduler, threadData, 0, r.size(), preFunctor);
112 
115 
116  auto functor = [this, r, &finder, &neighs, omega, radius](const Size i, ThreadData& data) {
117  finder.findAll(i, radius, data.neighs);
118  data.idxs.clear();
119  data.grads.clear();
120 
121  Array<Vector>& secondGrads = secondData.local().grads;
122  secondGrads.clear();
123 
124  for (auto& n : data.neighs) {
125  const Size j = n.index;
126  const Vector gradi = 1._f / omega[i] * kernel.grad(r[i] - r[j], r[i][H]);
127  SPH_ASSERT(isReal(gradi) && dot(gradi, r[i] - r[j]) <= 0._f, gradi, r[i] - r[j]);
128  const Vector gradj = 1._f / omega[j] * kernel.grad(r[j] - r[i], r[j][H]);
129  SPH_ASSERT(isReal(gradj) && dot(gradj, r[j] - r[i]) <= 0._f, gradj, r[j] - r[i]);
130  data.idxs.emplaceBack(j);
131  data.grads.emplaceBack(gradi);
132  secondGrads.emplaceBack(gradj);
133  }
134 
135  // evaluate the 'normal' derivatives using the gradient for i-th particle
136  derivatives.eval(i, data.idxs, data.grads);
137 
138  // evaluate the 'extra' derivative using both lists of gradients
139  for (auto& deriv : asymmetricDerivatives) {
140  deriv->evalAsymmetric(i, data.idxs, data.grads, secondGrads);
141  }
142 
143  neighs[i] = data.idxs.size();
144  };
145  parallelFor(scheduler, threadData, 0, r.size(), functor);
146 }
147 
@ SHARED
Multiple derivatives may accumulate into the buffer.
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
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
constexpr int DIMENSIONS
Number of spatial dimensions in the code.
Definition: Globals.h:22
Extension of SPH solver taking into account the gradient of smoothing lengths.
constexpr INLINE T max(const T &f1, const T &f2)
Definition: MathBasic.h:20
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
#define UNUSED(x)
Definition: Object.h:37
#define NAMESPACE_SPH_END
Definition: Object.h:12
@ PRESSURE
Pressure, affected by yielding and fragmentation model, always a scalar quantity.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ DENSITY
Density, always a scalar quantity.
@ MASS
Paricles masses, always a scalar quantity.
@ NEIGHBOUR_CNT
Number of neighbouring particles (in radius h * kernel.radius)
Holder of quantity values and their temporal derivatives.
@ SECOND
Quantity with 1st and 2nd derivative.
@ ZERO
Quantity without derivatives, or "zero order" of quantity.
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
BasicVector< Float > Vector
Definition: Vector.h:539
INLINE float dot(const BasicVector< float > &v1, const BasicVector< float > &v2)
Make sure the vector is trivially constructible and destructible, needed for fast initialization of a...
Definition: Vector.h:548
@ H
Definition: Vector.h:25
Storage for accumulating derivatives.
Definition: Accumulated.h:30
Array< TValue > & getBuffer(const QuantityId id, const OrderEnum order)
Returns the buffer of given quantity and given order.
Definition: Accumulated.cpp:53
void insert(const QuantityId id, const OrderEnum order, const BufferSource source)
Creates a new storage with given ID.
INLINE TCounter size() const
Definition: ArrayView.h:101
Generic dynamically allocated resizable storage.
Definition: Array.h:43
StorageType & emplaceBack(TArgs &&... args)
Constructs a new element at the end of the array in place, using the provided arguments.
Definition: Array.h:332
void clear()
Removes all elements from the array, but does NOT release the memory.
Definition: Array.h:434
virtual void initialize(const Storage &input, Accumulated &results) override
Initialize derivative before iterating over neighbours.
Definition: GradHSolver.cpp:16
virtual void create(Accumulated &results) override
Emplace all needed buffers into shared storage.
Definition: GradHSolver.cpp:12
virtual void evalAsymmetric(const Size i, ArrayView< const Size > neighs, ArrayView< const Vector > gradi, ArrayView< const Vector > gradj) override
Compute a part of derivatives from interaction of particle pairs.
Definition: GradHSolver.cpp:21
Generic SPH solver, evaluating equations for each particle separately.
ThreadLocal< ThreadData > threadData
DerivativeHolder derivatives
Holds all derivatives (shared for all threads)
Wrapper of pointer that deletes the resource from destructor.
Definition: AutoPtr.h:15
void eval(const Size idx, ArrayView< const Size > neighs, ArrayView< const Vector > grads)
Evaluates all held derivatives for given particle.
Definition: Derivative.cpp:113
INLINE Accumulated & getAccumulated()
Definition: Derivative.h:226
Container holding equation terms.
Definition: EquationTerm.h:238
GradHSolver(IScheduler &scheduler, const RunSettings &settings, const EquationHolder &basicTerms, Array< AutoPtr< IAsymmetricTerm >> &&asymmetricTerms)
Definition: GradHSolver.cpp:72
virtual void create(Storage &storage, IMaterial &material) const override
Initializes all quantities needed by the solver in the storage.
Definition: GradHSolver.cpp:83
virtual void loop(Storage &storage, Statistics &stats) override
Definition: GradHSolver.cpp:89
Object evaluating grad-h terms.
Definition: GradHSolver.cpp:39
void eval(const LutKernel< DIMENSIONS > &kernel, const Size i, ArrayView< const NeighbourRecord > neighs)
Definition: GradHSolver.cpp:52
GradH(Storage &storage)
Definition: GradHSolver.cpp:46
Special derivative evaluated by GradHSolver.
Definition: GradHSolver.h:17
IScheduler & scheduler
Scheduler used to parallelize the solver.
LutKernel< DIMENSIONS > kernel
Selected SPH kernel.
AutoPtr< ISymmetricFinder > finder
Structure used to search for neighbouring particles.
virtual void create(Storage &storage, IMaterial &material) const override
Initializes all quantities needed by the solver in the storage.
virtual RawPtr< const IBasicFinder > getFinder(ArrayView< const Vector > r)
Returns a finder, already build using the provided positions.
Interface of objects finding neighbouring particles.
Material settings and functions specific for one material.
Definition: IMaterial.h:110
Interface that allows unified implementation of sequential and parallelized versions of algorithms.
Definition: Scheduler.h:27
INLINE Float value(const Vector &r, const Float h) const noexcept
Definition: Kernel.h:26
INLINE Vector grad(const Vector &r, const Float h) const noexcept
Definition: Kernel.h:32
INLINE Float radius() const noexcept
Definition: Kernel.h:107
Object holding various statistics about current run.
Definition: Statistics.h:22
Container storing all quantities used within the simulations.
Definition: Storage.h:230
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
auto getValues(const QuantityId first, const QuantityId second, const TArgs... others)
Retrieves an array of quantities from the key.
Definition: Storage.h:359
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
Definition: Storage.cpp:191
INLINE Type & local()
Return a value for current thread.
Definition: ThreadLocal.h:88
constexpr Size sum()
Definition: Multipole.h:31
Holds information about a neighbour particles.