SPH
Rheology.cpp
Go to the documentation of this file.
1 #include "physics/Rheology.h"
2 #include "io/Logger.h"
3 #include "physics/Damage.h"
4 #include "quantities/IMaterial.h"
5 #include "quantities/Quantity.h"
6 #include "quantities/Storage.h"
7 #include "thread/Scheduler.h"
8 
10 
11 // ----------------------------------------------------------------------------------------------------------
12 // VonMisesRheology
13 // ----------------------------------------------------------------------------------------------------------
14 
17 
19  : damage(std::move(damage)) {
20  SPH_ASSERT(this->damage != nullptr);
21 }
22 
24 
26  IMaterial& material,
27  const MaterialInitialContext& context) const {
29 
30  SPH_ASSERT(storage.getMaterialCnt() == 1);
32 
33  damage->setFlaws(storage, material, context);
34 }
35 
36 void VonMisesRheology::initialize(IScheduler& scheduler, Storage& storage, const MaterialView material) {
38 
44  if (storage.has(QuantityId::DAMAGE)) {
45  D = storage.getValue<Float>(QuantityId::DAMAGE);
46  }
47 
48  const Float limit = material->getParam<Float>(BodySettingsId::ELASTICITY_LIMIT);
49  SPH_ASSERT(limit > 0._f);
50 
51  const Float u_melt = material->getParam<Float>(BodySettingsId::MELT_ENERGY);
52  IndexSequence seq = material.sequence();
53  constexpr Float eps = 1.e-15_f;
54  parallelFor(scheduler, *seq.begin(), *seq.end(), [&](const Size i) INL {
55  // reduce the pressure (pressure is reduced only for negative values)
56  const Float d = D ? pow<3>(D[i]) : 0._f;
57  if (p[i] < 0._f) {
58  p[i] = (1._f - d) * p[i];
59  }
60 
61  // compute yielding stress
62  const Float unorm = u[i] / u_melt;
63  Float Y = unorm < 1.e-5_f ? limit : limit * max(1._f - unorm, 0._f);
64  Y = (1._f - d) * Y;
65 
66  // apply reduction to stress tensor
67  if (Y < EPS) {
68  reducing[i] = 0._f;
69  S[i] = TracelessTensor::null();
70  return;
71  }
72  // compute second invariant using damaged stress tensor
73  const Float J2 = 0.5_f * ddot(S[i], S[i]) + eps;
74  SPH_ASSERT(isReal(J2) && J2 > 0._f);
75  const Float red = min(Y / sqrt(3._f * J2), 1._f);
76  SPH_ASSERT(red >= 0._f && red <= 1._f);
77  reducing[i] = red;
78 
79  // apply yield reduction in place
80  S[i] = S[i] * red;
81  SPH_ASSERT(isReal(S[i]));
82  });
83 }
84 
85 void VonMisesRheology::integrate(IScheduler& scheduler, Storage& storage, const MaterialView material) {
87  damage->integrate(scheduler, storage, material);
88 }
89 
90 // ----------------------------------------------------------------------------------------------------------
91 // DruckerPragerRheology
92 // ----------------------------------------------------------------------------------------------------------
93 
96 
98  : damage(std::move(damage)) {
99  SPH_ASSERT(this->damage != nullptr);
100 }
101 
103 
105  IMaterial& material,
106  const MaterialInitialContext& context) const {
108  SPH_ASSERT(storage.getMaterialCnt() == 1);
114  }
115 
116  damage->setFlaws(storage, material, context);
117 }
118 
119 void DruckerPragerRheology::initialize(IScheduler& scheduler, Storage& storage, const MaterialView material) {
121 
127  if (storage.has(QuantityId::DAMAGE)) {
128  D = storage.getValue<Float>(QuantityId::DAMAGE);
129  }
130 
131  const Float Y_0 = material->getParam<Float>(BodySettingsId::COHESION);
132  const Float Y_M = material->getParam<Float>(BodySettingsId::ELASTICITY_LIMIT);
133  const Float mu_i = material->getParam<Float>(BodySettingsId::INTERNAL_FRICTION);
134  const Float mu_d = material->getParam<Float>(BodySettingsId::DRY_FRICTION);
135  const Float u_melt = material->getParam<Float>(BodySettingsId::MELT_ENERGY);
136 
137  const bool fluidization = material->getParam<bool>(BodySettingsId::USE_ACOUSTIC_FLUDIZATION);
138  // const Float nu_lim = material->getParam<Float>(BodySettingsId::FLUIDIZATION_VISCOSITY);
139  ArrayView<const Float> v_vib, rho, cs;
140  if (fluidization) {
141  tie(v_vib, rho, cs) = storage.getValues<Float>(
143  }
144 
145  const IndexSequence seq = material.sequence();
146  parallelFor(scheduler, *seq.begin(), *seq.end(), [&](const Size i) {
147  // reduce the pressure (pressure is reduced only for negative values)
148  const Float d = D ? pow<3>(D[i]) : 0._f;
149  if (p[i] < 0._f) {
150  p[i] = (1._f - d) * p[i];
151  }
152 
153  const Float Y_i = Y_0 + mu_i * p[i] / (1._f + mu_i * max(p[i], 0._f) / (Y_M - Y_0));
154  Float Y_d = mu_d * p[i];
155 
156  if (fluidization) {
157  const Float p_vib = rho[i] * cs[i] * v_vib[i];
158  Y_d = max(0._f, Y_d - mu_d * p_vib);
159  }
160 
161  Float Y;
162  if (Y_d > Y_i) {
163  // at pressures above Y_i, the shear strength follows the same pressure dependence regardless
164  // of damage.
165  Y = Y_i;
166  } else {
167  Y = (1._f - d) * Y_i + d * Y_d;
168  }
169 
170  // apply temperature dependence
171  Y = (u[i] < 1.e-5_f * u_melt) ? Y : Y * max(1._f - u[i] / u_melt, 0._f);
172 
173  if (Y < EPS) {
174  reducing[i] = 0._f;
175  S[i] = TracelessTensor::null();
176  return;
177  }
178 
179  const Float J2 = 0.5_f * ddot(S[i], S[i]) + EPS;
180  const Float red = min(Y / sqrt(J2), 1._f);
181  SPH_ASSERT(red >= 0._f && red <= 1._f, red);
182  reducing[i] = red;
183 
184  // apply yield reduction in place
185  S[i] = S[i] * red;
186  SPH_ASSERT(isReal(S[i]));
187  });
188 }
189 
190 void DruckerPragerRheology::integrate(IScheduler& scheduler, Storage& storage, const MaterialView material) {
192 
193  if (material->getParam<bool>(BodySettingsId::USE_ACOUSTIC_FLUDIZATION)) {
194  // integrate the vibrational velocity
195  ArrayView<Float> v, dv;
200 
201  const Float t_dec = material->getParam<Float>(BodySettingsId::OSCILLATION_DECAY_TIME);
202  const Float e = material->getParam<Float>(BodySettingsId::OSCILLATION_REGENERATION);
203  const Float rho = material->getParam<Float>(BodySettingsId::DENSITY);
204 
205  for (Size i : material.sequence()) {
206  const SymmetricTensor sigma = p[i] * SymmetricTensor::identity() - SymmetricTensor(S[i]);
207  const Float dE = e * max(ddot(sigma, eps[i]), 0._f);
208  // energy to velocity
209  dv[i] = sqrt(2._f * dE / rho) - v[i] / t_dec;
210  }
211  }
212 
213  damage->integrate(scheduler, storage, material);
214 }
215 
217  IMaterial& UNUSED(material),
218  const MaterialInitialContext& UNUSED(context)) const {
219  SPH_ASSERT(storage.getMaterialCnt() == 1);
221 }
222 
224  Storage& UNUSED(storage),
225  const MaterialView UNUSED(material)) {}
226 
228  Storage& UNUSED(storage),
229  const MaterialView UNUSED(material)) {}
230 
INLINE bool isReal(const AntisymmetricTensor &t)
INLINE Float ddot(const AntisymmetricTensor &t1, const AntisymmetricTensor &t2)
Double-dot product t1 : t2 = sum_ij t1_ij t2_ij.
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
INLINE AutoPtr< T > makeAuto(TArgs &&... args)
Definition: AutoPtr.h:124
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
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.
Logging routines of the run.
#define VERBOSE_LOG
Helper macro, creating.
Definition: Logger.h:242
constexpr INLINE T max(const T &f1, const T &f2)
Definition: MathBasic.h:20
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
INLINE T sqrt(const T f)
Return a squared root of a value.
Definition: MathUtils.h:78
constexpr Float LARGE
Definition: MathUtils.h:34
#define UNUSED(x)
Definition: Object.h:37
#define NAMESPACE_SPH_END
Definition: Object.h:12
#define INL
Definition: Object.h:32
@ DEVIATORIC_STRESS
Deviatoric stress tensor, always a traceless tensor.
@ PRESSURE
Pressure, affected by yielding and fragmentation model, always a scalar quantity.
@ VELOCITY_GRADIENT
Velocity gradient.
@ DAMAGE
Damage.
@ ENERGY
Specific internal energy, always a scalar quantity.
@ DENSITY
Density, always a scalar quantity.
@ SOUND_SPEED
Sound speed, always a scalar quantity.
@ STRESS_REDUCING
Total stress reduction factor due to damage and yielding. Is always scalar.
@ VIBRATIONAL_VELOCITY
Vibrational particle velocity, used by the block model of acoustic fluidization.
Holder of quantity values and their temporal derivatives.
@ FIRST
Quantity with 1st derivative.
@ ZERO
Quantity without derivatives, or "zero order" of quantity.
Rheology of materials.
Interface for executing tasks (potentially) asynchronously.
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
Container for storing particle quantities and materials.
@ Y
Definition: Vector.h:23
Pressure dependent failure modes .
Definition: Rheology.h:84
virtual void integrate(IScheduler &scheduler, Storage &storage, const MaterialView material) override
Computes derivatives of the time-dependent quantities of the rheological model.
Definition: Rheology.cpp:190
virtual void initialize(IScheduler &scheduler, Storage &storage, const MaterialView material) override
Evaluates the stress tensor reduction factors.
Definition: Rheology.cpp:119
DruckerPragerRheology()
Constructs a rheology with no fragmentation model.
Definition: Rheology.cpp:94
virtual void create(Storage &storage, IMaterial &material, const MaterialInitialContext &context) const override
Creates all the necessary quantities and material parameters needed by the rheology.
Definition: Rheology.cpp:104
virtual void integrate(IScheduler &scheduler, Storage &storage, const MaterialView material) override
Computes derivatives of the time-dependent quantities of the rheological model.
Definition: Rheology.cpp:227
virtual void initialize(IScheduler &scheduler, Storage &storage, const MaterialView material) override
Evaluates the stress tensor reduction factors.
Definition: Rheology.cpp:223
virtual void create(Storage &storage, IMaterial &material, const MaterialInitialContext &context) const override
Creates all the necessary quantities and material parameters needed by the rheology.
Definition: Rheology.cpp:216
virtual void integrate(IScheduler &scheduler, Storage &storage, const MaterialView sequence)=0
Compute damage derivatives.
virtual void setFlaws(Storage &storage, IMaterial &material, const MaterialInitialContext &context) const =0
Sets up all the necessary quantities in the storage given material settings.
Material settings and functions specific for one material.
Definition: IMaterial.h:110
INLINE TValue getParam(const BodySettingsId paramIdx) const
Returns a parameter associated with given particle.
Definition: IMaterial.h:137
void setRange(const QuantityId id, const Interval &range, const Float minimal)
Sets the timestepping parameters of given quantity.
Definition: IMaterial.cpp:17
Interface that allows unified implementation of sequential and parallelized versions of algorithms.
Definition: Scheduler.h:27
INLINE IndexIterator begin() const
INLINE IndexIterator end() const
Object representing a 1D interval of real numbers.
Definition: Interval.h:17
Non-owning wrapper of a material and particles with this material.
Definition: IMaterial.h:30
INLINE IndexSequence sequence()
Returns iterable index sequence.
Definition: IMaterial.h:75
Container storing all quantities used within the simulations.
Definition: Storage.h:230
Size getMaterialCnt() const
Return the number of materials in the storage.
Definition: Storage.cpp:437
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
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.
Symmetric traceless 2nd order tensor.
static INLINE TracelessTensor null()
Returns a tensor with all zeros.
Introduces plastic behavior for stress tensor, using von Mises yield criterion .
Definition: Rheology.h:58
VonMisesRheology()
Constructs a rheology with no fragmentation model.
Definition: Rheology.cpp:15
virtual void create(Storage &storage, IMaterial &settings, const MaterialInitialContext &context) const override
Creates all the necessary quantities and material parameters needed by the rheology.
Definition: Rheology.cpp:25
virtual void integrate(IScheduler &scheduler, Storage &storage, const MaterialView material) override
Computes derivatives of the time-dependent quantities of the rheological model.
Definition: Rheology.cpp:85
virtual void initialize(IScheduler &scheduler, Storage &storage, const MaterialView material) override
Evaluates the stress tensor reduction factors.
Definition: Rheology.cpp:36
@ INTERNAL_FRICTION
Coefficient of friction for undamaged material.
@ ELASTICITY_LIMIT
Elasticity limit of the von Mises yielding criterion.
@ DRY_FRICTION
Coefficient of friction for fully damaged material.
@ OSCILLATION_REGENERATION
Regeneration efficiency of acoustric oscillations.
@ MELT_ENERGY
Melting energy, used for temperature-dependence of the stress tensor.
@ USE_ACOUSTIC_FLUDIZATION
Whether to use the acoustic fludization model.
@ COHESION
Cohesion, yield strength at zero pressure.
@ DENSITY
Density at zero pressure.
@ OSCILLATION_DECAY_TIME
Characteristic decay time of acoustic oscillations in the material.
Overload of std::swap for Sph::Array.
Definition: Array.h:578
Shared data used when creating all bodies in the simulation.
Definition: IMaterial.h:89