LinearGaussImproved.cpp
2 #include "../../../misc/utils.hpp"
3 #include <array>
4 #ifdef RICH_MPI
5 #include "../../../mpi/mpi_commands.hpp"
6 #endif //RICH_MPI
7 
8 
9 
10 namespace
11 {
12  void GetNeighborMesh(Tessellation const& tess, vector<const Edge *> const& edges, size_t cell_index,
13  vector<Vector2D> &res)
14  {
15  res.resize(edges.size());
16  const size_t nloop = edges.size();
17  for (size_t i = 0; i < nloop; ++i)
18  {
19  const int neigh0 = edges[i]->neighbors.first;
20  const int neigh1 = edges[i]->neighbors.second;
21  if (neigh0 == static_cast<int>(cell_index))
22  res[i] = tess.GetMeshPoint(neigh1);
23  else
24  res[i] = tess.GetMeshPoint(neigh0);
25  }
26  }
27 
28  void GetNeighborCM(Tessellation const& tess, vector<const Edge*> const& edges, size_t cell_index,
29  vector<Vector2D> &res)
30  {
31  res.resize(edges.size());
32  const size_t nloop = edges.size();
33  for (size_t i = 0; i < nloop; ++i)
34  {
35  const int neigh0 = edges[i]->neighbors.first;
36  const int neigh1 = edges[i]->neighbors.second;
37  if (neigh0 == static_cast<int>(cell_index))
38  res[i] = tess.GetCellCM(neigh1);
39  else
40  res[i] = tess.GetCellCM(neigh0);
41  }
42  }
43 
44  vector<ComputationalCell const*> GetNeighborCells(vector<const Edge *> const& edges, size_t cell_index,
45  vector<ComputationalCell> const& cells)
46  {
47  vector<ComputationalCell const*> res(edges.size());
48  const size_t nloop = edges.size();
49  for (size_t i = 0; i < nloop; ++i)
50  {
51  size_t other_cell = (edges[i]->neighbors.first == static_cast<int>(cell_index)) ? static_cast<size_t>
52  (edges[i]->neighbors.second) : static_cast<size_t> (edges[i]->neighbors.first);
53  res[i] = &cells.at(other_cell);
54  }
55  return res;
56  }
57 
58  void GetEdgeList(Tessellation const& tess,
59  vector<int> const& edge_indices, vector<const Edge*> &res)
60  {
61  res.clear();
62  res.reserve(edge_indices.size());
63  const size_t nloop = edge_indices.size();
64  for (size_t i = 0; i < nloop; ++i)
65  res.push_back(&tess.GetEdge(edge_indices[i]));
66  }
67 
68  void calc_naive_slope(ComputationalCell const& cell,
69  Vector2D const& center, Vector2D const& cell_cm, double cell_volume, vector<ComputationalCell const*> const& neighbors,
70  vector<Vector2D> const& neighbor_centers, vector<Vector2D> const& neigh_cm, vector<const Edge*> const& edge_list,
71  Slope &res,Slope &vec_compare)
72  {
73  size_t n = edge_list.size();
74  if (n > 20)
75  {
76  UniversalError eo("Cell has too many neighbors");
77  eo.AddEntry("Cell x cor", center.x);
78  eo.AddEntry("Cell y cor", center.y);
79  throw eo;
80  }
81  // Create the matrix to invert and the vector to compare
82  vector<double> m(4, 0);
83  for (size_t i = 0; i < edge_list.size(); ++i)
84  {
85  const Vector2D c_ij = CalcCentroid(*edge_list[i]) - 0.5*(neigh_cm[i] + cell_cm);
86  const double e_length = edge_list[i]->GetLength();
87  const Vector2D r_ij = normalize(neighbor_centers[i] - center)*e_length;
88  m[0] -= c_ij.x*r_ij.x;
89  m[1] -= c_ij.y*r_ij.x;
90  m[2] -= c_ij.x*r_ij.y;
91  m[3] -= c_ij.y*r_ij.y;
92  if (i == 0)
93  {
94  ReplaceComputationalCell(vec_compare.xderivative, cell);
95  ReplaceComputationalCell(vec_compare.yderivative, cell);
96  vec_compare.xderivative *= r_ij.x*0.5;
97  vec_compare.yderivative *= r_ij.y*0.5;
98  }
99  else
100  {
101  ComputationalCellAddMult(vec_compare.xderivative, cell, r_ij.x*0.5);
102  ComputationalCellAddMult(vec_compare.yderivative, cell, r_ij.y*0.5);
103  }
104  ComputationalCellAddMult(vec_compare.yderivative, *neighbors[i], r_ij.y*0.5);
105  ComputationalCellAddMult(vec_compare.xderivative, *neighbors[i], r_ij.x*0.5);
106  }
107  m[0] += cell_volume;
108  m[3] += cell_volume;
109  // Find the det
110  const double det = m[0] * m[3] - m[1] * m[2];
111  // Check none singular
112  if (std::abs(det) < 1e-10*cell_volume*cell_volume)
113  {
114  UniversalError eo("Singular matrix");
115  eo.AddEntry("Cell x cor", center.x);
116  eo.AddEntry("Cell y cor", center.y);
117  eo.AddEntry("Cell volume", cell_volume);
118  eo.AddEntry("Det was", det);
119  throw eo;
120  }
121  // Invert the matrix
122  std::array<double,4> m_inv;
123  const double det_inv = 1.0 / det;
124  m_inv[0] = m[3] * det_inv;
125  m_inv[1] = -m[1] * det_inv;
126  m_inv[2] = -m[2] * det_inv;
127  m_inv[3] = m[0] * det_inv;
128  // Calculate the gradient
129  ReplaceComputationalCell(res.xderivative, vec_compare.xderivative);
130  ReplaceComputationalCell(res.yderivative, vec_compare.yderivative);
131  res.xderivative *= m_inv[0];
132  res.yderivative *= m_inv[3];
133  ComputationalCellAddMult(res.xderivative, vec_compare.yderivative, m_inv[1]);
134  ComputationalCellAddMult(res.yderivative, vec_compare.xderivative, m_inv[2]);
135  }
136 
137  double PressureRatio(ComputationalCell cell, vector<ComputationalCell const*> const& neigh)
138  {
139  double res = 1;
140  double p = cell.pressure;
141  for (size_t i = 0; i < neigh.size(); ++i)
142  {
143  if (p > neigh[i]->pressure)
144  res = std::min(res, neigh[i]->pressure / p);
145  else
146  res = std::min(res, p / neigh[i]->pressure);
147  }
148  return res;
149  }
150 
151  bool is_shock(Slope const& naive_slope, double cell_width, double shock_ratio,
152  ComputationalCell const& cell, vector<ComputationalCell const*> const& neighbor_list, double pressure_ratio, double cs)
153  {
154  const bool cond1 = (naive_slope.xderivative.velocity.x + naive_slope.yderivative.velocity.y)*
155  cell_width < (-shock_ratio)*cs;
156  const bool cond2 = PressureRatio(cell, neighbor_list) < pressure_ratio;
157  return cond1 || cond2;
158  }
159 
160  void interp(ComputationalCell& res,ComputationalCell const& cell, Slope const& slope,
161  Vector2D const& target, Vector2D const& cm)
162  {
163  ReplaceComputationalCell(res, cell);
164  ComputationalCellAddMult(res, slope.xderivative, target.x - cm.x);
165  ComputationalCellAddMult(res, slope.yderivative, target.y - cm.y);
166  }
167 
168  void interp2(ComputationalCell &res, Slope const& slope,
169  Vector2D const& target, Vector2D const& cm)
170  {
171  ComputationalCellAddMult(res, slope.xderivative, target.x - cm.x);
172  ComputationalCellAddMult(res, slope.yderivative, target.y - cm.y);
173  }
174 
175  void slope_limit(ComputationalCell const& cell, Vector2D const& cm,
176  vector<ComputationalCell const*> const& neighbors, vector<const Edge*> const& edge_list,
177  Slope &slope,
178  ComputationalCell &cmax,
179  ComputationalCell &cmin,
180  ComputationalCell &maxdiff,
181  ComputationalCell &mindiff,
182  TracerStickerNames const& tracerstickernames,
183  string const& skip_key,
184  Tessellation const& tess, vector<double> &psi, ComputationalCell &centroid_val, ComputationalCell & dphi,bool SR)
185  {
186  double maxv = 0,R=0;
187  if (SR)
188  {
189  maxv = abs(cell.velocity);
190  }
191  ReplaceComputationalCell(cmax, cell);
192  ReplaceComputationalCell(cmin, cell);
193  // Find maximum.minimum neighbor values
194  size_t nloop = neighbors.size();
195  for (size_t i = 0; i < nloop; ++i)
196  {
197  ComputationalCell const& cell_temp = *neighbors[i];
198  if (!skip_key.empty() && safe_retrieve(cell_temp.stickers, tracerstickernames.sticker_names, skip_key))
199  continue;
200  if (tess.GetOriginalIndex(edge_list[i]->neighbors.first) == tess.GetOriginalIndex(edge_list[i]->neighbors.second))
201  continue;
202  cmax.density = std::max(cmax.density, cell_temp.density);
203  cmax.pressure = std::max(cmax.pressure, cell_temp.pressure);
204  cmax.velocity.x = std::max(cmax.velocity.x, cell_temp.velocity.x);
205  cmax.velocity.y = std::max(cmax.velocity.y, cell_temp.velocity.y);
206  cmin.density = std::min(cmin.density, cell_temp.density);
207  cmin.pressure = std::min(cmin.pressure, cell_temp.pressure);
208  cmin.velocity.x = std::min(cmin.velocity.x, cell_temp.velocity.x);
209  cmin.velocity.y = std::min(cmin.velocity.y, cell_temp.velocity.y);
210  if (SR)
211  maxv = std::max(maxv,abs(cell_temp.velocity));
212  for (size_t j = 0; j < cell_temp.tracers.size(); ++j)
213  {
214  cmax.tracers[j] = std::max(cmax.tracers[j], cell_temp.tracers[j]);
215  cmin.tracers[j] = std::min(cmin.tracers[j], cell_temp.tracers[j]);
216  }
217  }
218  ReplaceComputationalCell(maxdiff, cmax);
219  maxdiff -= cell;
220  ReplaceComputationalCell(mindiff, cmin);
221  mindiff -= cell;
222  // limit the slope
223  interp(centroid_val, cell, slope, CalcCentroid(*edge_list[0]), cm);
224  ReplaceComputationalCellDiff(dphi, centroid_val, cell);
225  psi.resize(4 + cell.tracers.size());
226  psi.assign(psi.size(), 1);
227  const size_t nedges = edge_list.size();
228  for (size_t i = 0; i < nedges; ++i)
229  {
230  //if (tess.GetOriginalIndex(edge_list[i]->neighbors.first) == tess.GetOriginalIndex(edge_list[i]->neighbors.second))
231  // continue;
232  if (i > 0)
233  {
234  ReplaceComputationalCell(centroid_val, cell);
235  interp2(centroid_val, slope, CalcCentroid(*edge_list[i]), cm);
236  ReplaceComputationalCell(dphi, centroid_val);
237  dphi -= cell;
238  }
239  if (SR)
240  R = std::max(R, abs(CalcCentroid(*edge_list[i]) - cm));
241  // density
242  if (std::abs(dphi.density) > 0.05*std::max(std::abs(maxdiff.density), std::abs(mindiff.density)) || centroid_val.density > cmax.density || centroid_val.density < cmin.density)
243  {
244  if (dphi.density > 1e-9*cell.density)
245  psi[0] = std::min(psi[0], maxdiff.density / dphi.density);
246  else
247  if (dphi.density<-1e-9*cell.density)
248  psi[0] = std::min(psi[0], mindiff.density / dphi.density);
249  }
250  // pressure
251  if (std::abs(dphi.pressure) > 0.05*std::max(std::abs(maxdiff.pressure), std::abs(mindiff.pressure)) || centroid_val.pressure < cmin.pressure || centroid_val.pressure>cmax.pressure)
252  {
253  if (dphi.pressure > 1e-9*cell.pressure)
254  psi[1] = std::min(psi[1], maxdiff.pressure / dphi.pressure);
255  else
256  if (dphi.pressure<-1e-9*cell.pressure)
257  psi[1] = std::min(psi[1], mindiff.pressure / dphi.pressure);
258  }
259  // xvelocity
260  if (std::abs(dphi.velocity.x) > 0.05*std::max(std::abs(maxdiff.velocity.x), std::abs(mindiff.velocity.x)) || centroid_val.velocity.x<cmin.velocity.x || centroid_val.velocity.x>cmax.velocity.x)
261  {
262  if (dphi.velocity.x > std::abs(1e-9*cell.velocity.x))
263  psi[2] = std::min(psi[2], maxdiff.velocity.x / dphi.velocity.x);
264  else
265  if (dphi.velocity.x<-std::abs(1e-9*cell.velocity.x))
266  psi[2] = std::min(psi[2], mindiff.velocity.x / dphi.velocity.x);
267  }
268  // yvelocity
269  if (std::abs(dphi.velocity.y) > 0.05*std::max(std::abs(maxdiff.velocity.y), std::abs(mindiff.velocity.y)) || centroid_val.velocity.y<cmin.velocity.y || centroid_val.velocity.y>cmax.velocity.y)
270  {
271  if (dphi.velocity.y > std::abs(1e-9*cell.velocity.y))
272  psi[3] = std::min(psi[3], maxdiff.velocity.y / dphi.velocity.y);
273  else
274  if (dphi.velocity.y < -std::abs(1e-9*cell.velocity.y))
275  psi[3] = std::min(psi[3], mindiff.velocity.y / dphi.velocity.y);
276  }
277  // tracers
278  for (size_t j = 0; j < dphi.tracers.size(); ++j)
279  {
280  double cell_tracer = cell.tracers[j];
281  double diff_tracer = maxdiff.tracers[j];
282  if (std::abs(dphi.tracers[j]) > 0.05*std::max(std::abs(diff_tracer), std::abs(mindiff.tracers[j])) || (
283  centroid_val.tracers[j] * cell_tracer < 0))
284  {
285  if (dphi.tracers[j] > std::abs(1e-9*cell_tracer))
286  psi[4 + j] = std::min(psi[4 + j], diff_tracer / dphi.tracers[j]);
287  else
288  if (dphi.tracers[j] < -std::abs(1e-9 * cell_tracer))
289  psi[4 + j] = std::min(psi[4 + j], mindiff.tracers[j] / dphi.tracers[j]);
290  }
291  }
292  }
293  slope.xderivative.density *= psi[0];
294  slope.yderivative.density *= psi[0];
295  slope.xderivative.pressure *= psi[1];
296  slope.yderivative.pressure *= psi[1];
297  slope.xderivative.velocity.x *= psi[2];
298  slope.yderivative.velocity.x *= psi[2];
299  slope.xderivative.velocity.y *= psi[3];
300  slope.yderivative.velocity.y *= psi[3];
301  if (SR)
302  {
303  double vcell = abs(cell.velocity);
304  double maxadd = R * std::sqrt(slope.xderivative.velocity.x*slope.xderivative.velocity.x +
308  if ((vcell + maxadd) > maxv)
309  {
310  double factor = (maxv - vcell) / maxadd;
311  slope.xderivative.velocity.x *= factor;
312  slope.yderivative.velocity.x *= factor;
313  slope.xderivative.velocity.y *= factor;
314  slope.yderivative.velocity.y *= factor;
315  }
316  }
317 
318  size_t counter = 4;
319  size_t N = slope.xderivative.tracers.size();
320  for (size_t k = 0; k < N; ++k)
321  {
322  slope.xderivative.tracers[k] *= psi[counter];
323  slope.yderivative.tracers[k] *= psi[counter];
324  ++counter;
325  }
326 
327  }
328 
329  void shocked_slope_limit(ComputationalCell const& cell, Vector2D const& cm,
330  vector<ComputationalCell const*> const& neighbors, vector<const Edge*> const& edge_list,
331  Slope &slope, double diffusecoeff,TracerStickerNames const& tracerstickernames,
332  string const& skip_key,ComputationalCell &cmax,ComputationalCell &cmin,ComputationalCell &maxdiff,
333  ComputationalCell &mindiff,vector<double> &psi,ComputationalCell &centroid_val,ComputationalCell & dphi, bool SR)
334  {
335  double maxv = 0,R=0;
336  if (SR)
337  maxv = abs(cell.velocity);
338  ReplaceComputationalCell(cmax, cell);
339  ReplaceComputationalCell(cmin, cell);
340  // Find maximum values
341  for (size_t i = 0; i < neighbors.size(); ++i)
342  {
343  ComputationalCell const& cell_temp = *neighbors[i];
344  if (!skip_key.empty() && safe_retrieve(cell_temp.stickers, tracerstickernames.sticker_names, skip_key))
345  continue;
346  cmax.density = std::max(cmax.density, cell_temp.density);
347  cmax.pressure = std::max(cmax.pressure, cell_temp.pressure);
348  cmax.velocity.x = std::max(cmax.velocity.x, cell_temp.velocity.x);
349  cmax.velocity.y = std::max(cmax.velocity.y, cell_temp.velocity.y);
350  cmin.density = std::min(cmin.density, cell_temp.density);
351  cmin.pressure = std::min(cmin.pressure, cell_temp.pressure);
352  cmin.velocity.x = std::min(cmin.velocity.x, cell_temp.velocity.x);
353  cmin.velocity.y = std::min(cmin.velocity.y, cell_temp.velocity.y);
354  if (SR)
355  maxv = std::max(maxv, abs(cell_temp.velocity));
356  for (size_t j = 0; j < cell_temp.tracers.size(); ++j)
357  {
358  cmax.tracers[j] = std::max(cmax.tracers[j], cell_temp.tracers[j]);
359  cmin.tracers[j] = std::min(cmin.tracers[j], cell_temp.tracers[j]);
360  }
361  }
362  ReplaceComputationalCellDiff(maxdiff, cmax, cell);
363  ReplaceComputationalCellDiff(mindiff, cmin, cell);
364  // limit the slope
365  psi.resize(4 + cell.tracers.size());
366  psi.assign(psi.size(), 1);
367  for (size_t i = 0; i<edge_list.size(); ++i)
368  {
369  if (!skip_key.empty() && safe_retrieve(neighbors[i]->stickers, tracerstickernames.sticker_names, skip_key))
370  continue;
371  interp(centroid_val,cell, slope, CalcCentroid(*edge_list[i]), cm);
372  if (SR)
373  R = std::max(R, abs(CalcCentroid(*edge_list[i]) - cm));
374  ReplaceComputationalCellDiff(dphi,centroid_val,cell);
375  // density
376  if (std::abs(dphi.density) > 0.1*std::max(std::abs(maxdiff.density), std::abs(mindiff.density)) || centroid_val.density > cmax.density || centroid_val.density < cmin.density)
377  {
378  if (std::abs(dphi.density) > 1e-9*cell.density)
379  psi[0] = std::min(psi[0], std::max(diffusecoeff*(neighbors[i]->density - cell.density) / dphi.density, 0.0));
380  }
381  // pressure
382  if (std::abs(dphi.pressure) > 0.1*std::max(std::abs(maxdiff.pressure), std::abs(mindiff.pressure)) || centroid_val.pressure < cmin.pressure || centroid_val.pressure>cmax.pressure)
383  {
384  if (std::abs(dphi.pressure) > 1e-9*cell.pressure)
385  psi[1] = std::min(psi[1], std::max(diffusecoeff*(neighbors[i]->pressure - cell.pressure) / dphi.pressure, 0.0));
386  }
387  // xvelocity
388  if (std::abs(dphi.velocity.x) > 0.1*std::max(std::abs(maxdiff.velocity.x), std::abs(mindiff.velocity.x)) || centroid_val.velocity.x<cmin.velocity.x || centroid_val.velocity.x>cmax.velocity.x)
389  {
390  if (std::abs(dphi.velocity.x) > 1e-9*cell.velocity.x)
391  psi[2] = std::min(psi[2], std::max(diffusecoeff*(neighbors[i]->velocity.x - cell.velocity.x) / dphi.velocity.x, 0.0));
392  }
393  // yvelocity
394  if (std::abs(dphi.velocity.y) > 0.1*std::max(std::abs(maxdiff.velocity.y), std::abs(mindiff.velocity.y)) || centroid_val.velocity.y<cmin.velocity.y || centroid_val.velocity.y>cmax.velocity.y)
395  {
396  if (std::abs(dphi.velocity.y) > 1e-9*cell.velocity.y)
397  psi[3] = std::min(psi[3], std::max(diffusecoeff*(neighbors[i]->velocity.y - cell.velocity.y) / dphi.velocity.y, 0.0));
398  }
399  // tracers
400  size_t counter = 0;
401  for (size_t j = 0; j < dphi.tracers.size(); ++j)
402  {
403  double cell_tracer = cell.tracers[j];
404  double diff_tracer = maxdiff.tracers[j];
405  double centroid_tracer = centroid_val.tracers[j];
406  if (std::abs(dphi.tracers[j]) > 0.1*std::max(std::abs(diff_tracer), std::abs(mindiff.tracers[j])) ||
407  centroid_tracer*cell_tracer < 0)
408  {
409  if (std::abs(dphi.tracers[j]) > std::abs(1e-9*cell_tracer))
410  psi[4 + counter] = std::min(psi[4 + counter],
411  std::max(diffusecoeff*(neighbors[i]->tracers[j] - cell_tracer) / dphi.tracers[j], 0.0));
412  }
413  ++counter;
414  }
415  }
416  slope.xderivative.density *= psi[0];
417  slope.yderivative.density *= psi[0];
418  slope.xderivative.pressure *= psi[1];
419  slope.yderivative.pressure *= psi[1];
420  slope.xderivative.velocity.x *= psi[2];
421  slope.yderivative.velocity.x *= psi[2];
422  slope.xderivative.velocity.y *= psi[3];
423  slope.yderivative.velocity.y *= psi[3];
424  if (SR)
425  {
426  double vcell = abs(cell.velocity);
427  double maxadd = R*std::sqrt(slope.xderivative.velocity.x*slope.xderivative.velocity.x +
429  slope.xderivative.velocity.y*slope.xderivative.velocity.y +
431  if ((vcell + maxadd) > maxv)
432  {
433  double factor = (maxv - vcell) / maxadd;
434  slope.xderivative.velocity.x *= factor;
435  slope.yderivative.velocity.x *= factor;
436  slope.xderivative.velocity.y *= factor;
437  slope.yderivative.velocity.y *= factor;
438  }
439  }
440  size_t counter = 0;
441  for (size_t k = 0; k < slope.xderivative.tracers.size(); ++k)
442  {
443  slope.xderivative.tracers[k] *= psi[4 + counter];
444  slope.yderivative.tracers[k] *= psi[4 + counter];
445  ++counter;
446  }
447  }
448 
449  void GetBoundarySlope(ComputationalCell const& cell, Vector2D const& cell_cm,
450  vector<ComputationalCell const*> const& neighbors, vector<Vector2D> const& neigh_cm,
451  Slope &res)
452  {
453  size_t Nneigh = neigh_cm.size();
454  ComputationalCell PhiSy, PhiSx;
455  PhiSy.tracers.resize(cell.tracers.size(), 0);
456  PhiSx.tracers.resize(cell.tracers.size(), 0);
457  double SxSy(0), Sy2(0), Sx2(0);
458  for (size_t i = 0; i < Nneigh; ++i)
459  {
460  PhiSy += (*neighbors[i] - cell)*(neigh_cm[i].y - cell_cm.y);
461  PhiSx += (*neighbors[i] - cell)*(neigh_cm[i].x - cell_cm.x);
462  SxSy += (neigh_cm[i].y - cell_cm.y)*(neigh_cm[i].x - cell_cm.x);
463  Sx2 += (neigh_cm[i].x - cell_cm.x)*(neigh_cm[i].x - cell_cm.x);
464  Sy2 += (neigh_cm[i].y - cell_cm.y)*(neigh_cm[i].y - cell_cm.y);
465  }
466  res.xderivative = (PhiSy*SxSy - PhiSx*Sy2) / (SxSy*SxSy - Sx2*Sy2);
467  res.xderivative.stickers = cell.stickers;
468  res.yderivative = (PhiSx*SxSy - PhiSy*Sx2) / (SxSy*SxSy - Sx2*Sy2);
469  res.yderivative.stickers = cell.stickers;
470  }
471 
472 
473  void calc_slope
474  (Tessellation const& tess,
475  vector<ComputationalCell> const& cells,
476  size_t cell_index,
477  bool slf,
478  double shockratio,
479  double diffusecoeff,
480  double pressure_ratio,
481  EquationOfState const& eos,
482  const vector<string>& calc_tracers,
483  Slope &naive_slope_,
484  Slope & res,
485  Slope & temp1,
486  ComputationalCell &temp2,
487  ComputationalCell &temp3,
488  ComputationalCell &temp4,
489  ComputationalCell &temp5,
490  ComputationalCell &temp6,
491  ComputationalCell &temp7,
492  vector<const Edge *> const& edge_list,
493  vector<Vector2D> &neighbor_mesh_list,
494  vector<Vector2D> &neighbor_cm_list,
495  TracerStickerNames const& tracerstickernames,
496  string const& skip_key,
497  vector<double> &psi,bool SR)
498  {
499  GetNeighborMesh(tess, edge_list, cell_index, neighbor_mesh_list);
500  GetNeighborCM(tess, edge_list, cell_index, neighbor_cm_list);
501  vector<ComputationalCell const*> neighbor_list = GetNeighborCells(edge_list, cell_index, cells);
502 
503  ComputationalCell const& cell = cells[cell_index];
504  bool boundary_slope = false;
505  size_t Nneigh = neighbor_list.size();
506  for (size_t i = 0; i < Nneigh; ++i)
507  if (tess.GetOriginalIndex(edge_list[i]->neighbors.first) == tess.GetOriginalIndex(edge_list[i]->neighbors.second))
508  {
509  boundary_slope = true;
510  break;
511  }
512  if (boundary_slope)
513  GetBoundarySlope(cell, tess.GetCellCM(static_cast<int>(cell_index)),
514  neighbor_list, neighbor_cm_list, res);
515  else
516  calc_naive_slope(cell, tess.GetMeshPoint(static_cast<int>(cell_index)), tess.GetCellCM(static_cast<int>(cell_index)),
517  tess.GetVolume(static_cast<int>(cell_index)), neighbor_list, neighbor_mesh_list, neighbor_cm_list, edge_list,
518  res, temp1);
519 
520  naive_slope_ = res;
521 
522  for (size_t i = 0; i < res.xderivative.tracers.size(); ++i)
523  {
524  if (std::find(calc_tracers.begin(), calc_tracers.end(), tracerstickernames.tracer_names[i]) == calc_tracers.end())
525  {
526  res.xderivative.tracers[i] = 0;
527  res.yderivative.tracers[i] = 0;
528  }
529  }
530 
531  if (slf)
532  {
533  if (!is_shock(res, tess.GetWidth(static_cast<int>(cell_index)), shockratio, cell, neighbor_list, pressure_ratio,
534  eos.dp2c(cell.density, cell.pressure, cell.tracers,tracerstickernames.tracer_names)))
535  {
536  slope_limit(cell, tess.GetCellCM(static_cast<int>(cell_index)), neighbor_list, edge_list, res, temp2, temp3,
537  temp4, temp5,tracerstickernames,skip_key,tess,psi,temp6,temp7,SR);
538  }
539  else
540  {
541  shocked_slope_limit(cell, tess.GetCellCM(static_cast<int>(cell_index)), neighbor_list, edge_list, res, diffusecoeff,tracerstickernames,skip_key,temp2,temp3,temp4,temp5,psi,temp6,temp7, SR);
542  }
543  }
544  }
545 }
546 
548  Vector2D const& target)const
549 {
550  ComputationalCell res;
551  interp(res,cell, rslopes_[cell_index], target, cm);
552  return res;
553 }
554 
556 (EquationOfState const& eos,
557  GhostPointGenerator const& ghost,
558  bool slf,
559  double delta_v,
560  double theta,
561  double delta_P,
562  const vector<string>& calc_tracers,
563  string skip_key,
564  bool SR) :
565  eos_(eos),
566  ghost_(ghost),
567  rslopes_(),
568  naive_rslopes_(),
569  slf_(slf),
570  shockratio_(delta_v),
571  diffusecoeff_(theta),
572  pressure_ratio_(delta_P),
573  calc_tracers_(calc_tracers),
574  skip_key_(skip_key),
575  to_skip_(),
576  SR_(SR){}
577 
578 #ifdef RICH_MPI
579 namespace
580 {
581  void exchange_ghost_slopes(Tessellation const& tess, vector<Slope> & slopes)
582  {
583  MPI_exchange_data(tess, slopes, true);
584  }
585 }
586 #endif//RICH_MPI
587 
589  const vector<ComputationalCell>& cells, double time, vector<pair<ComputationalCell, ComputationalCell> > &res,
590  TracerStickerNames const& tracerstikersnames,CacheData const& /*cd*/) const
591 {
592  const size_t CellNumber = static_cast<size_t>(tess.GetPointNo());
593  vector<int> boundaryedges;
594  // Get ghost points
595  boost::container::flat_map<size_t, ComputationalCell> ghost_cells = ghost_.operator()(tess, cells, time, tracerstikersnames);
596  // Copy ghost data into new cells vector
597  vector<ComputationalCell> new_cells(cells);
598  new_cells.resize (static_cast<size_t>(tess.GetTotalPointNumber()));
599  for (boost::container::flat_map<size_t, ComputationalCell>::const_iterator it = ghost_cells.begin(); it !=
600  ghost_cells.end(); ++it)
601  new_cells[it->first] = it->second;
602  if (SR_)
603  {
604  size_t Nall = new_cells.size();
605  for (size_t j = 0; j < Nall; ++j)
606  {
607  double gamma = 1.0 / std::sqrt(1 - ScalarProd(new_cells[j].velocity, new_cells[j].velocity));
608  new_cells[j].velocity *= gamma;
609  }
610  }
611  // Prepare slopes
612  rslopes_.resize(CellNumber, Slope(cells[0], cells[0]));
613  naive_rslopes_.resize(CellNumber);
614  Slope temp1(cells[0], cells[0]);
615  ComputationalCell temp2(cells[0]);
616  ComputationalCell temp3(cells[0]);
617  ComputationalCell temp4(cells[0]);
618  ComputationalCell temp5(cells[0]);
619  ComputationalCell temp6(cells[0]);
620  ComputationalCell temp7(cells[0]);
621  vector<double> psi;
622  vector<const Edge *> edge_list;
623  vector<Vector2D> neighbor_mesh_list;
624  vector<Vector2D> neighbor_cm_list;
625  for (size_t i = 0; i < CellNumber; ++i)
626  {
627  vector<int> const& edge_index = tess.GetCellEdges(static_cast<int>(i));
628  GetEdgeList(tess, edge_index, edge_list);
629  calc_slope(tess, new_cells, i, slf_, shockratio_, diffusecoeff_, pressure_ratio_, eos_,
630  calc_tracers_, naive_rslopes_[i], rslopes_[i], temp1, temp2, temp3, temp4, temp5,temp6,temp7, edge_list,
631  neighbor_mesh_list, neighbor_cm_list, tracerstikersnames,skip_key_,psi,SR_);
632  const size_t nloop = edge_index.size();
633  for (size_t j = 0; j < nloop; ++j)
634  {
635  Edge const& edge = *edge_list[j];
636  if (edge.neighbors.first == static_cast<int>(i))
637  {
638  ReplaceComputationalCell(res[static_cast<size_t>(edge_index[j])].first,new_cells[i]);
639  interp2(res[static_cast<size_t>(edge_index[j])].first,
640  rslopes_[i], CalcCentroid(edge), tess.GetCellCM(static_cast<int>(i)));
641  if (edge.neighbors.second > static_cast<int>(CellNumber))
642  boundaryedges.push_back(edge_index[j]);
643  }
644  else
645  {
646  ReplaceComputationalCell(res[static_cast<size_t>(edge_index[j])].second,new_cells[i]);
647  interp2(res[static_cast<size_t>(edge_index[j])].second,
648  rslopes_[i], CalcCentroid(edge), tess.GetCellCM(static_cast<int>(i)));
649  if (edge.neighbors.first > static_cast<int>(CellNumber))
650  boundaryedges.push_back(edge_index[j]);
651  }
652  }
653  }
654 #ifdef RICH_MPI
655  // communicate ghost slopes
656  exchange_ghost_slopes(tess, rslopes_);
657 #endif //RICH_MPI
658  // Interpolate the boundary edges
659  for (size_t i = 0; i < boundaryedges.size(); ++i)
660  {
661  Edge const& edge = tess.GetEdge(boundaryedges[i]);
662  if (edge.neighbors.first > static_cast<int>(CellNumber))
663  {
664  res[static_cast<size_t>(boundaryedges[i])].first = new_cells[static_cast<size_t>(edge.neighbors.first)];
665 #ifdef RICH_MPI
666  if (tess.GetOriginalIndex(edge.neighbors.first) > static_cast<int>(CellNumber))
667  interp2(res[static_cast<size_t>(boundaryedges[i])].first,
668  rslopes_[static_cast<size_t>(edge.neighbors.first)], CalcCentroid(edge), tess.GetCellCM(edge.neighbors.first));
669  else
670  interp(res[static_cast<size_t>(boundaryedges[i])].first,res[static_cast<size_t>(boundaryedges[i])].first,
671  ghost_.GetGhostGradient(tess, cells, rslopes_, static_cast<size_t>(
672  edge.neighbors.first), time, edge, tracerstikersnames), CalcCentroid(edge), tess.GetCellCM(edge.neighbors.first));
673 #else
674  interp(res[static_cast<size_t>(boundaryedges[i])].first,res[static_cast<size_t>(boundaryedges[i])].first,
675  ghost_.GetGhostGradient(tess, cells, rslopes_, static_cast<size_t>(
676  edge.neighbors.first), time, edge, tracerstikersnames), CalcCentroid(edge), tess.GetCellCM(edge.neighbors.first));
677 #endif //RICH_MPI
678  }
679  else
680  {
681  res[static_cast<size_t>(boundaryedges[i])].second = new_cells[static_cast<size_t>(edge.neighbors.second)];
682 #ifdef RICH_MPI
683  if (tess.GetOriginalIndex(edge.neighbors.second) > static_cast<int>(CellNumber))
684  interp2(res[static_cast<size_t>(boundaryedges[i])].second,
685  rslopes_[static_cast<size_t>(edge.neighbors.second)], CalcCentroid(edge), tess.GetCellCM(edge.neighbors.second));
686  else
687  interp(res[static_cast<size_t>(boundaryedges[i])].second, res[static_cast<size_t>(boundaryedges[i])].second,
688  ghost_.GetGhostGradient(tess, cells, rslopes_, static_cast<size_t>(
689  edge.neighbors.second), time, edge, tracerstikersnames), CalcCentroid(edge), tess.GetCellCM(edge.neighbors.second));
690 #else
691  interp(res[static_cast<size_t>(boundaryedges[i])].second,res[static_cast<size_t>(boundaryedges[i])].second,
692  ghost_.GetGhostGradient(tess, cells, rslopes_, static_cast<size_t>(
693  edge.neighbors.second), time, edge, tracerstikersnames), CalcCentroid(edge), tess.GetCellCM(edge.neighbors.second));
694 #endif //RICH_MPI
695  }
696  }
697  //In SR convert back to velocities
698  if (SR_)
699  {
700  size_t N = res.size();
701  for (size_t i = 0; i < N; ++i)
702  {
703  double factor = 1.0 / std::sqrt(1 + ScalarProd(res[i].first.velocity, res[i].first.velocity));
704  res[i].first.velocity *= factor;
705  factor = 1.0 / std::sqrt(1 + ScalarProd(res[i].second.velocity, res[i].second.velocity));
706  res[i].second.velocity *= factor;
707  }
708  }
709 }
710 
711 
712 vector<Slope>& LinearGaussImproved::GetSlopes(void)const
713 {
714  return rslopes_;
715 }
716 
718 {
719  return naive_rslopes_;
720 }
721 
vector< Slope > & GetSlopes(void) const
Returns the gradients.
vector< Slope > & GetSlopesUnlimited(void) const
Returns the unsloped limtied gradients.
std::vector< std::string > sticker_names
The names of the stickers.
Abstract class for tessellation.
virtual int GetPointNo(void) const =0
Get Total number of mesh generating points.
virtual Vector2D const & GetCellCM(int index) const =0
Returns Position of Cell&#39;s CM.
virtual int GetOriginalIndex(int point) const
Returns the original index of the duplicated point.
Definition: tessellation.cpp:5
Container for error reports.
ComputationalCell Interp(ComputationalCell const &cell, size_t cell_index, Vector2D const &cm, Vector2D const &target) const
Interpolates a cell.
Interface between two cells.
Definition: Edge.hpp:13
virtual Slope GetGhostGradient(const Tessellation &tess, const vector< ComputationalCell > &cells, const vector< Slope > &gradients, size_t ghost_index, double time, const Edge &edge, TracerStickerNames const &tracerstickernames) const =0
Calculates the gradients for the ghost cells.
virtual Vector2D GetMeshPoint(int index) const =0
Returns Position of mesh generating point.
Class for spatial interpolations.
virtual double dp2c(double d, double p, tvector const &tracers=tvector(), vector< string > const &tracernames=vector< string >()) const =0
Calculates the speed of sound.
double max(vector< double > const &v)
returns the maximal term in a vector
Definition: utils.cpp:52
Abstract class for creating ghost points.
double y
Component in the y direction.
Definition: geometry.hpp:48
tvector tracers
Tracers (can transfer from one cell to another)
virtual Edge const & GetEdge(int index) const =0
Returns edge (interface between cells)
LinearGaussImproved(EquationOfState const &eos, GhostPointGenerator const &ghost, bool slf=true, double delta_v=0.2, double theta=0.5, double delta_P=0.7, const vector< string > &calc_tracers=vector< string >(), string skip_key=string(), bool SR=false)
Class constructor.
double pressure
Pressure.
ComputationalCell xderivative
Slope in the x direction.
double ScalarProd(Vector3D const &v1, Vector3D const &v2)
Scalar product of two vectors.
Definition: Vector3D.cpp:185
Base class for equation of state.
virtual int GetTotalPointNumber(void) const =0
Returns the total number of points (including ghost)
Container for cache data.
Definition: cache_data.hpp:14
virtual double GetWidth(int index) const =0
Returns the effective width of a cell.
std::vector< std::string > tracer_names
The names of the tracers.
vector< T >::const_reference safe_retrieve(vector< T > const &data, vector< S > const &keys, const S &key)
Checks for existence and retrieves entry from flat map.
Definition: utils.hpp:727
svector stickers
Stickers (stick to the same cell)
double min(vector< double > const &v)
Returns the minimal term in a vector.
Definition: utils.cpp:44
virtual double GetVolume(int index) const =0
Returns the volume of a cell.
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
virtual vector< int > const & GetCellEdges(int index) const =0
Returns the indexes of a cell&#39;s edges.
Vector2D velocity
Velocity.
Linear interpolation that guarantees compliance with the equation of state and calcualtes the GG grad...
void operator()(const Tessellation &tess, const vector< ComputationalCell > &cells, double time, vector< pair< ComputationalCell, ComputationalCell > > &res, TracerStickerNames const &tracerstickersnames, CacheData const &cd) const
interpolates values on both sides of each interface
2D Mathematical vector
Definition: geometry.hpp:15
Vector2D CalcCentroid(Edge const &edge)
Calculates the central point of the edge.
double x
Component in the x direction.
Definition: geometry.hpp:45
Computational cell.
ComputationalCell yderivative
Slope in the y direction.