hllc.cpp
1 #include "hllc.hpp"
3 #include "../../misc/universal_error.hpp"
4 #include "../../misc/utils.hpp"
5 
6 using namespace std;
7 
8 namespace {
9  class WaveSpeeds
10  {
11  public:
12 
13  WaveSpeeds(double left_i,
14  double center_i,
15  double right_i) :
16  left(left_i),
17  center(center_i),
18  right(right_i) {}
19 
20  const double left;
21  const double center;
22  const double right;
23  };
24 }
25 
26 namespace {
27  WaveSpeeds estimate_wave_speeds
28  (Primitive const& left, Primitive const& right)
29  {
30  const double dl = left.Density;
31  const double pl = left.Pressure;
32  const double vl = left.Velocity.x;
33  const double cl = left.SoundSpeed;
34  const double dr = right.Density;
35  const double pr = right.Pressure;
36  const double vr = right.Velocity.x;
37  const double cr = right.SoundSpeed;
38  const double sl = min(vl - cl, vr - cr);
39  const double sr = max(vl + cl, vr + cr);
40  const double ss = (pr - pl + dl*vl*(sl - vl) - dr*vr*(sr - vr)) /
41  (dl*(sl - vl) - dr*(sr - vr));
42  return WaveSpeeds(sl, ss, sr);
43  }
44 }
45 
46 namespace {
47  UniversalError invalid_wave_speeds(Primitive const& left,
48  Primitive const& right,
49  double velocity,
50  double left_wave_speed,
51  double center_wave_speed,
52  double right_wave_speed)
53  {
54  UniversalError res("Invalid wave speeds in hllc solver");
55  res.AddEntry("left density", left.Density);
56  res.AddEntry("left pressure", left.Pressure);
57  res.AddEntry("left x velocity", left.Velocity.x);
58  res.AddEntry("left y velocity", left.Velocity.y);
59  res.AddEntry("left sound speed", left.SoundSpeed);
60  res.AddEntry("left energy", left.Energy);
61  res.AddEntry("right density", right.Density);
62  res.AddEntry("right pressure", right.Pressure);
63  res.AddEntry("right x velocity", right.Velocity.x);
64  res.AddEntry("right y velocity", right.Velocity.y);
65  res.AddEntry("right sound speed", right.SoundSpeed);
66  res.AddEntry("right energy", right.Energy);
67  res.AddEntry("interface velocity", velocity);
68  res.AddEntry("left wave speed", left_wave_speed);
69  res.AddEntry("center wave speed", center_wave_speed);
70  res.AddEntry("right wave speed", right_wave_speed);
71  return res;
72  }
73 }
74 
75 namespace {
76  Conserved starred_state
77  (Primitive const& state, double sk, double ss)
78  {
79  const double dk = state.Density;
80  const double pk = state.Pressure;
81  const double uk = state.Velocity.x;
82  const double vk = state.Velocity.y;
83  const double ds = dk*(sk - uk) / (sk - ss);
84  const double ek = TotalEnergyDensity(state);
85  Conserved res;
86  res.Mass = ds;
87  res.Momentum.x = ds*ss;
88  res.Momentum.y = ds*vk;
89  res.Energy = ek*ds / dk +
90  ds*(ss - uk)*(ss + pk / dk / (sk - uk));
91  return res;
92  }
93 }
94 
95 Hllc::Hllc(bool massflux) :massflux_(massflux) {}
96 
97 Conserved Hllc::operator()
98 (Primitive const& left,
99  Primitive const& right,
100  double velocity) const
101 {
102  if (is_nan(right.Velocity.x))
103  throw UniversalError("Hllc::Solved entered with nan");
104 
105  const Vector2D normaldir(1, 0);
106  Primitive local_left = left;
107  Primitive local_right = right;
108 
109  local_left.Velocity -= velocity*normaldir;
110  local_right.Velocity -= velocity*normaldir;
111 
112  if (!massflux_)
113  {
114  WaveSpeeds ws2 = estimate_wave_speeds(local_left, local_right);
115 
116  local_left.Velocity -= ws2.center*normaldir;
117  local_right.Velocity -= ws2.center*normaldir;
118  velocity += ws2.center;
119  }
120 
121  WaveSpeeds ws = estimate_wave_speeds(local_left, local_right);
122 
123  const Conserved ul = Primitive2Conserved(local_left);
124  const Conserved ur = Primitive2Conserved(local_right);
125 
126  const Vector2D xdir(1, 0);
127  const Conserved fl = Primitive2Flux(local_left, xdir);
128  const Conserved fr = Primitive2Flux(local_right, xdir);
129 
130  const Conserved usl = starred_state(local_left, ws.left, ws.center);
131  const Conserved usr = starred_state(local_right, ws.right, ws.center);
132 
133  Conserved f_gr;
134  if (ws.left>0)
135  f_gr = fl;
136  else if (ws.left <= 0 && ws.center >= 0)
137  f_gr = fl + ws.left*(usl - ul);
138  else if (ws.center<0 && ws.right >= 0)
139  f_gr = fr + ws.right*(usr - ur);
140  else if (ws.right<0)
141  f_gr = fr;
142  else
143  throw invalid_wave_speeds(local_left,
144  local_right,
145  velocity,
146  ws.left,
147  ws.center,
148  ws.right);
149 
150  f_gr.Energy += ScalarProd(f_gr.Momentum, velocity*normaldir) +
151  0.5*f_gr.Mass*velocity*velocity;
152  f_gr.Momentum += velocity*f_gr.Mass*normaldir;
153  return f_gr;
154 }
Set of conserved variables (extensive)
Vector2D Momentum
Momentum.
double Density
Density.
double SoundSpeed
Speed of sound.
Hydrodynamic variables.
Container for error reports.
Vector2D Velocity
Velocity.
double max(vector< double > const &v)
returns the maximal term in a vector
Definition: utils.cpp:52
double Energy
Total energy (kinetic + thermal)
double TotalEnergyDensity(Primitive const &p)
Calculates the total energy density.
double y
Component in the y direction.
Definition: geometry.hpp:48
Conserved Primitive2Conserved(Primitive const &p)
Converts primitive variables to conserved intensive.
HLLC riemann solver on an eulerian grid.
Conserved Primitive2Flux(Primitive const &p, Vector2D const &n)
Converts primitive variables to flux.
double ScalarProd(Vector3D const &v1, Vector3D const &v2)
Scalar product of two vectors.
Definition: Vector3D.cpp:185
double min(vector< double > const &v)
Returns the minimal term in a vector.
Definition: utils.cpp:44
double Pressure
Pressure.
double Energy
Thermal energy per unit mass, entahalpy in relativistic case.
bool is_nan(double x)
Checks whether a number is a nan.
Definition: utils.cpp:19
Primitive hydrodynamic variables.
2D Mathematical vector
Definition: geometry.hpp:15
Hllc(bool massflux=true)
Class constructor.
Definition: hllc.cpp:95
double x
Component in the x direction.
Definition: geometry.hpp:45