SPH
Solution.cpp
Go to the documentation of this file.
1 #include "sod/Solution.h"
2 #include "quantities/Quantity.h"
3 #include "quantities/Storage.h"
4 
6 
7 static Pair<Float> computeCharacteristics(const SodConfig& sod,
8  const Float P3,
9  const Float P,
10  const Float c) {
11  const Float u = P3 / P;
12  if (u > 1) {
13  const Float term1 = sod.gamma * ((sod.gamma + 1.) * u + sod.gamma - 1.);
14  const Float term2 = sqrt(2. / term1);
15  const Float fp = (u - 1.) * c * term2;
16  const Float dfdp =
17  c * term2 / P + (u - 1.) * c / term2 * (-1. / sqr(term1)) * sod.gamma * (sod.gamma + 1.) / P;
18  return { fp, dfdp };
19  } else {
20  const Float beta = (sod.gamma - 1) / (2 * sod.gamma);
21  const Float fp = (pow(u, beta) - 1.) * (2. * c / (sod.gamma - 1.));
22  const Float dfdp = 2. * c / (sod.gamma - 1.) * beta * pow(u, (beta - 1.)) / P;
23  return { fp, dfdp };
24  }
25 }
26 
27 static Pair<Float> solveRiemannProblem(const SodConfig& sod) {
28  const Float c_l = sqrt(sod.gamma * sod.P_l / sod.rho_l);
29  const Float c_r = sqrt(sod.gamma * sod.P_r / sod.rho_r);
30 
31  const Float beta = (sod.gamma - 1) / (2 * sod.gamma);
32 
33  Float P_new = pow((c_l + c_r + (sod.u_l - sod.u_r) * 0.5 * (sod.gamma - 1.)) /
34  (c_l / pow(sod.P_l, beta) + c_r / pow(sod.P_r, beta)),
35  1. / beta);
36  Float P3 = 0.5 * (sod.P_r + sod.P_l);
37  Float f_L = 0._f, f_R = 0._f;
38  while (fabs(P3 - P_new) > 1e-6) {
39  P3 = P_new;
40  Float dfdp_L, dfdp_R;
41  tie(f_L, dfdp_L) = computeCharacteristics(sod, P3, sod.P_l, c_l);
42  tie(f_R, dfdp_R) = computeCharacteristics(sod, P3, sod.P_r, c_r);
43  const Float f = f_L + f_R + (sod.u_r - sod.u_l);
44  const Float df = dfdp_L + dfdp_R;
45  const Float dp = -f / df;
46  P_new = P3 + dp;
47  }
48  const Float v_3 = sod.u_l - f_L;
49  return { P_new, v_3 };
50 }
51 
52 Storage analyticSod(const SodConfig& sod, const Float t) {
53  const Float x_min = -0.5;
54  const Float x_max = 0.5;
55  const Float mu = sqrt((sod.gamma - 1._f) / (sod.gamma + 1._f));
56  // const Float beta = (sod.gamma - 1) / (2 * sod.gamma);
57 
59  const Float c_l = sqrt(sod.gamma * sod.P_l / sod.rho_l);
60 
61  Float P_post;
62  Float v_post;
63  tie(P_post, v_post) = solveRiemannProblem(sod);
64 
65  const Float rho_post = sod.rho_r * (((P_post / sod.P_r) + sqr(mu)) / (1 + mu * mu * (P_post / sod.P_r)));
66  const Float v_shock = v_post * ((rho_post / sod.rho_r) / ((rho_post / sod.rho_r) - 1));
67  const Float rho_middle = sod.rho_l * pow((P_post / sod.P_l), 1 / sod.gamma);
68 
69  // Key Positions
70  const Float x1 = sod.x0 - c_l * t;
71  const Float x3 = sod.x0 + v_post * t;
72  const Float x4 = sod.x0 + v_shock * t;
73 
74  // determining x2
75  const Float c_2 = c_l - ((sod.gamma - 1) / 2) * v_post;
76  const Float x2 = sod.x0 + (v_post - c_2) * t;
77  // start setting values
78  Array<Vector> pos(1000);
79  for (Size i = 0; i < pos.size(); ++i) {
80  const Float x = x_min + (x_max - x_min) / pos.size() * i;
81  pos[i] = Vector(x, 0._f, 0._f, EPS);
82  }
83  Storage storage;
84  storage.insert<Vector>(QuantityId::POSITION, OrderEnum::FIRST, std::move(pos));
88 
89  ArrayView<Vector> r, v;
90  tie(r, v) = storage.getAll<Vector>(QuantityId::POSITION);
94 
95  for (Size i = 0; i < r.size(); ++i) {
96  const Float x = r[i][X];
97  if (x < x1) {
98  // Solution left of x1
99  rho[i] = sod.rho_l;
100  P[i] = sod.P_l;
101  v[i][X] = sod.u_l;
102  } else if (x1 <= x && x <= x2) {
103  // Solution between x1 and x2
104  const Float c = mu * mu * ((sod.x0 - x) / t) + (1 - mu * mu) * c_l;
105  rho[i] = sod.rho_l * pow((c / c_l), 2 / (sod.gamma - 1));
106  P[i] = sod.P_l * pow((rho[i] / sod.rho_l), sod.gamma);
107  v[i][X] = (1 - mu * mu) * ((-(sod.x0 - x) / t) + c_l);
108  } else if (x2 <= x && x <= x3) {
109  // Solution between x2 and x3
110  rho[i] = rho_middle;
111  P[i] = P_post;
112  v[i][X] = v_post;
113  } else if (x3 <= x && x <= x4) {
114  // Solution between x3 and x4
115  rho[i] = rho_post;
116  P[i] = P_post;
117  v[i][X] = v_post;
118  } else {
119  // Solution after x4
120  rho[i] = sod.rho_r;
121  P[i] = sod.P_r;
122  v[i][X] = sod.u_r;
123  }
124  u[i] = P[i] / ((sod.gamma - 1._f) * rho[i]);
125  }
126  return storage;
127 }
128 
129 
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
constexpr Float EPS
Definition: MathUtils.h:30
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
INLINE T sqrt(const T f)
Return a squared root of a value.
Definition: MathUtils.h:78
constexpr INLINE Float pow(const Float v)
Power for floats.
#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,.
@ ENERGY
Specific internal energy, always a scalar quantity.
@ DENSITY
Density, always a scalar quantity.
Holder of quantity values and their temporal derivatives.
@ FIRST
Quantity with 1st derivative.
@ ZERO
Quantity without derivatives, or "zero order" of quantity.
Storage analyticSod(const SodConfig &sod, const Float t)
Definition: Solution.cpp:52
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.
BasicVector< Float > Vector
Definition: Vector.h:539
@ X
Definition: Vector.h:22
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
Generic dynamically allocated resizable storage.
Definition: Array.h:43
INLINE TCounter size() const noexcept
Definition: Array.h:193
Array with fixed number of allocated elements.
Definition: StaticArray.h:19
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
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 > & getValue(const QuantityId key)
Retrieves a quantity values from the storage, given its key and value type.
Definition: Storage.cpp:191
Float P_r
Definition: Solution.h:18
Float P_l
Definition: Solution.h:14
Float u_r
Definition: Solution.h:19
Float u_l
Definition: Solution.h:15
Float x0
Definition: Solution.h:12
Float rho_r
Definition: Solution.h:17
Float gamma
Definition: Solution.h:21
Float rho_l
Definition: Solution.h:13