LagrangianExtensiveUpdate.cpp
1 #include "LagrangianExtensiveUpdate.hpp"
2 #include "../../misc/utils.hpp"
3 #ifdef RICH_MPI
4 #include <mpi.h>
5 #endif
6 namespace
7 {
8  bool bracketed(int low, int arg, int high)
9  {
10  return arg >= low && high > arg;
11  }
12 }
13 
15  const& ghost) :lflux_(lflux), ghost_(ghost) {}
16 
17 void LagrangianExtensiveUpdate::operator()(const vector<Extensive>& fluxes, const PhysicalGeometry& /*pg*/,
18  const Tessellation& tess, const double dt, const CacheData& cd, const vector<ComputationalCell>& cells,
19  vector<Extensive>& extensives, double time, TracerStickerNames const& tracerstickernames) const
20 {
21  const vector<Edge>& edge_list = tess.getAllEdges();
22  Extensive delta = dt*cd.areas[0] * fluxes[0];
23  size_t N = static_cast<size_t>(tess.GetPointNo());
24  std::vector<double> dA(N, 0), dWs(N, 0);
25  size_t indexX = static_cast<size_t>(binary_find(tracerstickernames.tracer_names.begin(), tracerstickernames.tracer_names.end(),
26  string("AreaX")) - tracerstickernames.tracer_names.begin());
27  size_t indexY = static_cast<size_t>(binary_find(tracerstickernames.tracer_names.begin(), tracerstickernames.tracer_names.end(),
28  string("AreaY")) - tracerstickernames.tracer_names.begin());
29  //assert(indexX < tracerstickernames.tracer_names.size() && indexY < tracerstickernames.tracer_names.size());
30  bool area_calc = false;
31  if (indexX < tracerstickernames.tracer_names.size())
32  {
33  area_calc = true;
34  for (size_t i = 0; i < N; ++i)
35  {
36  extensives[i].tracers[indexX] *= 0.85;
37  extensives[i].tracers[indexY] *= 0.85;
38  }
39  }
40 
41  boost::container::flat_map<size_t,ComputationalCell> ghosts = ghost_(tess, cells, time, tracerstickernames);
42  vector<ComputationalCell> newcells(cells);
43  newcells.resize(static_cast<size_t>(tess.GetTotalPointNumber()));
44  for (boost::container::flat_map<size_t, ComputationalCell>::iterator it = ghosts.begin(); it != ghosts.end(); ++it)
45  newcells[it->first] = it->second;
46 
47  for (size_t i = 0; i < edge_list.size(); ++i)
48  {
49  const Edge& edge = edge_list[i];
50  ReplaceExtensive(delta, fluxes[i]);
51  delta *= dt*cd.areas[i];
52  double deltaWs = -lflux_.ws_[i] * cd.areas[i] * dt;
53  Vector2D normal = normalize(tess.GetMeshPoint(edge.neighbors.second) - tess.GetMeshPoint(edge.neighbors.first));
54  if (lflux_.Lag_calc_[i])
55  {
56  double p_star = ScalarProd(fluxes[i].momentum, normal);
57  double v_star = fluxes[i].energy / p_star;
58  double v_new = (v_star - lflux_.ws_[i]);
59  if (v_new*v_star > 0)
60  {
61  if (v_new > 0 && tess.GetOriginalIndex(edge.neighbors.second) != tess.GetOriginalIndex(edge.neighbors.first)
62  && p_star > 1.2*newcells[static_cast<size_t>(edge.neighbors.second)].pressure)
63  v_new = std::max(v_new, ScalarProd(newcells[static_cast<size_t>(edge.neighbors.second)].velocity,
64  normal));
65  if (v_new < 0 && tess.GetOriginalIndex(edge.neighbors.second) != tess.GetOriginalIndex(edge.neighbors.first)
66  && p_star > 1.2*newcells[static_cast<size_t>(edge.neighbors.first)].pressure)
67  v_new = std::min(v_new, ScalarProd(newcells[static_cast<size_t>(edge.neighbors.first)].velocity,
68  normal));
69  delta.energy = p_star*v_new*cd.areas[i] * dt;
70  }
71  else
72  {
73  if (v_new > 0 && tess.GetOriginalIndex(edge.neighbors.first) != tess.GetOriginalIndex(edge.neighbors.second))
74  delta.energy = cd.areas[i] * dt*v_new*newcells[static_cast<size_t>(edge.neighbors.first)].pressure;
75  else
76  if (tess.GetOriginalIndex(edge.neighbors.second) != tess.GetOriginalIndex(edge.neighbors.first))
77  delta.energy = cd.areas[i] * dt*v_new*newcells[static_cast<size_t>(edge.neighbors.second)].pressure;
78  else
79  delta.energy = 0;
80  }
81  }
82  if (bracketed(0, edge.neighbors.first, tess.GetPointNo()))
83  {
84  extensives[static_cast<size_t>(edge.neighbors.first)] -= delta;
85  if (area_calc)
86  {
87  extensives[static_cast<size_t>(edge.neighbors.first)].tracers[indexX] -= normal.x*deltaWs;
88  extensives[static_cast<size_t>(edge.neighbors.first)].tracers[indexY] -= normal.y*deltaWs;
89  }
90  }
91  if (bracketed(0, edge.neighbors.second, tess.GetPointNo()))
92  {
93  extensives[static_cast<size_t>(edge.neighbors.second)] += delta;
94  if (area_calc)
95  {
96  extensives[static_cast<size_t>(edge.neighbors.second)].tracers[indexX] -= normal.x*deltaWs;
97  extensives[static_cast<size_t>(edge.neighbors.second)].tracers[indexY] -= normal.y*deltaWs;
98  }
99  }
100  }
101 
102  for (size_t i = 0; i < N; ++i)
103  {
104  if ((!(extensives[i].mass > 0)) || (!(extensives[i].energy > 0)) || (!std::isfinite(extensives[i].momentum.x)) || (!std::isfinite(extensives[i].momentum.y)))
105  {
106  int rank = 0;
107 #ifdef RICH_MPI
108  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
109 #endif
110  std::cout << "Bad cell in LagrangianExtensiveUpdate, cell " << i << " rank " << rank << " time " << time << std::endl;
111  std::cout << "mass " << extensives[i].mass << " energy " << extensives[i].energy << " Entropy " <<
112  extensives[i].tracers[0] << " momentum" << abs(extensives[i].momentum) << " volume " << cd.volumes[i]<< std::endl;
113  std::cout << "Old cell, density " << cells[i].density << " pressure " << cells[i].pressure << " v " <<
114  abs(cells[i].velocity) << std::endl;
115  std::vector<int> temp = tess.GetCellEdges(static_cast<int>(i));
116  for (size_t j = 0; j < temp.size(); ++j)
117  {
118  Edge edge = tess.GetEdge(temp[j]);
119  int N0 = tess.GetEdge(temp[j]).neighbors.first;
120  int N1 = tess.GetEdge(temp[j]).neighbors.second;
121  double Area = tess.GetEdge(temp[j]).GetLength() * dt;
122  std::cout << "Edge " << temp[j] << " neigh " << N0 << "," << N1 << " mass=" << fluxes[static_cast<size_t>(temp[j])].mass*Area <<
123  " energy " << fluxes[static_cast<size_t>(temp[j])].energy*Area << " momentum=" << abs(fluxes[static_cast<size_t>(temp[j])].momentum)*Area <<
124  " L*dt " << Area << " N0 " << tess.GetMeshPoint(N0).x << "," << tess.GetMeshPoint(N0).y << " N1 "
125  << tess.GetMeshPoint(N1).x << "," << tess.GetMeshPoint(N1).y << std::endl;
126  std::cout << "dl " << newcells[static_cast<size_t>(N0)].density << " pl " << newcells[static_cast<size_t>(N0)].pressure << " vxl " << newcells[static_cast<size_t>(N0)].velocity.x << " vyl " << newcells[static_cast<size_t>(N0)].velocity.y << std::endl;
127  std::cout << "dr " << newcells[static_cast<size_t>(N1)].density << " pr " << newcells[static_cast<size_t>(N1)].pressure << " vxr " << newcells[static_cast<size_t>(N1)].velocity.x << " vyr " << newcells[static_cast<size_t>(N1)].velocity.y << std::endl;
128  Vector2D normal = normalize(tess.GetMeshPoint(N1) - tess.GetMeshPoint(N0));
129  std::cout << "dx " << normal.x << " dy " << normal.y << std::endl;
130  if (lflux_.Lag_calc_[static_cast<size_t>(temp[j])])
131  {
132  double p_star = ScalarProd(fluxes[static_cast<size_t>(temp[j])].momentum, normal);
133  double v_star = fluxes[static_cast<size_t>(temp[j])].energy / p_star;
134  double v_new = (v_star - lflux_.ws_[static_cast<size_t>(temp[j])]);
135  std::cout << "Old pstar " << p_star << " vstar " << v_star << " vnew " << v_new << std::endl;
136  if (v_new*v_star > 0)
137  {
138  if (v_new > 0 && tess.GetOriginalIndex(edge.neighbors.second) != tess.GetOriginalIndex(edge.neighbors.first)
139  && p_star > 1.2*newcells[static_cast<size_t>(edge.neighbors.second)].pressure)
140  v_new = std::max(v_new, ScalarProd(newcells[static_cast<size_t>(edge.neighbors.second)].velocity,
141  normal));
142  if (v_new < 0 && tess.GetOriginalIndex(edge.neighbors.second) != tess.GetOriginalIndex(edge.neighbors.first)
143  && p_star > 1.2*newcells[static_cast<size_t>(edge.neighbors.first)].pressure)
144  v_new = std::min(v_new, ScalarProd(newcells[static_cast<size_t>(edge.neighbors.first)].velocity,
145  normal));
146  }
147  else
148  {
149  if (v_new > 0 && tess.GetOriginalIndex(edge.neighbors.first) != tess.GetOriginalIndex(edge.neighbors.second))
150  p_star = newcells[static_cast<size_t>(edge.neighbors.first)].pressure;
151  else
152  if (tess.GetOriginalIndex(edge.neighbors.second) != tess.GetOriginalIndex(edge.neighbors.first))
153  p_star = newcells[static_cast<size_t>(edge.neighbors.second)].pressure;
154  else
155  p_star = 0;
156  }
157  std::cout << "Pstar " << p_star << " Ustar " << v_new << std::endl;
158  }
159  }
160  assert(false);
161  }
162  }
163 }
164 
Extensive variables.
Definition: extensive.hpp:18
Abstract class for tessellation.
vector< bool > Lag_calc_
Was this edge calculated Lagrangialy.
virtual int GetPointNo(void) const =0
Get Total number of mesh generating points.
virtual int GetOriginalIndex(int point) const
Returns the original index of the duplicated point.
Definition: tessellation.cpp:5
Interface between two cells.
Definition: Edge.hpp:13
virtual Vector2D GetMeshPoint(int index) const =0
Returns Position of mesh generating point.
const CachedLazyList< double > areas
List of areas of interfaces.
Definition: cache_data.hpp:84
double max(vector< double > const &v)
returns the maximal term in a vector
Definition: utils.cpp:52
Abstract class for creating ghost points.
double energy
energy, in relativity it is = rho*h*gamma^2-P-rho
Definition: extensive.hpp:28
double y
Component in the y direction.
Definition: geometry.hpp:48
LagrangianExtensiveUpdate(LagrangianFlux const &lflux, GhostPointGenerator const &ghost)
Class constructor.
virtual Edge const & GetEdge(int index) const =0
Returns edge (interface between cells)
double ScalarProd(Vector3D const &v1, Vector3D const &v2)
Scalar product of two vectors.
Definition: Vector3D.cpp:185
virtual const vector< Edge > & getAllEdges(void) const =0
Returns reference to the list of all edges.
void ReplaceExtensive(Extensive &toreplace, Extensive const &other)
Replaces the data in the extensive. The tracers should already be allocated.
Definition: extensive.cpp:47
virtual int GetTotalPointNumber(void) const =0
Returns the total number of points (including ghost)
const CachedLazyList< double > volumes
List of cell volumes.
Definition: cache_data.hpp:81
Container for cache data.
Definition: cache_data.hpp:14
std::vector< std::string > tracer_names
The names of the tracers.
double min(vector< double > const &v)
Returns the minimal term in a vector.
Definition: utils.cpp:44
void operator()(const vector< Extensive > &fluxes, const PhysicalGeometry &pg, const Tessellation &tess, const double dt, const CacheData &cd, const vector< ComputationalCell > &cells, vector< Extensive > &extensives, double time, TracerStickerNames const &tracerstickernames) const
Updates the extensive variables.
Vector2D normalize(const Vector2D &v)
Normalized a vector.
Definition: geometry.cpp:158
Class for keeping the names of the tracers and stickers.
std::pair< int, int > neighbors
Neighboring cells.
Definition: Edge.hpp:21
double abs(Vector3D const &v)
Norm of a vector.
Definition: Vector3D.cpp:44
A flux scheme that minimises mass transfer between cells.
virtual vector< int > const & GetCellEdges(int index) const =0
Returns the indexes of a cell&#39;s edges.
Iter binary_find(Iter begin, Iter end, T val)
Binary search that return iterator of found object or end if not found.
Definition: utils.hpp:709
2D Mathematical vector
Definition: geometry.hpp:15
double GetLength(void) const
Returns the length of the edge.
Definition: Edge.cpp:26
Base class for physical geometry.
double x
Component in the x direction.
Definition: geometry.hpp:45
vector< double > ws_
Velocity of the interfaces.