SPH
Derivative.cpp
Go to the documentation of this file.
2 #include "objects/Exceptions.h"
4 #include "quantities/Quantity.h"
5 
7 
9  sumOnlyUndamaged = settings.get<bool>(RunSettingsId::SPH_SUM_ONLY_UNDAMAGED);
10 }
11 
13  // needs to be computed first, so that other derivatives can use the result
15 }
16 
18  results.insert<SymmetricTensor>(
20 }
21 
22 void CorrectionTensor::initialize(const Storage& input, Accumulated& results) {
25 
26  if (sumOnlyUndamaged && input.has(QuantityId::STRESS_REDUCING)) {
27  idxs = input.getValue<Size>(QuantityId::FLAG);
29  } else {
30  reduce = nullptr;
31  }
32 
34 }
35 
37  SPH_ASSERT(neighs.size() == grads.size());
38  C[i] = SymmetricTensor::null();
39  if (reduce) {
40  for (Size k = 0; k < neighs.size(); ++k) {
41  const Size j = neighs[k];
42  if (idxs[i] != idxs[j] || reduce[i] == 0._f || reduce[j] == 0._f) {
43  // condition must match the one in velocity template!
44  continue;
45  }
46  SymmetricTensor t = symmetricOuter(r[j] - r[i], grads[k]); // symmetric in i,j ?
47  C[i] += m[j] / rho[j] * t;
48  }
49  } else {
50  for (Size k = 0; k < neighs.size(); ++k) {
51  const Size j = neighs[k];
52  SymmetricTensor t = symmetricOuter(r[j] - r[i], grads[k]);
53  C[i] += m[j] / rho[j] * t;
54  }
55  }
56 
57  if (C[i] == SymmetricTensor::null()) {
59  } else {
60  // sanity check that we are not getting 'weird' tensors with non-positive values on diagonal
61  SPH_ASSERT(minElement(C[i].diagonal()) >= 0._f, C[i]);
62  if (C[i].determinant() > 0.01_f) {
63  C[i] = C[i].inverse();
64  SPH_ASSERT(C[i].determinant() > 0._f, C[i]);
65  } else {
66  /*C[i] = C[i].pseudoInverse(1.e-3_f);
67  if (C[i] == SymmetricTensor::null()) {
68  C[i] = SymmetricTensor::identity();
69  }*/
71  }
72  }
74 }
75 
76 
78  for (const AutoPtr<IDerivative>& d : derivatives) {
79  // we need to create temporary references, otherwise clang will complain
80  const IDerivative& value1 = *d;
81  const IDerivative& value2 = *derivative;
82  if (typeid(value1) == typeid(value2)) {
83  // same type, check for equality of derivatives and return
84  if (!value1.equals(value2)) {
85  throw InvalidSetup(
86  "Using two derivatives with the same type, but with different internal state. This is "
87  "currently unsupported; while it is allowed to require the same derivative more than "
88  "once, it MUST have the same state.");
89  }
90  return;
91  }
92  }
93  derivatives.insert(std::move(derivative));
94 }
95 
97  if (needsCreate) {
98  // lazy buffer creation
99  for (const auto& deriv : derivatives) {
100  deriv->create(accumulated);
101  }
102  needsCreate = false;
103  }
104  // initialize buffers first, possibly resizing then and invalidating previously stored arrayviews
105  accumulated.initialize(input.getParticleCnt());
106 
107  for (const auto& deriv : derivatives) {
108  // then get the arrayviews for derivatives
109  deriv->initialize(input, accumulated);
110  }
111 }
112 
114  SPH_ASSERT(neighs.size() == grads.size());
115  for (const auto& deriv : derivatives) {
116  deriv->evalNeighs(idx, neighs, grads);
117  }
118 }
119 
121  ArrayView<const Size> neighs,
122  ArrayView<const Vector> grads) {
123  SPH_ASSERT(neighs.size() == grads.size());
125  for (const auto& deriv : derivatives) {
126  ISymmetricDerivative* symmetric = assert_cast<ISymmetricDerivative*>(&*deriv);
127  symmetric->evalSymmetric(idx, neighs, grads);
128  }
129 }
130 
132  for (const auto& deriv : derivatives) {
133  if (!dynamic_cast<ISymmetricDerivative*>(&*deriv)) {
134  return false;
135  }
136  }
137  return true;
138 }
139 
140 /*DerivativeHolder DerivativeHolder::getSubset(const QuantityId id, const OrderEnum order) {
141  DerivativeHolder subset;
142  for (const auto& deriv : derivatives) {
143  Accumulated a;
144  deriv->create(a);
145  if (a.hasBuffer(id, order)) {
146  // required since we don't sort the returned values by phase
147  SPH_ASSERT(deriv->phase() == DerivativePhase::EVALUATION);
148  subset.derivatives.insert(deriv);
149  }
150  }
151  return subset;
152 }*/
153 
@ UNIQUE
Only a single derivative accumulates to this buffer.
INLINE Float minElement(const AntisymmetricTensor &t)
Returns the minimal element of the tensor.
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
Spatial derivatives to be computed by SPH discretization.
DerivativePhase
Defines the phases of derivative evaluation.
Definition: Derivative.h:28
@ PRECOMPUTE
Auxiliary quantities needed for evaluation of other derivatives (grad-h, correction tensor,...
Key-value associative container implemented as a sorted array.
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
#define NAMESPACE_SPH_END
Definition: Object.h:12
@ FLAG
ID of original body, used to implement discontinuities between bodies in SPH.
@ STRAIN_RATE_CORRECTION_TENSOR
Correction tensor used to improve conservation of total angular momentum.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ DENSITY
Density, always a scalar quantity.
@ MASS
Paricles masses, always a scalar quantity.
@ STRESS_REDUCING
Total stress reduction factor due to damage and yielding. Is always scalar.
Holder of quantity values and their temporal derivatives.
@ ZERO
Quantity without derivatives, or "zero order" of quantity.
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
INLINE SymmetricTensor symmetricOuter(const Vector &v1, const Vector &v2)
SYMMETRIZED outer product of two vectors.
Storage for accumulating derivatives.
Definition: Accumulated.h:30
void initialize(const Size size)
Initialize all storages.
Definition: Accumulated.cpp:37
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
Wrapper of pointer that deletes the resource from destructor.
Definition: AutoPtr.h:15
CorrectionTensor(const RunSettings &settings)
Definition: Derivative.cpp:8
virtual void create(Accumulated &results) override
Emplace all needed buffers into shared storage.
Definition: Derivative.cpp:17
virtual void initialize(const Storage &input, Accumulated &results) override
Initialize derivative before iterating over neighbours.
Definition: Derivative.cpp:22
virtual DerivativePhase phase() const override
Returns the phase of the derivative.
Definition: Derivative.cpp:12
virtual void evalNeighs(Size i, ArrayView< const Size > neighs, ArrayView< const Vector > grads) override
Compute derivatives of given particle.
Definition: Derivative.cpp:36
virtual void require(AutoPtr< IDerivative > &&derivative)
Adds derivative if not already present.
Definition: Derivative.cpp:77
void evalSymmetric(const Size idx, ArrayView< const Size > neighs, ArrayView< const Vector > grads)
Evaluates all held derivatives symetrically for given particle pairs.
Definition: Derivative.cpp:120
void eval(const Size idx, ArrayView< const Size > neighs, ArrayView< const Vector > grads)
Evaluates all held derivatives for given particle.
Definition: Derivative.cpp:113
bool isSymmetric() const
Returns true if all stored derivatives are symmetric.
Definition: Derivative.cpp:131
virtual void initialize(const Storage &input)
Initialize derivatives before loop.
Definition: Derivative.cpp:96
Derivative accumulated by summing up neighbouring particles.
Definition: Derivative.h:43
virtual bool equals(const IDerivative &other) const
Returns true if this derivative is equal to the given derivative.
Definition: Derivative.h:81
Extension of derivative, allowing a symmetrized evaluation.
Definition: Derivative.h:90
virtual void evalSymmetric(const Size idx, ArrayView< const Size > neighs, ArrayView< const Vector > grads)=0
Compute a part of derivatives from interaction of particle pairs.
Thrown when components of the run are mutually incompatible.
Definition: Exceptions.h:24
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
Container storing all quantities used within the simulations.
Definition: Storage.h:230
Size getParticleCnt() const
Returns the number of particles.
Definition: Storage.cpp:445
auto getValues(const QuantityId first, const QuantityId second, const TArgs... others)
Retrieves an array of quantities from the key.
Definition: Storage.h:359
bool has(const QuantityId key) const
Checks if the storage contains quantity with given key.
Definition: Storage.cpp:130
Array< TValue > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
Definition: Storage.cpp:191
Symmetric tensor of 2nd order.
static INLINE SymmetricTensor identity()
Returns an identity tensor.
static INLINE SymmetricTensor null()
Returns a tensor with all zeros.