SPH
StabilizationSolver.h
Go to the documentation of this file.
1 #pragma once
2 
7 
8 #include "post/Analysis.h"
9 #include "quantities/IMaterial.h"
10 #include "sph/boundary/Boundary.h"
11 #include "system/Factory.h"
12 #include "system/Settings.h"
13 #include "system/Statistics.h"
14 #include "timestepping/ISolver.h"
15 
17 
24 class StabilizationSolver : public ISolver {
25 private:
26  AutoPtr<ISolver> solver;
27 
29  Interval timeRange;
30 
32  Float delta;
33 
34  struct BodyData {
35  Vector center;
36 
37  Vector omega;
38  };
39 
40  Optional<BodyData> data;
41 
42 
43 public:
44  StabilizationSolver(const Interval timeRange, const Float delta, AutoPtr<ISolver>&& solver)
45  : solver(std::move(solver))
46  , timeRange(timeRange)
47  , delta(delta) {}
48 
50  : solver(std::move(solver)) {
51  timeRange = Interval(settings.get<Float>(RunSettingsId::RUN_START_TIME),
54  }
55 
57  : StabilizationSolver(settings, Factory::getSolver(scheduler, settings, std::move(bc))) {}
58 
59  virtual void integrate(Storage& storage, Statistics& stats) override {
60  solver->integrate(storage, stats);
61 
62  const Float t = stats.get<Float>(StatisticsId::RUN_TIME);
63  const Float dt = stats.getOr<Float>(StatisticsId::TIMESTEP_VALUE, 0.01_f);
64 
65  if (!data) {
66  computeBodyData(storage);
67  }
68  SPH_ASSERT(data);
69 
70  // damp velocities
71  ArrayView<Vector> r, v, dv;
72  tie(r, v, dv) = storage.getAll<Vector>(QuantityId::POSITION);
73 
74  for (Size i = 0; i < r.size(); ++i) {
75  // gradually decrease the delta
76  const Float factor = 1._f + lerp(delta * dt, 0._f, (t - timeRange.lower()) / timeRange.size());
77 
78  // if the body is moving and/or rotating, we have to damp the velocities in co-moving frame
79  // rather than in world frame, otherwise we would slow the whole body down and lose (angular)
80  // momentum.
81  const Vector v_local = cross(data->omega, r[i] - data->center);
82 
83  // we have to dump only the deviation of velocities, not the initial rotation!
84  v[i] = (v[i] - v_local) / factor + v_local;
85  v[i][H] = 0._f;
86  SPH_ASSERT(isReal(v[i]));
87  }
88 
89  if (storage.has(QuantityId::DAMAGE)) {
90  // reset both the damage and its derivative
91  ArrayView<Float> D, dD;
92  tie(D, dD) = storage.getAll<Float>(QuantityId::DAMAGE);
93  const Float d0 = storage.getMaterial(0)->getParam<Float>(BodySettingsId::DAMAGE);
94  for (Size i = 0; i < D.size(); ++i) {
95  dD[i] = 0._f;
96  D[i] = d0;
97  }
98  }
99 
100  if (storage.has(QuantityId::STRESS_REDUCING)) {
102  for (Size i = 0; i < Y.size(); ++i) {
103  Y[i] = 1._f;
104  }
105  }
106  }
107 
108  virtual void collide(Storage& storage, Statistics& stats, const Float dt) override {
109  // no damping needed here, just forward the call
110  solver->collide(storage, stats, dt);
111  }
112 
113  virtual void create(Storage& storage, IMaterial& material) const override {
114  solver->create(storage, material);
115  }
116 
117 private:
118  void computeBodyData(const Storage& storage) {
119  data.emplace();
120 
124  data->center = Post::getCenterOfMass(m, r);
125  data->omega = Post::getAngularFrequency(m, r, v);
126  }
127 };
128 
Various function for interpretation of the results of a simulation.
INLINE bool isReal(const AntisymmetricTensor &t)
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
Boundary conditions.
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.
Base interface for all solvers.
INLINE T lerp(const T v1, const T v2, const TAmount amount)
Definition: MathUtils.h:341
#define NAMESPACE_SPH_END
Definition: Object.h:12
@ DAMAGE
Damage.
@ POSITION
Positions (velocities, accelerations) of particles, always a vector quantity,.
@ MASS
Paricles masses, always a scalar quantity.
@ STRESS_REDUCING
Total stress reduction factor due to damage and yielding. Is always scalar.
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
Statistics gathered and periodically displayed during the run.
@ RUN_TIME
Current time of the simulation in code units. Does not necessarily have to be 0 when run starts.
@ TIMESTEP_VALUE
Current value of timestep.
INLINE BasicVector< float > cross(const BasicVector< float > &v1, const BasicVector< float > &v2)
Cross product between two vectors.
Definition: Vector.h:559
@ H
Definition: Vector.h:25
@ Y
Definition: Vector.h:23
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
INLINE TCounter size() const
Definition: ArrayView.h:101
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
Base class for all solvers.
Definition: ISolver.h:20
virtual void integrate(Storage &storage, Statistics &stats)=0
Computes derivatives of all time-dependent quantities.
virtual void create(Storage &storage, IMaterial &material) const =0
Initializes all quantities needed by the solver in the storage.
virtual void collide(Storage &UNUSED(storage), Statistics &UNUSED(stats), const Float UNUSED(dt))
Detects the collisions and computes new positions of particles.
Definition: ISolver.h:54
Object representing a 1D interval of real numbers.
Definition: Interval.h:17
INLINE Float lower() const
Returns lower bound of the interval.
Definition: Interval.h:74
INLINE Float size() const
Returns the size of the interval.
Definition: Interval.h:89
void emplace(TArgs &&... args)
Constructs the uninitialized object from a list of arguments.
Definition: Optional.h:95
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
Helper solver used to converge into stable initial conditions.
virtual void integrate(Storage &storage, Statistics &stats) override
Computes derivatives of all time-dependent quantities.
StabilizationSolver(const Interval timeRange, const Float delta, AutoPtr< ISolver > &&solver)
virtual void create(Storage &storage, IMaterial &material) const override
Initializes all quantities needed by the solver in the storage.
StabilizationSolver(IScheduler &scheduler, const RunSettings &settings, AutoPtr< IBoundaryCondition > &&bc)
StabilizationSolver(const RunSettings &settings, AutoPtr< ISolver > &&solver)
virtual void collide(Storage &storage, Statistics &stats, const Float dt) override
Object holding various statistics about current run.
Definition: Statistics.h:22
TValue get(const StatisticsId idx) const
Returns value of a statistic.
Definition: Statistics.h:88
TValue getOr(const StatisticsId idx, const TValue &other) const
Returns value of a statistic, or a given value if the statistic is not stored.
Definition: Statistics.h:98
Container storing all quantities used within the simulations.
Definition: Storage.h:230
StaticArray< Array< TValue > &, 3 > getAll(const QuantityId key)
Retrieves quantity buffers from the storage, given its key and value type.
Definition: Storage.cpp:163
Array< TValue > & getDt(const QuantityId key)
Retrieves a quantity derivative from the storage, given its key and value type.
Definition: Storage.cpp:217
MaterialView getMaterial(const Size matIdx) const
Returns an object containing a reference to given material.
Definition: Storage.cpp:366
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
Creating code components based on values from settings.
Generic storage and input/output routines of settings.
@ DAMAGE
Initial damage of the body.
@ SPH_STABILIZATION_DAMPING
Provides a convenient way to construct objects from settings.
Definition: Factory.h:46
AutoPtr< ISolver > getSolver(IScheduler &scheduler, const RunSettings &settings)
Definition: Factory.cpp:278
Vector getAngularFrequency(ArrayView< const Float > m, ArrayView< const Vector > r, ArrayView< const Vector > v, const Vector &r0, const Vector &v0, ArrayView< const Size > idxs=nullptr)
Computes the immediate vector of angular frequency of a rigid body.
Definition: Analysis.cpp:514
Vector getCenterOfMass(ArrayView< const Float > m, ArrayView< const Vector > r, ArrayView< const Size > idxs=nullptr)
Computes the center of mass.
Definition: Analysis.cpp:461
Overload of std::swap for Sph::Array.
Definition: Array.h:578