SPH
ElasticDeformationSolver.cpp
Go to the documentation of this file.
2 #include "math/Quat.h"
4 #include "quantities/IMaterial.h"
5 #include "quantities/Quantity.h"
7 #include "system/Factory.h"
8 #include "thread/Scheduler.h"
9 
11 
12 
19 static AffineMatrix extractRotation(const AffineMatrix& a,
20  const AffineMatrix& r0,
21  const Size iterationCnt = 3) {
22  const Vector a1 = a.column(0);
23  const Vector a2 = a.column(1);
24  const Vector a3 = a.column(2);
25 
26  AffineMatrix r = r0;
27  for (Size i = 0; i < iterationCnt; ++i) {
28  const Vector r1 = r.column(0);
29  const Vector r2 = r.column(1);
30  const Vector r3 = r.column(2);
31 
32  const Vector omega = (cross(r1, a1) + cross(r2, a2) + cross(r3, a3)) /
33  (abs(dot(r1, a1) + dot(r2, a2) + dot(r3, a3)) + EPS);
34  if (omega != Vector(0._f)) {
35  Vector dir;
36  Float angle;
37  tieToTuple(dir, angle) = getNormalizedWithLength(omega);
38  r = AffineMatrix::rotateAxis(dir, angle) * r;
39  SPH_ASSERT(isReal(r.row(0)) && isReal(r.row(1)) && isReal(r.row(2)));
40  }
41  }
42 
43  return r;
44 }
45 
47  const RunSettings& settings,
49  : scheduler(scheduler)
50  , bc(std::move(bc)) {
51  kernel = Factory::getKernel<3>(settings);
52  finder = Factory::getFinder(settings);
53 
55 }
56 
58  bc->initialize(storage);
59  bc->finalize(storage);
60 
70 
71  if (neighsPerParticle.empty()) {
72  // lazy initialization
73  r0.resize(r.size());
74  V0.resize(r.size());
75 
76  finder->build(scheduler, r);
77  const Float maxH = r[0][H];
78  neighsPerParticle.resize(r.size());
80  for (Size i = 0; i < r.size(); ++i) {
81  r0[i] = r[i];
82  V0[i] = m[i] / rho[i];
83 
84  finder->findAll(i, maxH * kernel.radius(), neighs);
85 
87  C[i] = SymmetricTensor::null();
88  for (NeighbourRecord& n : neighs) {
89  const Size j = n.index;
90  const Float hbar = 0.5_f * (r[i][H] + r[j][H]);
91  if (i != j && n.distanceSqr < sqr(kernel.radius() * hbar)) {
92  neighsPerParticle[i].push(j);
93 
94  C[i] += m[j] / rho[j] * symmetricOuter(r[j] - r[i], kernel.grad(r[i], r[j]));
95  }
96  }
97  if (C[i] == SymmetricTensor::null()) {
99  } else {
100  C[i] = C[i].inverse();
101  }
102  }
103  R.resize(r.size());
105 
106 #ifdef SPH_DEBUG
107  for (Size i = 0; i < r.size(); ++i) {
108  for (Size j : neighsPerParticle[i]) {
109  SPH_ASSERT(std::find(neighsPerParticle[j].begin(), neighsPerParticle[j].end(), i) !=
110  neighsPerParticle[j].end());
111  }
112  }
113 #endif
114  }
115 
116  for (Size matId = 0; matId < storage.getMaterialCnt(); ++matId) {
117  MaterialView mat = storage.getMaterial(matId);
118  const Float mu = mat->getParam<Float>(BodySettingsId::SHEAR_MODULUS);
119  const Float lambda = mat->getParam<Float>(BodySettingsId::ELASTIC_MODULUS);
120 
121  IndexSequence seq = mat.sequence();
122  parallelFor(scheduler, *seq.begin(), *seq.end(), [&](const Size i) {
123  // compute preliminar deformation gradient (Eq. 3)
124  Tensor F = Tensor::null();
125  for (Size j : neighsPerParticle[i]) {
126  const Vector w = C[i] * kernel.grad(r0[i], r0[j]);
127  F += V0[j] * outer(r[j] - r[i], w);
128  }
129 
130  // extract rotation
131  R[i] = extractRotation(convert<AffineMatrix>(F), R[i]);
132  const Quat q(R[i]);
133  if (abs(q.angle()) > EPS) {
134  alpha[i] = q.axis() * q.angle() * RAD_TO_DEG;
135  } else {
136  alpha[i] = Vector(0._f);
137  }
138 
139  // compute corotated deformation gradient (Eq. 5)
140  Tensor F_star = Tensor::identity();
141  for (Size j : neighsPerParticle[i]) {
142  const Vector w_star = R[i] * (C[i] * kernel.grad(r0[i], r0[j]));
143  F_star += V0[j] * outer(r[j] - r[i] - R[i] * (r0[j] - r0[i]), w_star);
144  }
145 
146  // compute stress tensor
148  const SymmetricTensor sigma = 2._f * mu * e + lambda * e.trace() * SymmetricTensor::identity();
149  p[i] = -sigma.trace() / 3._f;
150  S[i] = TracelessTensor(sigma + p[i] * SymmetricTensor::identity());
151  });
152 
154  parallelFor(scheduler, *seq.begin(), *seq.end(), [&](const Size i) {
155  for (Size j : neighsPerParticle[i]) {
156  const Vector w = kernel.grad(r0[i], r0[j]);
157  const Vector wi_star = R[i] * (C[i] * w);
158  const Vector wj_star = R[j] * (C[j] * w);
159  const Vector f =
160  V0[i] * V0[j] * (-p[i] * wi_star - p[j] * wj_star + S[i] * wi_star + S[j] * wj_star);
161  dv[i] += f / m[i];
162  }
163 
164  dv[i] += gravity;
165  });
166  }
167 }
168 
169 void ElasticDeformationSolver::create(Storage& storage, IMaterial& UNUSED(material)) const {
171  storage.insert<SymmetricTensor>(
174 }
175 
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
Spatial derivatives to be computed by SPH discretization.
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.
constexpr Float EPS
Definition: MathUtils.h:30
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
INLINE auto abs(const T &f)
Definition: MathUtils.h:276
constexpr Float RAD_TO_DEG
Definition: MathUtils.h:371
#define UNUSED(x)
Definition: Object.h:37
#define NAMESPACE_SPH_END
Definition: Object.h:12
@ STRAIN_RATE_CORRECTION_TENSOR
Correction tensor used to improve conservation of total angular momentum.
@ DEVIATORIC_STRESS
Deviatoric stress tensor, always a traceless tensor.
@ 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.
Holder of quantity values and their temporal derivatives.
@ ZERO
Quantity without derivatives, or "zero order" of quantity.
Quaternion algebra.
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
INLINE SymmetricTensor symmetricOuter(const Vector &v1, const Vector &v2)
SYMMETRIZED outer product of two vectors.
INLINE SymmetricTensor symmetrize(const Tensor &t)
Computes a symmetrized tensor 1/2*(t + t^T)
Definition: Tensor.h:177
INLINE Tensor outer(const Vector &r1, const Vector &r2)
Outer product.
Definition: Tensor.h:183
INLINE Tuple< TArgs &... > tieToTuple(TArgs &... args)
Creates a tuple of l-value references. Use IGNORE placeholder to omit one or more parameters.
Definition: Tuple.h:304
INLINE Tuple< Vector, Float > getNormalizedWithLength(const Vector &v)
Returns normalized vector and length of the input vector as tuple.
Definition: Vector.h:597
INLINE BasicVector< float > cross(const BasicVector< float > &v1, const BasicVector< float > &v2)
Cross product between two vectors.
Definition: Vector.h:559
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
static AffineMatrix identity()
Definition: AffineMatrix.h:132
INLINE Vector column(const Size idx) const
Definition: AffineMatrix.h:39
INLINE Vector row(const Size idx) const
Definition: AffineMatrix.h:44
static AffineMatrix rotateAxis(const Vector &axis, const Float angle)
Definition: AffineMatrix.h:159
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
INLINE TCounter size() const
Definition: ArrayView.h:101
void resize(const TCounter newSize)
Resizes the array to new size.
Definition: Array.h:215
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
Definition: Array.h:306
void fill(const T &t)
Sets all elements of the array to given value.
Definition: Array.h:187
INLINE bool empty() const noexcept
Definition: Array.h:201
virtual void create(Storage &storage, IMaterial &material) const override
Initializes all quantities needed by the solver in the storage.
virtual void integrate(Storage &storage, Statistics &stats) override
Computes derivatives of all time-dependent quantities.
ElasticDeformationSolver(IScheduler &scheduler, const RunSettings &settings, AutoPtr< IBoundaryCondition > &&bc)
void build(IScheduler &scheduler, ArrayView< const Vector > points)
Constructs the struct with an array of vectors.
virtual Size findAll(const Size index, const Float radius, Array< NeighbourRecord > &neighbours) const =0
Finds all neighbours within given radius from the point given by index.
virtual void finalize(Storage &storage)=0
Applies the boundary conditions after the derivatives are computed.
virtual void initialize(Storage &storage)=0
Applies the boundary conditions before the derivatives are computed.
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
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
Quaternion representing an axis of rotation and a (half of) rotation angle.
Definition: Quat.h:16
INLINE Vector axis() const
Returns the normalized rotational axis.
Definition: Quat.h:54
INLINE Float angle() const
Returns the angle of rotation (in radians).
Definition: Quat.h:60
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
Object holding various statistics about current run.
Definition: Statistics.h:22
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
Array< TValue > & getD2t(const QuantityId key)
Retrieves a quantity second derivative from the storage, given its key and value type.
Definition: Storage.cpp:243
MaterialView getMaterial(const Size matIdx) const
Returns an object containing a reference to given material.
Definition: Storage.cpp:366
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.
INLINE Float trace() const
Return the trace of the tensor.
static INLINE SymmetricTensor identity()
Returns an identity tensor.
static INLINE SymmetricTensor null()
Returns a tensor with all zeros.
INLINE Float radius() const
Definition: Kernel.h:583
INLINE Vector grad(const Vector &r1, const Vector &r2) const
Definition: Kernel.h:578
Generic 2nd-order tensor with 9 independent components.
Definition: Tensor.h:13
static Tensor identity()
Definition: Tensor.h:81
Symmetric traceless 2nd order tensor.
static INLINE TracelessTensor null()
Returns a tensor with all zeros.
Creating code components based on values from settings.
@ ELASTIC_MODULUS
Elastic modulus lambda (a.k.a Lame's first parameter) of the material.
@ SHEAR_MODULUS
Shear modulus mu (a.k.a Lame's second parameter) of the material.
@ FRAME_CONSTANT_ACCELERATION
AutoPtr< ISymmetricFinder > getFinder(const RunSettings &settings)
Definition: Factory.cpp:156
Overload of std::swap for Sph::Array.
Definition: Array.h:578
Holds information about a neighbour particles.