plm1d.cpp
1 #include <cmath>
2 #include "plm1d.hpp"
3 #include "../../misc/universal_error.hpp"
4 
5 using namespace std;
6 
7 namespace {
8  Primitive Derivative(vector<double> const& grid,
9  vector<Primitive> const& cells,
10  size_t idx)
11  {
12  return (cells[idx]-cells[idx-1])/
13  (0.5*(grid[idx+1]-grid[idx-1]));
14 
15  }
16 
17  Primitive SymmetricDerivative(vector<double> const& grid,
18  vector<Primitive> const& cells,
19  size_t idx)
20  {
21  const double xr = 0.5*(grid[idx+2]+grid[idx+1]);
22  const double xl = 0.5*(grid[idx]+grid[idx-1]);
23  return (cells[idx+1]-cells[idx-1])/(xr-xl);
24  }
25 
26  bool effectively_zero(double x)
27  {
28  return fabs(x)<1e-14;
29  }
30 
31  double sgn(double x)
32  {
33  if(x>0)
34  return 1;
35  else if(x<0)
36  return -1;
37  else if(effectively_zero(x))
38  return 0;
39  else
40  throw UniversalError("NaN detected in sgn");
41  }
42 }
43 
44 namespace {
45  double my_min(double x, double y, double z)
46  {
47  return min(min(x,y),z);
48  }
49 
50  double minmod(double x, double y, double z)
51  {
52  return 0.125*(sgn(x)+sgn(y))*
53  (sgn(y)+sgn(z))*
54  (sgn(z)+sgn(x))*
55  my_min(abs(x),abs(y),abs(z));
56  }
57 
58  Primitive minmod(Primitive const& p1,
59  Primitive const& p2,
60  Primitive const& p3)
61  {
62  Primitive res;
63  for(int i=0;i<res.GetVarNo();++i)
64  res[i] = minmod(p1[i],p2[i],p3[i]);
65  return res;
66  }
67 }
68 
69 PLM1D::PLM1D(bool second_order_time,
70  bool slope_limiter_flag):
71  second_order_time_(second_order_time),
72  slope_limiter_flag_(slope_limiter_flag) {}
73 
74 Primitive PLM1D::operator()
75  (vector<double> const& vp,
76  vector<Primitive> const& hv,
77  double /*interface_speed*/,
78  size_t idx,
79  int dir, double dt) const
80 {
81  if(dir==0){
82  if(idx==1)
83  return hv[0];
84  else if(idx==vp.size()-1)
85  return hv[vp.size()-2];
86  else if(idx==0)
87  throw UniversalError("Error in PLM1D::InterpState\n Target of interpolation lies outside grid, on the left side");
88  else{
89  Primitive slope_left = Derivative(vp,hv,idx-1);
90  Primitive slope_center = Derivative(vp,hv,idx);
91  Primitive slope_symmetric = SymmetricDerivative(vp,hv,idx-1);
92  Primitive slope = minmod(slope_left,slope_center,2*slope_symmetric);
93  double dx = vp[idx]-vp[idx-1];
94  if(!slope_limiter_flag_)
95  return hv[idx-1]+slope_center*dx/2;
96  if(second_order_time_)
97  return hv[idx-1]+slope*(dx/2-hv[idx-1].SoundSpeed*dt/2);
98  else
99  return hv[idx-1]+slope*dx/2;
100  }
101  }
102  else if(dir==1){
103  if(idx==vp.size()-2)
104  return hv[vp.size()-2];
105  else if(idx==0)
106  return hv[0];
107  else if(idx==vp.size()-1)
108  throw UniversalError("Error in PLM1D::InterpState\n Target of interpolation lies outside grid, on the right side");
109  else{
110  Primitive slope_right = Derivative(vp,hv,idx+1);
111  Primitive slope_center = Derivative(vp,hv,idx);
112  Primitive slope_symmetric = SymmetricDerivative(vp,hv,idx);
113  Primitive slope = minmod(slope_center,slope_right,2*slope_symmetric);
114  double dx = vp[idx+1]-vp[idx];
115  if(!slope_limiter_flag_)
116  return hv[idx]-slope_center*dx/2;
117  if(second_order_time_)
118  return hv[idx]-slope*(dx/2-hv[idx].SoundSpeed*dt/2);
119  else
120  return hv[idx]-slope*dx/2;
121  }
122  }
123  else
124  throw UniversalError("Unknown direction in plm1d");
125 }
PLM1D(bool second_order_time=false, bool slope_limiter_flag=true)
Class constructor.
Definition: plm1d.cpp:69
int GetVarNo(void) const
Returns the numbers of members.
Container for error reports.
double min(vector< double > const &v)
Returns the minimal term in a vector.
Definition: utils.cpp:44
Piecewise linear method for spatial reconstruction.
double abs(Vector3D const &v)
Norm of a vector.
Definition: Vector3D.cpp:44
Primitive hydrodynamic variables.