LagrangianHLLC.cpp
1 #include "LagrangianHLLC.hpp"
3 #include "../../misc/universal_error.hpp"
4 #include "../../misc/utils.hpp"
5 #include <cmath>
6 
7 using namespace std;
8 
9 namespace
10 {
11  std::pair<double, double> HLLpu(Primitive const& left,Primitive const& right,EquationOfState const& eos)
12  {
13  double sl = std::min(left.Velocity.x - left.SoundSpeed, right.Velocity.x - right.SoundSpeed);
14  double sr = std::max(left.Velocity.x + left.SoundSpeed, right.Velocity.x + right.SoundSpeed);
15  Conserved Ul(left.Density, left.Density*left.Velocity, left.Density*(left.Energy + ScalarProd(left.Velocity, left.Velocity*0.5))),
16  Ur(right.Density, right.Density*right.Velocity, right.Density*(right.Energy + ScalarProd(right.Velocity, right.Velocity*0.5)));
17  Conserved Fl(left.Density*left.Velocity.x, Vector2D(left.Density*left.Velocity.x*left.Velocity.x + left.Pressure, left.Density*left.Velocity.x*left.Velocity.y), (Ul.Energy + left.Pressure)*left.Velocity.x),
18  Fr(right.Density*right.Velocity.x, Vector2D(right.Density*right.Velocity.x*right.Velocity.x + right.Pressure, right.Density*right.Velocity.x*right.Velocity.y), (Ur.Energy + right.Pressure)*right.Velocity.x);
19  Conserved Ull = (sr*Ur - sl * Ul + Fl - Fr) / (sr - sl);
20  return std::pair<double, double> (eos.de2p(Ull.Mass, std::max(0.0,(Ull.Energy - ScalarProd(Ull.Momentum,Ull.Momentum)*0.5 / Ull.Mass))/Ull.Mass), Ull.Momentum.x / Ull.Mass);
21  }
22 
23  class WaveSpeeds
24  {
25  public:
26 
27  WaveSpeeds(double left_i,
28  double center_i,
29  double right_i,double ps_i) :
30  left(left_i),
31  center(center_i),
32  right(right_i),ps(ps_i) {}
33 
34  WaveSpeeds(WaveSpeeds const& other):left(other.left),center(other.center),
35  right(other.right),ps(other.ps){}
36 
37  WaveSpeeds& operator=(WaveSpeeds const& ws)
38  {
39  left = ws.left;
40  center = ws.center;
41  right = ws.right;
42  ps = ws.ps;
43  return *this;
44  }
45 
46  double left;
47  double center;
48  double right;
49  double ps;
50  };
51 }
52 
53 namespace
54 {
55  WaveSpeeds estimate_wave_speeds(Primitive const& left, Primitive const& right,double pstar)
56  {
57  const double dl = left.Density;
58  const double pl = left.Pressure;
59  const double vl = left.Velocity.x;
60  const double cl = left.SoundSpeed;
61  const double dr = right.Density;
62  const double pr = right.Pressure;
63  const double vr = right.Velocity.x;
64  const double cr = right.SoundSpeed;
65  const double sl = vl - cl * (pstar > pl ? std::sqrt(0.8*(pstar / pl - 1) + 1) : 1);
66  const double sr = vr + cr * (pstar > pr ? std::sqrt(0.8*(pstar / pr - 1) + 1) : 1);
67  const double denom = 1.0 /(dl*(sl - vl) - dr * (sr - vr));
68  const double ss = (pr - pl + dl * vl*(sl - vl) - dr * vr*(sr - vr)) *denom;
69  const double ps = std::max(0.0,dl * (sl - vl)*(pr - dr * (vr - vl)*(sr - vr)) *denom - pl * dr*(sr - vr) *denom);
70  return WaveSpeeds(sl, ss, sr,ps);
71  }
72 }
73 
74 namespace
75 {
76  UniversalError invalid_wave_speeds(Primitive const& left,
77  Primitive const& right,
78  double velocity,
79  double left_wave_speed,
80  double center_wave_speed,
81  double right_wave_speed)
82  {
83  UniversalError res("Invalid wave speeds in hllc solver");
84  res.AddEntry("left density", left.Density);
85  res.AddEntry("left pressure", left.Pressure);
86  res.AddEntry("left x velocity", left.Velocity.x);
87  res.AddEntry("left y velocity", left.Velocity.y);
88  res.AddEntry("left sound speed", left.SoundSpeed);
89  res.AddEntry("left energy", left.Energy);
90  res.AddEntry("right density", right.Density);
91  res.AddEntry("right pressure", right.Pressure);
92  res.AddEntry("right x velocity", right.Velocity.x);
93  res.AddEntry("right y velocity", right.Velocity.y);
94  res.AddEntry("right sound speed", right.SoundSpeed);
95  res.AddEntry("right energy", right.Energy);
96  res.AddEntry("interface velocity", velocity);
97  res.AddEntry("left wave speed", left_wave_speed);
98  res.AddEntry("center wave speed", center_wave_speed);
99  res.AddEntry("right wave speed", right_wave_speed);
100  return res;
101  }
102 }
103 
104 namespace
105 {
106  Conserved starred_state
107  (Primitive const& state, double sk, double ss)
108  {
109  const double dk = state.Density;
110  const double pk = state.Pressure;
111  const double uk = state.Velocity.x;
112  const double vk = state.Velocity.y;
113  const double ds = dk*(sk - uk) / (sk - ss);
114  const double ek = TotalEnergyDensity(state);
115  Conserved res;
116  res.Mass = ds;
117  res.Momentum.x = ds*ss;
118  res.Momentum.y = ds*vk;
119  res.Energy = ek*ds / dk +
120  ds*(ss - uk)*(ss + pk / dk / (sk - uk));
121  return res;
122  }
123 }
124 
125 LagrangianHLLC::LagrangianHLLC(EquationOfState const& eos,bool massflux,bool iter) :eos_(eos), massflux_(massflux),iter_(iter),energy(0)
126 {}
127 
128 Conserved LagrangianHLLC::operator()
129 (Primitive const& left,
130  Primitive const& right,
131  double velocity) const
132 {
133  if (is_nan(right.Velocity.x))
134  throw UniversalError("Hllc::Solved entered with nan");
135 
136  const Vector2D normaldir(1, 0);
137  Primitive local_left = left;
138  Primitive local_right = right;
139 
140  local_left.Velocity -= velocity*normaldir;
141  local_right.Velocity -= velocity*normaldir;
142 
143  Conserved f_gr;
144  std::pair<double, double> p_u_star = HLLpu(local_left, local_right, eos_);
145  double old_ps = p_u_star.first;
146 
147  //old_ps = 0;
148 
149  WaveSpeeds ws = estimate_wave_speeds(local_left, local_right, old_ps);
150  if (iter_)
151  {
152  size_t counter = 0;
153  while (ws.ps > 1.01 * old_ps || old_ps > 1.01 * ws.ps)
154  {
155  old_ps = ws.ps;
156  ws = estimate_wave_speeds(local_left, local_right, ws.ps);
157  ++counter;
158  if (counter > 54)
159  {
160  std::cout << "Too many iterations in HLLC" << std::endl;
161  std::cout << "Normal " << normaldir.x << "," << normaldir.y << " velocity = " << velocity << std::endl;
162  std::cout << " Left density = " << left.Density << " pressure = " << left.Pressure << " internal_energy = " << left.Energy << " vx = " << left.Velocity.x <<
163  " vy = " << left.Velocity.y << std::endl;
164  std::cout << " Right density = " << right.Density << " pressure = " << right.Pressure << " internal_energy = " << right.Energy << " vx = " << right.Velocity.x <<
165  " vy = " << right.Velocity.y << std::endl;
166  std::cout << "Old Pstar = " << old_ps << " new Pstar = " << ws.ps << std::endl;
167  throw UniversalError("LagrangianHllc::No convergence");
168  }
169 
170  }
171  }
172  if (!massflux_)
173  {
174  local_left.Velocity -= ws.center*normaldir;
175  local_right.Velocity -= ws.center*normaldir;
176  velocity += ws.center;
177  energy = ws.center;
178  ws = estimate_wave_speeds(local_left, local_right, ws.ps);
179  }
180 
181 
182  const Conserved ul = Primitive2Conserved(local_left);
183  const Conserved ur = Primitive2Conserved(local_right);
184 
185  const Vector2D xdir(1, 0);
186  const Conserved fl = Primitive2Flux(local_left, xdir);
187  const Conserved fr = Primitive2Flux(local_right, xdir);
188 
189  const Conserved usl = starred_state(local_left, ws.left, ws.center);
190  const Conserved usr = starred_state(local_right, ws.right, ws.center);
191 
192  if (ws.left > 0)
193  {
194  f_gr = fl;
195  if(massflux_)
196  energy = ScalarProd(local_left.Velocity, xdir)*local_left.Energy*local_left.Density;
197  }
198  else if (ws.left <= 0 && ws.center >= 0)
199  {
200  f_gr = fl + ws.left*(usl - ul);
201  if (massflux_)
202  energy = ScalarProd(local_left.Velocity, xdir)*local_left.Energy*local_left.Density +
203  ws.left*local_left.Energy*((ws.left-local_left.Velocity.x)/(ws.left-ws.center)-1)*local_left.Density;
204  }
205  else if (ws.center < 0 && ws.right >= 0)
206  {
207  f_gr = fr + ws.right*(usr - ur);
208  if (massflux_)
209  energy = (ScalarProd(local_right.Velocity, xdir)*local_right.Energy + ws.right*local_right.Energy*
210  ((ws.right - local_right.Velocity.x) / (ws.right - ws.center) - 1))*local_right.Density;
211  }
212  else if (ws.right<0)
213  {
214  f_gr = fr;
215  if (massflux_)
216  energy = ScalarProd(local_right.Velocity, xdir)*local_right.Energy*local_right.Density;
217  }
218  else
219  throw invalid_wave_speeds(local_left,
220  local_right,
221  velocity,
222  ws.left,
223  ws.center,
224  ws.right);
225 
226  f_gr.Energy += ScalarProd(f_gr.Momentum, velocity*normaldir) +
227  0.5*f_gr.Mass*velocity*velocity;
228  f_gr.Momentum += velocity*f_gr.Mass*normaldir;
229  return f_gr;
230 }
Set of conserved variables (extensive)
Vector2D Momentum
Momentum.
double Density
Density.
double SoundSpeed
Speed of sound.
Hydrodynamic variables.
virtual double de2p(double d, double e, tvector const &tracers=tvector(), vector< string > const &tracernames=vector< string >()) const =0
Calculates the pressure.
Container for error reports.
Vector2D Velocity
Velocity.
double energy
Energy.
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.
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
Base class for equation of state.
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
HLLC riemann solver that keeps track of transfered internal energy.
Primitive hydrodynamic variables.
2D Mathematical vector
Definition: geometry.hpp:15
double x
Component in the x direction.
Definition: geometry.hpp:45
LagrangianHLLC(EquationOfState const &eos, bool massflux=true, bool iter=false)
Class constructor.