amr.cpp
1 #include "amr.hpp"
2 #include "../../tessellation/VoronoiMesh.hpp"
3 #ifdef RICH_MPI
4 #include "../../mpi/mpi_commands.hpp"
5 #endif
6 //#define debug_amr 1
7 
8 #ifdef debug_amr
9 #include "hdf5_diagnostics.hpp"
10 #endif
11 
13 
15 
17 
19 
20 AMR::~AMR(void) {}
21 
23  double volume, TracerStickerNames const& tracerstickernames) const
24 {
25  Extensive res;
26  const double mass = volume*cell.density;
27  res.mass = mass;
28  size_t N = cell.tracers.size();
29  res.tracers.resize(N);
30  for (size_t i = 0; i < N; ++i)
31  res.tracers[i] = cell.tracers[i] * mass;
32  res.energy = eos.dp2e(cell.density, cell.pressure, cell.tracers,tracerstickernames.tracer_names)*mass +
33  0.5*mass*ScalarProd(cell.velocity, cell.velocity);
34  res.momentum = mass*cell.velocity;
35 
36  return res;
37 }
38 
40  double volume, TracerStickerNames const& tracerstickernames) const
41 {
42  Extensive res;
43  double gamma = 1.0 / std::sqrt(1 - ScalarProd(cell.velocity, cell.velocity));
44  const double mass = volume * cell.density*gamma;
45  res.mass = mass;
46  size_t N = cell.tracers.size();
47  res.tracers.resize(N);
48  for (size_t i = 0; i < N; ++i)
49  res.tracers[i] = cell.tracers[i] * mass;
50  double enthalpy = eos.dp2e(cell.density, cell.pressure, cell.tracers, tracerstickernames.tracer_names);
51  if (fastabs(cell.velocity) < 1e-5)
52  res.energy = (gamma*enthalpy + 0.5*ScalarProd(cell.velocity, cell.velocity))* mass - cell.pressure*volume;
53  else
54  res.energy = (gamma*enthalpy + (gamma - 1))* mass - cell.pressure*volume;
55  res.momentum = mass * cell.velocity *gamma*(enthalpy+1);
56  return res;
57 }
58 
59 SimpleAMRCellUpdater::SimpleAMRCellUpdater(vector<string> toskip) :toskip_(toskip) {}
60 
62  double volume, ComputationalCell const& old_cell,TracerStickerNames const& tracerstickernames) const
63 {
64  for (size_t i = 0; i < toskip_.size(); ++i)
65  if(safe_retrieve(old_cell.stickers, tracerstickernames.sticker_names,toskip_[i]))
66  return old_cell;
68  const double vol_inv = 1.0 / volume;
69  res.density = extensive.mass*vol_inv;
70  res.velocity = extensive.momentum / extensive.mass;
71  size_t N = extensive.tracers.size();
72  res.tracers.resize(N);
73  for (size_t i = 0; i < N;++i)
74  res.tracers[i]=extensive.tracers[i] / extensive.mass;
75  res.stickers = old_cell.stickers;
76  res.pressure = eos.de2p(res.density, extensive.energy / extensive.mass - 0.5*ScalarProd(res.velocity, res.velocity),res.tracers,tracerstickernames.tracer_names);
77  if (!(res.pressure > 0))
78  {
79  UniversalError eo("Negative pressure in AMR cell update");
80  eo.AddEntry("Volume", volume);
81  eo.AddEntry("Cell mass", extensive.mass);
82  eo.AddEntry("Cell x momentum", extensive.momentum.x);
83  eo.AddEntry("Cell y momentum", extensive.momentum.y);
84  eo.AddEntry("Cell energy", extensive.energy);
85  for (size_t i = 0; i < tracerstickernames.tracer_names.size(); ++i)
86  eo.AddEntry(tracerstickernames.tracer_names[i], extensive.tracers[i]);
87  throw;
88  }
89  return res;
90 }
91 
92 SimpleAMRCellUpdaterSR::SimpleAMRCellUpdaterSR(double G,vector<string> toskip) : G_(G),toskip_(toskip) {}
93 
95  double volume, ComputationalCell const& old_cell, TracerStickerNames const& tracerstickernames) const
96 {
97  for (size_t i = 0; i < toskip_.size(); ++i)
98  if (safe_retrieve(old_cell.stickers, tracerstickernames.sticker_names, toskip_[i]))
99  return old_cell;
100 
101  double v = GetVelocity(extensive, G_);
102  volume = 1.0 / volume;
103  ComputationalCell res;
104  if (res.density < 0)
105  throw UniversalError("Negative density in SimpleAMRCellUpdaterSR");
106  res.velocity = (fastabs(extensive.momentum)*1e8 < extensive.mass) ? extensive.momentum / extensive.mass : v * extensive.momentum / abs(extensive.momentum);
107  double gamma_1 = std::sqrt(1 - ScalarProd(res.velocity,res.velocity));
108  res.density = extensive.mass *gamma_1*volume;
109  res.stickers = old_cell.stickers;
110  size_t N = extensive.tracers.size();
111  res.tracers.resize(N);
112  for (size_t i = 0; i < extensive.tracers.size(); ++i)
113  res.tracers[i] = extensive.tracers[i] / extensive.mass;
114  if (fastabs(res.velocity) < 1e-5)
115  res.pressure = (G_ - 1)*((extensive.energy - ScalarProd(extensive.momentum, res.velocity))*volume
116  + (0.5*ScalarProd(res.velocity, res.velocity))*res.density);
117  else
118  res.pressure = (G_ - 1)*(extensive.energy*volume - ScalarProd(extensive.momentum, res.velocity)*volume
119  + (1.0 / gamma_1 - 1)*res.density);
120  return res;
121 }
122 
123 
124 namespace
125 {
126 #ifdef RICH_MPI
127  vector<vector<int> > GetSentIndeces(Tessellation const& tess, vector<size_t> const& ToRemove,vector<vector<size_t> > &
128  RemoveIndex)
129  {
130  RemoveIndex.clear();
131  vector<vector<int> > sentpoints = tess.GetDuplicatedPoints();
132  vector<vector<int> > sort_indeces(sentpoints.size());
133  vector<vector<int> > res(sentpoints.size());
134  RemoveIndex.resize(sentpoints.size());
135  int Nprocs = static_cast<int>(sentpoints.size());
136  // sort vectors for fast search
137  for (int i = 0; i < Nprocs; ++i)
138  {
139  sort_index(sentpoints[i], sort_indeces[i]);
140  sort(sentpoints[i].begin(), sentpoints[i].end());
141  }
142  // search the vectors
143  int Nremove = static_cast<int>(ToRemove.size());
144  for (int i = 0; i < Nremove; ++i)
145  {
146  for (int j = 0; j < Nprocs; ++j)
147  {
148  vector<int>::const_iterator it = std::lower_bound(sentpoints[static_cast<size_t>(j)].begin(), sentpoints[static_cast<size_t>(j)].end(),
149  ToRemove[static_cast<size_t>(i)]);
150  if ((it != sentpoints[static_cast<size_t>(j)].end()) && (*it == static_cast<int>(ToRemove[static_cast<size_t>(i)])))
151  {
152  res[static_cast<size_t>(j)].push_back(sort_indeces[static_cast<size_t>(j)][static_cast<size_t>(it -
153  sentpoints[static_cast<size_t>(j)].begin())]);
154  RemoveIndex[static_cast<size_t>(j)].push_back(static_cast<size_t>(i));
155  }
156  }
157  }
158  return res;
159  }
160 
161  void SendRecvOuterMerits(Tessellation const& tess, vector<vector<int> > &sent_indeces,vector<double> const& merits,
162  vector<vector<size_t> > const& RemoveIndex,vector<vector<int> > &recv_indeces,vector<vector<double> > &recv_mertis)
163  {
164  vector<vector<double> > send_merits(sent_indeces.size());
165  size_t Nproc = send_merits.size();
166  for (size_t i = 0; i < Nproc; ++i)
167  send_merits[i]=VectorValues(merits, RemoveIndex[i]);
168  recv_indeces = MPI_exchange_data(tess.GetDuplicatedProcs(), sent_indeces);
169  recv_mertis = MPI_exchange_data(tess.GetDuplicatedProcs(), send_merits);
170  }
171 
172  vector<size_t> KeepMPINeighbors(Tessellation const& tess, vector<size_t> const& ToRemove,vector<double> const& merits,
173  vector<vector<int> > &recv_indeces,vector<vector<double> > &recv_mertis)
174  {
175  vector<vector<int> > const& Nghost = tess.GetGhostIndeces();
176  size_t Nproc = recv_indeces.size();
177  for (size_t i = 0; i < Nproc; ++i)
178  {
179  recv_indeces[i] = VectorValues(Nghost[i], recv_indeces[i]);
180  vector<size_t> temp = sort_index(recv_indeces[i]);
181  sort(recv_indeces[i].begin(), recv_indeces[i].end());
182  recv_mertis[i] = VectorValues(recv_mertis[i], temp);
183  }
184 
185  int N = tess.GetPointNo();
186  size_t Nremove = ToRemove.size();
187  vector<int> neigh;
188  vector<size_t> RemoveFinal;
189  for (size_t i = 0; i < Nremove; ++i)
190  {
191  bool good = true;
192  tess.GetNeighbors(static_cast<int>(ToRemove[i]), neigh);
193  size_t Nneigh = neigh.size();
194  for (size_t j = 0; j < Nneigh; ++j)
195  {
196  if (neigh[j] >= N)
197  {
198  for (size_t k = 0; k < Nproc; ++k)
199  {
200  vector<int>::const_iterator it = binary_find(recv_indeces[k].begin(), recv_indeces[k].end(),neigh[j]);
201  if (it != recv_indeces[k].end())
202  {
203  if (recv_mertis[k][static_cast<size_t>(it - recv_indeces[k].begin())] > merits[i])
204  {
205  good = false;
206  break;
207  }
208  }
209  }
210  if (!good)
211  break;
212  }
213  }
214  if (good)
215  RemoveFinal.push_back(ToRemove[i]);
216  }
217  return RemoveFinal;
218  }
219 
220  void ExchangeOuterRemoveData(Tessellation const& tess, vector<size_t> const& ToRemove,vector<vector<int> >
221  &to_check,vector<vector<Vector2D> > &chulls_res,vector<Extensive> const& extensives,vector<Extensive> & mpi_extensives,
222  CacheData const& cd)
223  {
224  chulls_res.clear();
225  to_check.clear();
226  mpi_extensives.clear();
227  vector<vector<int> > Nghost = tess.GetGhostIndeces();
228  vector<vector<int> > sort_indeces(Nghost.size());
229  int Nprocs = static_cast<int>(Nghost.size());
230  // sort vectors for fast search
231  for (int i = 0; i < Nprocs; ++i)
232  {
233  sort_index(Nghost[i], sort_indeces[i]);
234  sort(Nghost[i].begin(), Nghost[i].end());
235  }
236  vector<vector<Extensive> > myremove(Nprocs);
237  vector<vector<vector<Vector2D> > > chulls(Nprocs);
238  vector<vector<vector<int> > > remove_neigh(Nprocs);
239  size_t Nremove = ToRemove.size();
240  int Np = tess.GetPointNo();
241  vector<int> neigh;
242  vector<Vector2D> tempV2D;
243  for (size_t i = 0; i < Nremove; ++i)
244  {
245  bool calculated = false;
246  tess.GetNeighbors(static_cast<int>(ToRemove[i]), neigh);
247  size_t Nneigh = neigh.size();
248  for (size_t k = 0; k < static_cast<size_t>(Nprocs); ++k)
249  {
250  vector<int> temp_add;
251  bool should_add=false;
252  for (size_t j = 0; j < Nneigh; ++j)
253  {
254  if (neigh[j] >= Np && tess.GetOriginalIndex(neigh[j]) != static_cast<int>(ToRemove[i]))
255  {
256  vector<int>::const_iterator it = binary_find(Nghost[k].begin(), Nghost[k].end(), neigh[j]);
257  if (it != Nghost[k].end())
258  {
259  should_add=true;
260  if (!calculated)
261  {
262  ConvexHull(tempV2D, tess, static_cast<int>(ToRemove[i]));
263  calculated = true;
264  }
265  temp_add.push_back(sort_indeces[k][static_cast<size_t>(it - Nghost[k].begin())]);
266  }
267  }
268  }
269  if (should_add)
270  {
271  chulls[k].push_back(tempV2D);
272  remove_neigh[k].push_back(temp_add);
273  myremove[k].push_back((1.0/cd.volumes[ToRemove[i]]) * extensives[ToRemove[i]]);
274  }
275  }
276  }
277  // Exchange the data
278  chulls=MPI_exchange_data(tess, chulls, tess.GetMeshPoint(0));
279  remove_neigh=MPI_exchange_data(tess, remove_neigh);
280  vector<vector<Extensive> > mpi_recv_extensives = MPI_exchange_data(tess.GetDuplicatedProcs(), myremove,extensives[0]);
281  mpi_extensives = CombineVectors(mpi_recv_extensives);
282  //convert remove_neigh to indeces of real points via duplciated points
283  vector<vector<int> > duplicated_points = tess.GetDuplicatedPoints();
284  // sort vectors for fast search
285  /*for (int i = 0; i < Nprocs; ++i)
286  {
287  sort_index(duplicated_points[i], sort_indeces[i]);
288  sort(duplicated_points[i].begin(), duplicated_points[i].end());
289  }*/
290  for (size_t i = 0; i < static_cast<size_t>(Nprocs); ++i)
291  {
292  for (size_t j = 0; j < remove_neigh[i].size(); ++j)
293  {
294  for (size_t k = 0; k < remove_neigh[i][j].size(); ++k)
295  {
296  /*vector<int>::const_iterator it = binary_find(duplicated_points[i].begin(), duplicated_points[i].end(), remove_neigh[i][j][k]);
297  if (it != duplicated_points[i].end())
298  {
299  size_t loc = static_cast<size_t>(it - duplicated_points[i].begin());
300  remove_neigh[i][j][k] = duplicated_points[i][sort_indeces[i][loc]];
301  }*/
302  remove_neigh[i][j][k]=duplicated_points[i][remove_neigh[i][j][k]];
303  }
304  }
305  }
306  to_check = CombineVectors(remove_neigh);
307  chulls_res = CombineVectors(chulls);
308  }
309 
310  void DealWithMPINeighbors(Tessellation const& tess, vector<size_t> &ToRemove, vector<double> &merits,
311  vector<vector<int> > &to_check, vector<vector<Vector2D> > &chulls_res,
312  vector<Extensive> const& extensives, vector<Extensive> & mpi_extensives,CacheData const& cd)
313  {
314  vector<vector<size_t> > RemoveIndex;
315  vector<vector<int> > sent_indeces = GetSentIndeces(tess, ToRemove, RemoveIndex);
316  vector<vector<int> > recv_indeces;
317  vector<vector<double> > recv_mertis;
318  SendRecvOuterMerits(tess, sent_indeces, merits, RemoveIndex, recv_indeces, recv_mertis);
319  ToRemove = KeepMPINeighbors(tess, ToRemove, merits, recv_indeces, recv_mertis);
320  ExchangeOuterRemoveData(tess, ToRemove, to_check, chulls_res,extensives, mpi_extensives,cd);
321  }
322 #endif
323 
324  double AreaOverlap(vector<Vector2D> const& poly0, vector<Vector2D> const& poly1,PhysicalGeometry const& pg)
325  {
326  // returns the overlap of p1 with p0
327  using namespace ClipperLib;
328  Paths subj(1), clip(1), solution;
329  double maxi = 0;
330  Vector2D cm0;
331  for (size_t i = 0; i < poly0.size(); ++i)
332  cm0 += poly0[i];
333  cm0 = cm0/static_cast<double>(poly0.size());
334  for (size_t i = 0; i < poly0.size(); ++i)
335  maxi = std::max(maxi, std::max(std::abs(poly0[i].x-cm0.x), std::abs(poly0[i].y-cm0.y)));
336  for (size_t i = 0; i < poly1.size(); ++i)
337  maxi = std::max(maxi, std::max(std::abs(poly1[i].x-cm0.x), std::abs(poly1[i].y-cm0.y)));
338  int maxscale = static_cast<int>(log10(maxi) + 10);
339 
340  subj[0].resize(poly0.size());
341  clip[0].resize(poly1.size());
342  for (size_t i = 0; i < poly0.size(); ++i)
343  subj[0][i] = IntPoint(static_cast<cInt>((poly0[i].x-cm0.x)*pow(10.0, 18 - maxscale)), static_cast<cInt>((poly0[i].y-cm0.y)*pow(10.0, 18 - maxscale)));
344  for (size_t i = 0; i < poly1.size(); ++i)
345  clip[0][i] = IntPoint(static_cast<cInt>((poly1[i].x-cm0.x)*pow(10.0, 18 - maxscale)), static_cast<cInt>((poly1[i].y-cm0.y)*pow(10.0, 18 - maxscale)));
346 
347  //perform intersection ...
348  Clipper c;
349  c.AddPaths(subj, ptSubject, true);
350  c.AddPaths(clip, ptClip, true);
351  c.Execute(ctIntersection, solution, pftNonZero, pftNonZero);
352  if (!solution.empty())
353  {
354  if (solution[0].size() > 2)
355  {
356  vector<Vector2D> inter(solution[0].size());
357  double factor = pow(10.0, maxscale - 18);
358  for (size_t i = 0; i < solution[0].size(); ++i)
359  inter[i].Set(static_cast<double>(solution[0][i].X) * factor + cm0.x, static_cast<double>(solution[0][i].Y) * factor + cm0.y);
360  return pg.calcVolume(inter);
361  }
362  }
363  return 0;
364  }
365 
366  Vector2D FixInDomain(OuterBoundary const& obc, Vector2D &point)
367  {
368  Vector2D res;
369  if (point.x > obc.GetGridBoundary(Right))
370  {
371  point.x -= obc.GetGridBoundary(Right) - obc.GetGridBoundary(Left);
372  res.x += obc.GetGridBoundary(Right) - obc.GetGridBoundary(Left);
373  }
374  if (point.x < obc.GetGridBoundary(Left))
375  {
376  point.x += obc.GetGridBoundary(Right) - obc.GetGridBoundary(Left);
377  res.x -= obc.GetGridBoundary(Right) - obc.GetGridBoundary(Left);
378  }
379  if (point.y > obc.GetGridBoundary(Up))
380  {
381  point.y -= obc.GetGridBoundary(Up) - obc.GetGridBoundary(Down);
382  res.y += obc.GetGridBoundary(Up) - obc.GetGridBoundary(Down);
383  }
384  if (point.y < obc.GetGridBoundary(Down))
385  {
386  point.y += obc.GetGridBoundary(Up) - obc.GetGridBoundary(Down);
387  res.y -= obc.GetGridBoundary(Up) - obc.GetGridBoundary(Down);
388  }
389  return res;
390  }
391 }
392 
393 namespace
394 {
395  double GetAspectRatio(Tessellation const& tess, int index)
396  {
397  vector<int> const& edges = tess.GetCellEdges(index);
398  double L = 0;
399  for (size_t i = 0; i < edges.size(); ++i)
400  L += tess.GetEdge(edges[i]).GetLength();
401  return 4 * 3.14*tess.GetVolume(index) / (L*L);
402  }
403 
404  void RemoveNeighbors(vector<double> &merits, vector<size_t> &candidates, Tessellation const& tess)
405  {
406  vector<size_t> candidates_new;
407  vector<double> merits_new;
408  if (merits.size() != candidates.size())
409  throw UniversalError("Merits and Candidates don't have same size in RemoveNeighbors");
410  // Make sure there are no neighbors
411  vector<size_t> bad_neigh;
412  vector<int> neigh;
413  for (size_t i = 0; i < merits.size(); ++i)
414  {
415  bool good = true;
416  tess.GetNeighbors(static_cast<int>(candidates[i]),neigh);
417  size_t nneigh = neigh.size();
418  if (find(bad_neigh.begin(), bad_neigh.end(), candidates[i]) !=
419  bad_neigh.end())
420  good = false;
421  else
422  {
423  for (size_t j = 0; j < nneigh; ++j)
424  {
425  if (binary_search(candidates.begin(), candidates.end(), tess.GetOriginalIndex(neigh[j])))
426  {
427  if (merits[i] < merits[static_cast<size_t>(lower_bound(candidates.begin(), candidates.end(),
428  tess.GetOriginalIndex(neigh[j])) - candidates.begin())])
429  {
430  good = false;
431  break;
432  }
433  if (fabs(merits[i] - merits[static_cast<size_t>(lower_bound(candidates.begin(), candidates.end(),
434  tess.GetOriginalIndex(neigh[j])) - candidates.begin())]) < 1e-9)
435  {
436  if (find(bad_neigh.begin(), bad_neigh.end(), tess.GetOriginalIndex(neigh[j])) == bad_neigh.end())
437  bad_neigh.push_back(static_cast<size_t>(tess.GetOriginalIndex(neigh[j])));
438  }
439  }
440  }
441  }
442  if (good)
443  {
444  candidates_new.push_back(candidates[i]);
445  merits_new.push_back(merits[i]);
446  }
447  }
448  candidates = candidates_new;
449  merits = merits_new;
450  }
451 
452  Extensive GetNewExtensive(vector<Extensive> const& extensives,Tessellation const& tess,size_t N,size_t location,
453  vector<Vector2D> const& moved,vector<int> const& real_neigh,vector<vector<Vector2D> > const& Chull,
454  vector<ComputationalCell> const& cells,EquationOfState const& eos, AMRExtensiveUpdater const& eu,
455  double &TotalVolume,Tessellation const& oldtess,bool periodic,TracerStickerNames const& tracerstickernames,PhysicalGeometry const& pg,
456  CacheData const& cd)
457  {
458  Extensive NewExtensive(extensives[0].tracers);
459  vector<Vector2D> temp;
460  ConvexHull(temp, tess, static_cast<int>(N + location));
461  temp = temp + moved[location];
462  const double vv = cd.volumes[N + location];
463  stack<int> tocheck;
464  stack<vector<Vector2D> > tocheck_hull;
465  vector<int> checked(real_neigh);
466  vector<int> neightemp;
467  for (size_t j = 0; j < Chull.size(); ++j)
468  {
469  double v = AreaOverlap(temp, Chull[j],pg);
470  if (v > vv*1e-8)
471  {
472  NewExtensive += eu.ConvertPrimitveToExtensive(cells[static_cast<size_t>(real_neigh[j])], eos, v,tracerstickernames);
473  TotalVolume += v;
474 #ifdef RICH_MPI
475  if (oldtess.GetOriginalIndex(real_neigh[j]) > tess.GetPointNo() || oldtess.GetOriginalIndex(real_neigh[j])==real_neigh[j])
476  continue;
477 #endif
478  oldtess.GetNeighbors(real_neigh[j],neightemp);
479  for (size_t k = 0; k < neightemp.size(); ++k)
480  {
481 #ifdef RICH_MPI
482  if (oldtess.GetOriginalIndex(neightemp[k]) > tess.GetPointNo() || oldtess.GetOriginalIndex(neightemp[k]) == neightemp[k])
483  continue;
484 #endif
485  if (std::find(checked.begin(), checked.end(), oldtess.GetOriginalIndex(neightemp[k])) == checked.end())
486  {
487  vector<Vector2D> temp2;
488  ConvexHull(temp2, oldtess, oldtess.GetOriginalIndex(neightemp[k]));
489  tocheck.push(oldtess.GetOriginalIndex(neightemp[k]));
490  tocheck_hull.push(temp2);
491  checked.push_back(oldtess.GetOriginalIndex(neightemp[k]));
492  }
493  }
494  }
495  }
496  while (!tocheck.empty())
497  {
498  vector<Vector2D> chull = tocheck_hull.top();
499  int cur_check=tocheck.top();
500  tocheck.pop();
501  tocheck_hull.pop();
502  double v = AreaOverlap(temp, chull,pg);
503  if (v > vv*1e-8)
504  {
505  NewExtensive += eu.ConvertPrimitveToExtensive(cells[static_cast<size_t>(cur_check)], eos, v,tracerstickernames);
506  TotalVolume += v;
507  oldtess.GetNeighbors(cur_check,neightemp);
508  for (size_t k = 0; k < neightemp.size(); ++k)
509  {
510 #ifdef RICH_MPI
511  if (oldtess.GetOriginalIndex(neightemp[k]) > tess.GetPointNo())
512  continue;
513 #endif
514  if (std::find(checked.begin(), checked.end(), oldtess.GetOriginalIndex(neightemp[k])) == checked.end())
515  {
516  vector<Vector2D> temp2;
517  ConvexHull(temp2, oldtess, oldtess.GetOriginalIndex(neightemp[k]));
518  tocheck.push(oldtess.GetOriginalIndex(neightemp[k]));
519  tocheck_hull.push(temp2);
520  checked.push_back(oldtess.GetOriginalIndex(neightemp[k]));
521  }
522  }
523  }
524  }
525  const double eps = periodic ? 1e-2 : 1e-5;
526  if (vv > (1 + eps)*TotalVolume || vv < (1 - eps)*TotalVolume)
527  {
528  std::cout << "In refine Real volume: " << vv << " AMR volume: " << TotalVolume << std::endl;
529 #ifndef RICH_MPI
530  UniversalError eo("Not same volume in amr refine");
531  eo.AddEntry("location",static_cast<double>(location));
532  throw eo;
533 #endif
534  }
535  return NewExtensive;
536  }
537 
538  void GetToCheck(Tessellation const& tess, int ToRefine, vector<int> &real_neigh, vector<vector<Vector2D> > &Chull)
539  {
540  vector<int> neigh = tess.GetNeighbors(ToRefine);
541  vector<Vector2D> temp;
542  ConvexHull(temp, tess, static_cast<int>(ToRefine));
543  Chull.push_back(temp);
544  real_neigh.push_back(static_cast<int>(ToRefine));
545  size_t N = static_cast<size_t>(tess.GetPointNo());
546  vector<Vector2D> moved;
547  moved.push_back(Vector2D(0, 0));
548  for (size_t j = 0; j < neigh.size(); ++j)
549  {
550  if (neigh[j] < static_cast<int>(N))
551  {
552  real_neigh.push_back(neigh[j]);
553  ConvexHull(temp, tess, neigh[j]);
554  Chull.push_back(temp);
555  moved.push_back(Vector2D(0, 0));
556  }
557  else
558  {
559 #ifndef RICH_MPI
560  // Is it not a rigid wall?
561  if (tess.GetOriginalIndex(neigh[j]) != static_cast<int>(ToRefine))
562  {
563  real_neigh.push_back(tess.GetOriginalIndex(neigh[j]));
564  ConvexHull(temp, tess, real_neigh.back());
565  temp = temp + (tess.GetMeshPoint(neigh[j]) -
566  tess.GetMeshPoint(tess.GetOriginalIndex(neigh[j])));
567  Chull.push_back(temp);
568  moved.push_back((tess.GetMeshPoint(neigh[j]) - tess.GetMeshPoint(tess.GetOriginalIndex(neigh[j]))));
569  }
570 #endif
571  }
572  }
573  // Get neighbor neighbors
574  const size_t NN = real_neigh.size();
575  vector<int> neigh_temp;
576  for (size_t j = 0; j < NN; ++j)
577  {
578  tess.GetNeighbors(real_neigh[j],neigh_temp);
579  for (size_t i = 0; i < neigh_temp.size(); ++i)
580  {
581  if (std::find(real_neigh.begin(), real_neigh.end(), tess.GetOriginalIndex(neigh_temp[i])) == real_neigh.end())
582  {
583  if (neigh_temp[i] < static_cast<int>(N))
584  {
585  real_neigh.push_back(neigh_temp[i]);
586  ConvexHull(temp, tess, neigh_temp[i]);
587  Chull.push_back(temp+moved[j]);
588  }
589  else
590  {
591 #ifndef RICH_MPI
592  // Is it not a rigid wall?
593  if (tess.GetOriginalIndex(neigh_temp[i]) != static_cast<int>(real_neigh[j]))
594  {
595  real_neigh.push_back(tess.GetOriginalIndex(neigh_temp[i]));
596  ConvexHull(temp, tess, real_neigh.back());
597  temp = temp + (tess.GetMeshPoint(neigh_temp[i]) -
598  tess.GetMeshPoint(tess.GetOriginalIndex(neigh_temp[i]))) + moved[j];
599  Chull.push_back(temp);
600  }
601 #endif
602  }
603  }
604  }
605  }
606  }
607 
608  void AddCurrentNeigh(Tessellation const& tess,
609  size_t location, vector<vector<Vector2D> > &Chull, vector<int> &real_neigh,vector<Vector2D> const& Moved,
610  Tessellation const& oldtess)
611  {
612  int oldpointnumber = oldtess.GetPointNo();
613  int newindex = static_cast<int>(location) + oldpointnumber;
614  vector<int> neigh = tess.GetNeighbors(newindex);
615  vector<int> neighcopy(real_neigh);
616  sort(neighcopy.begin(), neighcopy.end());
617  vector<Vector2D> temp;
618  for (size_t i = 0; i < neigh.size(); ++i)
619  {
620  // Is it a new point? Should deal with mpi as well
621  if (tess.GetOriginalIndex(neigh[i]) >= oldpointnumber)
622  continue;
623  // Rigid wall?
624  if (tess.GetOriginalIndex(neigh[i]) == newindex)
625  continue;
626  // Do we already have this point?
627  if (binary_search(neighcopy.begin(), neighcopy.end(), tess.GetOriginalIndex(neigh[i])))
628  continue;
629  real_neigh.push_back(tess.GetOriginalIndex(neigh[i]));
630  ConvexHull(temp, oldtess, real_neigh.back());
631  // Periodic?
632  if (neigh[i] > tess.GetPointNo())
633  temp = temp + (tess.GetMeshPoint(neigh[i]) -
634  tess.GetMeshPoint(tess.GetOriginalIndex(neigh[i])))+Moved[location];
635  Chull.push_back(temp);
636  }
637  }
638 
639  void ConservedSingleCell(Tessellation const& oldtess, Tessellation const& tess, size_t ToRefine, size_t &location,
640  LinearGaussImproved *interp, EquationOfState const& eos, vector<ComputationalCell> &cells,
641  vector<pair<size_t, Vector2D> > const& NewPoints, vector<Extensive> const& extensives,
642  AMRExtensiveUpdater const& eu, AMRCellUpdater const& cu,vector<Vector2D> const& moved,bool periodic,
643  TracerStickerNames const& tracerstickernames,PhysicalGeometry const& pg,CacheData const& cd)
644  {
645  vector<int> real_neigh;
646  vector<vector<Vector2D> > Chull;
647  GetToCheck(oldtess, static_cast<int>(ToRefine),real_neigh,Chull);
648  size_t N = static_cast<size_t>(oldtess.GetPointNo());
649  while (location < NewPoints.size() && NewPoints[location].first == ToRefine)
650  {
651  AddCurrentNeigh(tess,location, Chull, real_neigh, moved, oldtess);
652  double TotalVolume=0;
653  Extensive NewExtensive = GetNewExtensive(extensives, tess, N, location, moved, real_neigh, Chull,
654  cells, eos, eu,TotalVolume,oldtess,periodic,tracerstickernames,pg,cd);
655  try
656  {
657  cells.push_back(cu.ConvertExtensiveToPrimitve(NewExtensive, eos, TotalVolume, cells[ToRefine], tracerstickernames));
658  }
659  catch (UniversalError & eo)
660  {
661  eo.AddEntry("ToRefine", static_cast<double>(ToRefine));
662  throw;
663  }
664  if (interp != 0)
665  interp->GetSlopesUnlimited().push_back(interp->GetSlopesUnlimited()[ToRefine]);
666  ++location;
667  }
668 
669  }
670 
671 }
672 
673 
674 void AMR::GetNewPoints2(vector<size_t> const& ToRefine, Tessellation const& tess,
675  vector<std::pair<size_t, Vector2D> > &NewPoints, vector<Vector2D> &Moved,
676  OuterBoundary const& obc)const
677 {
678  const double small = 1e-3;
679  NewPoints.clear();
680  NewPoints.reserve(ToRefine.size());
681  Moved.clear();
682  Moved.reserve(ToRefine.size());
683  vector<int> neigh;
684  for (size_t i = 0; i < ToRefine.size(); ++i)
685  {
686  // Split only if cell is rather round
687  const double R = tess.GetWidth(static_cast<int>(ToRefine[i]));
688  Vector2D const& myCM = tess.GetCellCM(static_cast<int>(ToRefine[i]));
689  Vector2D const& mypoint = tess.GetMeshPoint(static_cast<int>(ToRefine[i]));
690  if (GetAspectRatio(tess, static_cast<int>(ToRefine[i])) < 0.65)
691  continue;
692  if (myCM.distance(mypoint) > 0.2*R)
693  continue;
694  tess.GetNeighbors(static_cast<int>(ToRefine[i]),neigh);
695  double otherdist = mypoint.distance(tess.GetMeshPoint(neigh[0]));
696  size_t max_ind = 0;
697  for (size_t j = 1; j < neigh.size(); ++j)
698  {
699  Vector2D const& otherpoint = tess.GetMeshPoint(neigh[j]);
700  if (otherpoint.distance(mypoint) > otherdist)
701  {
702  max_ind = j;
703  otherdist = otherpoint.distance(mypoint);
704  }
705  }
706  Vector2D direction = tess.GetMeshPoint(neigh[max_ind]) - mypoint;
707  Vector2D candidate = mypoint+small*direction/abs(direction);
708  Moved.push_back(FixInDomain(obc, candidate));
709  NewPoints.push_back(std::pair<size_t, Vector2D>(ToRefine[i], candidate));
710  }
711 }
712 
713 
714 void AMR::GetNewPoints(vector<size_t> const& ToRefine, Tessellation const& tess,
715  vector<std::pair<size_t, Vector2D> > &NewPoints, vector<Vector2D> &Moved,
716  OuterBoundary const& obc
717 #ifdef RICH_MPI
718  , vector<Vector2D> const& proc_chull
719 #endif
720  )const
721 {
722  // ToRefine should be sorted
723  size_t N = static_cast<size_t>(tess.GetPointNo());
724  NewPoints.clear();
725  NewPoints.reserve(ToRefine.size() * 7);
726  Moved.clear();
727  Moved.reserve(ToRefine.size() * 7);
728  vector<int> neigh;
729  for (size_t i = 0; i < ToRefine.size(); ++i)
730  {
731  // Split only if cell is rather round
732  const double R = tess.GetWidth(static_cast<int>(ToRefine[i]));
733  Vector2D const& mypoint = tess.GetCellCM(static_cast<int>(ToRefine[i]));
734  if (GetAspectRatio(tess, static_cast<int>(ToRefine[i])) < 0.3)
735  continue;
736 
737  tess.GetNeighbors(static_cast<int>(ToRefine[i]),neigh);
738  vector<int> const& edges = tess.GetCellEdges(static_cast<int>(ToRefine[i]));
739  for (size_t j = 0; j < neigh.size(); ++j)
740  {
741  Vector2D const& otherpoint = tess.GetCellCM(neigh[j]);
742  if (otherpoint.distance(mypoint) < 1.25*R)
743  continue;
744  if (tess.GetEdge(edges[j]).GetLength() < 0.3*R)
745  continue;
746  Vector2D candidate = 0.75*mypoint + 0.25*otherpoint;
747  if (candidate.distance(tess.GetMeshPoint(static_cast<int>(ToRefine[i]))) < 0.3*R)
748  continue;
749  if (neigh[j] < static_cast<int>(N) && candidate.distance(tess.GetMeshPoint(neigh[j])) < tess.GetWidth(neigh[j])*0.3)
750  continue;
751  // Make sure not to split neighboring cells, this causes bad aspect ratio
752  if (std::binary_search(ToRefine.begin(), ToRefine.end(), static_cast<size_t>(neigh[j])))
753  {
754  if (static_cast<size_t>(neigh[j]) > ToRefine[i])
755  {
756  candidate = 0.5*mypoint + 0.5*otherpoint;
757  if (candidate.distance(tess.GetMeshPoint(static_cast<int>(ToRefine[i]))) < 0.3*R ||
758  (neigh[j] < static_cast<int>(N) && candidate.distance(tess.GetMeshPoint(neigh[j])) < tess.GetWidth(neigh[j])*0.3))
759  {
760  candidate = 0.5*tess.GetMeshPoint(static_cast<int>(ToRefine[i])) + 0.5*tess.GetMeshPoint(neigh[j]);
761  if (candidate.distance(tess.GetMeshPoint(static_cast<int>(ToRefine[i]))) < 0.3*R ||
762  (neigh[j] < static_cast<int>(N) && candidate.distance(tess.GetMeshPoint(neigh[j])) < tess.GetWidth(neigh[j])*0.3))
763  continue;
764  }
765  }
766  else
767  continue;
768  }
769 #ifdef RICH_MPI
770  if (!PointInCell(proc_chull, candidate))
771  continue;
772 #endif
773  Moved.push_back(FixInDomain(obc, candidate));
774  NewPoints.push_back(std::pair<size_t, Vector2D>(ToRefine[i], candidate));
775  }
776  }
777 }
778 
779 ConservativeAMR::ConservativeAMR
780 (CellsToRefine const& refine,
781  CellsToRemove const& remove,
782  bool periodic,
783  LinearGaussImproved *slopes,
784  AMRCellUpdater* cu,
785  AMRExtensiveUpdater* eu) :
786  refine_(refine),
787  remove_(remove),
788  scu_(vector<string>()),
789  seu_(),
790  periodic_(periodic),
791  cu_(cu),
792  eu_(eu),
793  interp_(slopes)
794 {
795  if (!cu)
796  cu_ = &scu_;
797  if(!eu)
798  eu_ = &seu_;
799 }
800 
803  OuterBoundary const& obc,
804  vector<ComputationalCell> &cells,
805  EquationOfState const& eos,
806  vector<Extensive> &extensives,
807  double time,
808 #ifdef RICH_MPI
809  Tessellation const& proctess,
810 #endif
811  TracerStickerNames const& tracerstickernames,
812  CacheData const& cd,
813  PhysicalGeometry const& pg)const
814 {
815  size_t N = static_cast<size_t>(tess.GetPointNo());
816  // Find the primitive of each point and the new location
817  vector<std::pair<size_t, Vector2D> > NewPoints;
818  vector<Vector2D> Moved;
819  vector<size_t> ToRefine = refine_.ToRefine(tess, cells, time,tracerstickernames);
820 #ifndef RICH_MPI
821  if (ToRefine.empty())
822  return;
823 #endif // RICH_MPI
824  sort(ToRefine.begin(), ToRefine.end());
825  ToRefine=unique(ToRefine);
826 #ifdef RICH_MPI
827  vector<double> merit;
828  ToRefine = RemoveNearBoundaryPoints(ToRefine, tess,merit);
829  vector<Vector2D> chull;
830  int rank;
831  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
832  ConvexHull(chull, proctess, rank);
833 #endif
834  GetNewPoints(ToRefine, tess, NewPoints, Moved, obc
835 #ifdef RICH_MPI
836  , chull
837 #endif
838  );
839  // save copy of old tessellation
840  boost::scoped_ptr<Tessellation> oldtess(tess.clone());
841 
842  // Rebuild tessellation
843  vector<Vector2D> cor = tess.GetMeshPoints();
844  cor.resize(N);
845  cells.resize(N);
846 
847  for (size_t i = 0; i < NewPoints.size(); ++i)
848  cor.push_back(NewPoints[i].second);
849 #ifdef debug_amr
850  WriteTess(tess, "c:/vold.h5");
851 #endif
852 
853 #ifdef RICH_MPI
854  tess.Update(cor, proctess);
855 #else
856  tess.Update(cor);
857 #endif
858  cd.reset();
859 #ifdef debug_amr
860  WriteTess(tess, "c:/vnew.h5");
861 #endif
862 
863 
864  size_t location = 0;
865  for (size_t i = 0; i < ToRefine.size(); ++i)
866  ConservedSingleCell(*oldtess, tess, ToRefine[i], location, interp_, eos, cells, NewPoints, extensives, *eu_,
867  *cu_,Moved,periodic_,tracerstickernames,pg,cd);
868  extensives.resize(N + NewPoints.size());
869  for (size_t i = 0; i < N + NewPoints.size(); ++i)
870  extensives[i] = eu_->ConvertPrimitveToExtensive(cells[i], eos, cd.volumes[i],tracerstickernames);
871 #ifdef RICH_MPI
872  MPI_exchange_data(tess, cells, true);
873 #endif
874 }
875 
877  OuterBoundary const& /*obc*/, vector<ComputationalCell> &cells, vector<Extensive> &extensives,
878  EquationOfState const& eos, double time,
879 #ifdef RICH_MPI
880  Tessellation const& proctess,
881 #endif
882  TracerStickerNames const& tracerstickernames,
883  CacheData const& cd,
884  PhysicalGeometry const& pg)const
885 {
886  size_t N = static_cast<size_t>(tess.GetPointNo());
887  // Rebuild tessellation
888  vector<Vector2D> cor = tess.GetMeshPoints();
889  cor.resize(N);
890  cells.resize(N);
891  std::pair<vector<size_t>, vector<double> > ToRemovepair = remove_.ToRemove(tess, cells, time,tracerstickernames);
892 #ifndef RICH_MPI
893  if (ToRemovepair.first.empty())
894  return;
895 #endif // RICH_MPI
896 
897  // Clean up vectors
898  vector<int> indeces;
899  sort_index(ToRemovepair.first,indeces);
900  sort(ToRemovepair.first.begin(), ToRemovepair.first.end());
901  ToRemovepair.second = VectorValues(ToRemovepair.second, indeces);
902  indeces = unique_index(ToRemovepair.first);
903  ToRemovepair.first = unique(ToRemovepair.first);
904  ToRemovepair.second = VectorValues(ToRemovepair.second, indeces);
905  RemoveNeighbors(ToRemovepair.second, ToRemovepair.first, tess);
906 #ifdef RICH_MPI
907  vector<vector<int> > mpi_check;
908  vector<vector<Vector2D> > chulls_mpi;
909  vector<Extensive> mpi_extensives;
910  DealWithMPINeighbors(tess, ToRemovepair.first, ToRemovepair.second, mpi_check, chulls_mpi,extensives, mpi_extensives,cd);
911 #endif
912 
913  // save copy of old tessellation
914  boost::scoped_ptr<Tessellation> oldtess(tess.clone());
915  vector<double> old_vol(ToRemovepair.first.size());
916  for (size_t i = 0; i < ToRemovepair.first.size(); ++i)
917  old_vol[i] = cd.volumes[ToRemovepair.first[i]];
918  RemoveVector(cor, ToRemovepair.first);
919 
920 #ifdef debug_amr
921  WriteTess(tess, "c:/vold.h5");
922 #endif
923 
924 #ifdef RICH_MPI
925  tess.Update(cor, proctess);
926 #else
927  tess.Update(cor);
928 #endif
929  cd.reset();
930 #ifdef debug_amr
931  WriteTess(tess, "c:/vnew.h5");
932 #endif
933 
934  // Fix the extensives
935  vector<Vector2D> temp;
936  vector<Vector2D> chull;
937  for (size_t i = 0; i < ToRemovepair.first.size(); ++i)
938  {
939  vector<int> neigh = oldtess->GetNeighbors(static_cast<int>(ToRemovepair.first[i]));
940  ConvexHull(chull, *oldtess, static_cast<int>(ToRemovepair.first[i]));
941  const double TotalV = old_vol[i];
942  temp.clear();
943  double dv = 0;
944  for (size_t j = 0; j < neigh.size(); ++j)
945  {
946  size_t toadd = static_cast<size_t>(lower_bound(ToRemovepair.first.begin(), ToRemovepair.first.end(),
947  oldtess->GetOriginalIndex(neigh[j])) - ToRemovepair.first.begin());
948  temp.clear();
949  if (neigh[j] < static_cast<int>(N))
950  {
951  ConvexHull(temp, tess, static_cast<int>(static_cast<size_t>(neigh[j]) - toadd));
952  }
953  else
954  {
955  if (oldtess->GetOriginalIndex(neigh[j]) != static_cast<int>(ToRemovepair.first[i]))
956  {
957 #ifdef RICH_MPI
958  continue;
959 #endif
960  ConvexHull(temp, tess, static_cast<int>(static_cast<size_t>(
961  oldtess->GetOriginalIndex(neigh[j]) )- toadd));
962  temp = temp + (oldtess->GetMeshPoint(neigh[j]) -
963  oldtess->GetMeshPoint(oldtess->GetOriginalIndex(neigh[j])));
964  }
965  }
966  if (!temp.empty())
967  {
968  const double v = AreaOverlap(chull, temp,pg);
969  dv += v;
970  extensives[static_cast<size_t>(oldtess->GetOriginalIndex(neigh[j]))] += (v / TotalV)*extensives[ToRemovepair.first[i]];
971  }
972  }
973  /*if (dv > (1 + 1e-5)*TotalV || dv < (1 - 1e-5)*TotalV)
974  {
975  std::cout << "Real volume: " << TotalV << " AMR volume: " << dv << std::endl;
976  throw UniversalError("Not same volume in amr remove");
977  }*/
978  }
979 #ifdef RICH_MPI
980  for (size_t i = 0; i < mpi_check.size(); ++i)
981  {
982  for (size_t j = 0; j < mpi_check[i].size(); ++j)
983  {
984  size_t toadd = static_cast<size_t>(lower_bound(ToRemovepair.first.begin(), ToRemovepair.first.end(),
985  oldtess->GetOriginalIndex(mpi_check[i][j])) - ToRemovepair.first.begin());
986  ConvexHull(chull, tess, mpi_check[i][j]-static_cast<int>(toadd));
987  const double v = AreaOverlap(chull, chulls_mpi[i], pg);
988  extensives[static_cast<size_t>(mpi_check[i][j])] += v*mpi_extensives[i];
989  }
990  }
991 #endif
992 
993  RemoveVector(extensives, ToRemovepair.first);
994  RemoveVector(cells, ToRemovepair.first);
995 
996  N = static_cast<size_t>(tess.GetPointNo());
997  cells.resize(static_cast<size_t>(tess.GetPointNo()));
998  for (size_t i = 0; i < N; ++i)
999  cells[i] = cu_->ConvertExtensiveToPrimitve(extensives[i], eos,cd.volumes[i], cells[i],tracerstickernames);
1000 #ifdef RICH_MPI
1001  MPI_exchange_data(tess, cells, true);
1002 #endif
1003 }
1004 
1006 {
1007  UpdateCellsRefine(sim.getTessellation(), sim.getOuterBoundary(), sim.getAllCells(), sim.getEos(),
1008  sim.getAllExtensives(), sim.getTime(),
1009 #ifdef RICH_MPI
1010  sim.GetProcTessellation(),
1011 #endif
1013  UpdateCellsRemove(sim.getTessellation(), sim.getOuterBoundary(), sim.getAllCells(), sim.getAllExtensives(),
1014  sim.getEos(), sim.getTime(),
1015 #ifdef RICH_MPI
1016  sim.GetProcTessellation(),
1017 #endif
1019  // redo cache data
1020  sim.getCacheData().reset();
1021 }
1022 
1023 
1024 
1025 NonConservativeAMR::NonConservativeAMR
1026 (CellsToRefine const& refine,
1027  CellsToRemove const& remove,
1028  LinearGaussImproved *slopes,
1029  AMRExtensiveUpdater* eu) :
1030  refine_(refine), remove_(remove), scu_(vector<string>()),
1031  seu_(),interp_(slopes),
1032  eu_(eu)
1033 {
1034  if (!eu)
1035  eu_ = &seu_;
1036 }
1037 
1039  OuterBoundary const& obc, vector<ComputationalCell> &cells, EquationOfState const& eos,
1040  vector<Extensive> &extensives, double time,
1041 #ifdef RICH_MPI
1042  Tessellation const& proctess,
1043 #endif
1044  TracerStickerNames const& tracerstickernames,
1045  CacheData const& cd,
1046  PhysicalGeometry const& /*pg*/)const
1047 {
1048  vector<size_t> ToRefine = refine_.ToRefine(tess, cells, time,tracerstickernames);
1049 #ifndef RICH_MPI
1050  if (ToRefine.empty())
1051  return;
1052 #endif // RICH_MPI
1053  sort(ToRefine.begin(), ToRefine.end());
1054  vector<std::pair<size_t, Vector2D> > NewPoints;
1055  vector<Vector2D> Moved;
1056 #ifdef RICH_MPI
1057  vector<Vector2D> chull;
1058  int rank;
1059  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1060  ConvexHull(chull, proctess,rank);
1061 #endif
1062  GetNewPoints(ToRefine, tess, NewPoints, Moved, obc
1063 #ifdef RICH_MPI
1064  , chull
1065 #endif
1066  );
1067  size_t N = static_cast<size_t>(tess.GetPointNo());
1068  vector<Vector2D> cor = tess.GetMeshPoints();
1069  cor.resize(N);
1070  cells.resize(N);
1071  extensives.resize(N + NewPoints.size());
1072 
1073  for (size_t i = 0; i < NewPoints.size(); ++i)
1074  {
1075  cor.push_back(NewPoints[i].second);
1076  cells.push_back(cells[NewPoints[i].first]);
1077  if (interp_ != 0)
1078  interp_->GetSlopesUnlimited().push_back(interp_->GetSlopesUnlimited()[NewPoints[i].first]);
1079  }
1080  // Rebuild tessellation
1081 #ifdef RICH_MPI
1082  tess.Update(cor, proctess);
1083 #else
1084  tess.Update(cor);
1085 #endif
1086  cd.reset();
1087  // Recalcualte extensives
1088  for (size_t i = 0; i < N + NewPoints.size(); ++i)
1089  extensives[i] = eu_->ConvertPrimitveToExtensive(cells[i], eos, cd.volumes[i],tracerstickernames);
1090 #ifdef RICH_MPI
1091  MPI_exchange_data(tess, cells, true);
1092 #endif
1093 }
1094 
1096  OuterBoundary const& /*obc*/, vector<ComputationalCell> &cells, vector<Extensive> &extensives,
1097  EquationOfState const& eos, double time,
1098 #ifdef RICH_MPI
1099  Tessellation const& proctess,
1100 #endif
1101  TracerStickerNames const& tracerstickernames,
1102  CacheData const& cd,
1103  PhysicalGeometry const& /*pg*/)const
1104 {
1105  std::pair<vector<size_t>, vector<double> > ToRemovepair = remove_.ToRemove(tess, cells, time,tracerstickernames);
1106  vector<size_t> ToRemove = ToRemovepair.first;
1107 #ifndef RICH_MPI
1108  if (ToRemove.empty())
1109  return;
1110 #endif // RICH_MPI
1111  size_t N = static_cast<size_t>(tess.GetPointNo());
1112  // Rebuild tessellation
1113  vector<Vector2D> cor = tess.GetMeshPoints();
1114  cor.resize(N);
1115  cells.resize(N);
1116 
1117  RemoveVector(cor, ToRemove);
1118  RemoveVector(cells, ToRemove);
1119 
1120 #ifdef RICH_MPI
1121  tess.Update(cor, proctess);
1122 #else
1123  tess.Update(cor);
1124 #endif
1125  cd.reset();
1126  // Recalcualte extensives
1127  extensives.resize(cells.size());
1128  for (size_t i = 0; i < extensives.size(); ++i)
1129  extensives[i] = eu_->ConvertPrimitveToExtensive(cells[i], eos, cd.volumes[i],tracerstickernames);
1130 #ifdef RICH_MPI
1131  MPI_exchange_data(tess, cells, true);
1132 #endif
1133 }
1134 
1136 {
1137  UpdateCellsRefine(sim.getTessellation(), sim.getOuterBoundary(), sim.getAllCells(), sim.getEos(),
1138  sim.getAllExtensives(), sim.getTime(),
1139 #ifdef RICH_MPI
1140  sim.GetProcTessellation(),
1141 #endif
1143  UpdateCellsRemove(sim.getTessellation(), sim.getOuterBoundary(), sim.getAllCells(), sim.getAllExtensives(),
1144  sim.getEos(), sim.getTime(),
1145 #ifdef RICH_MPI
1146  sim.GetProcTessellation(),
1147 #endif
1149  // redo cache data
1150  sim.getCacheData().reset();
1151 }
1152 
1153 #ifdef RICH_MPI
1154 vector<size_t> AMR::RemoveNearBoundaryPoints(vector<size_t> const&ToRemove,
1155  Tessellation const& tess, vector<double> &merits)const
1156 {
1157  vector<size_t> res;
1158  int N = tess.GetPointNo();
1159  vector<double> merittemp;
1160  for (size_t i = 0; i < ToRemove.size(); ++i)
1161  {
1162  bool good = true;
1163  vector<int> neigh = tess.GetNeighbors(static_cast<int>(ToRemove[i]));
1164  for (size_t j = 0; j < neigh.size(); ++j)
1165  {
1166  if (tess.GetOriginalIndex(neigh[j]) >= N)
1167  {
1168  good = false;
1169  break;
1170  }
1171  else
1172  {
1173  if (tess.GetOriginalIndex(neigh[j]) == static_cast<int>(ToRemove[i]))
1174  continue;
1175  vector<int> neigh2 = tess.GetNeighbors(neigh[j]);
1176  for (size_t k = 0; k < neigh2.size(); ++k)
1177  {
1178  if (tess.GetOriginalIndex(neigh2[k]) == neigh[j])
1179  continue;
1180  else
1181  {
1182  if (tess.GetOriginalIndex(neigh2[k]) >= N)
1183  {
1184  good = false;
1185  break;
1186  }
1187  }
1188  }
1189  }
1190  }
1191  if (good)
1192  {
1193  res.push_back(ToRemove[i]);
1194  if(!merits.empty())
1195  merittemp.push_back(merits.at(i));
1196  }
1197  }
1198  merits = merittemp;
1199  return res;
1200 }
1201 #endif
void operator()(hdsim &sim)
Runs the AMR.
Definition: amr.cpp:1005
Extensive variables.
Definition: extensive.hpp:18
vector< T > unique(vector< T > const &v)
Returns a vector containing only unique elements.
Definition: utils.hpp:376
const Tessellation & GetProcTessellation(void) const
Returns the processor tessellation.
Definition: hdsim2d.cpp:819
ComputationalCell ConvertExtensiveToPrimitve(const Extensive &extensive, const EquationOfState &eos, double volume, ComputationalCell const &old_cell, TracerStickerNames const &tracerstickernames) const
Calculates the computational cell.
Definition: amr.cpp:94
double distance(Vector2D const &v1) const
Caluclates the distance from the Vector to v1.
Definition: geometry.cpp:13
vector< T > VectorValues(vector< T > const &v, vector< int > const &index)
Returns only the values with indeces in index.
Definition: utils.hpp:326
void operator()(hdsim &sim)
Runs the AMR.
Definition: amr.cpp:1135
virtual ~AMRCellUpdater(void)
Class destructor.
Definition: amr.cpp:12
virtual vector< int > GetDuplicatedProcs(void) const =0
Returns the indeces of the processors with whom ghost points where exchanged.
virtual vector< int > Update(const vector< Vector2D > &points, bool HilbertOrder=false)=0
Update the tessellation.
void reset(void) const
Marks all items for recalculation.
Definition: cache_data.cpp:65
void sort_index(const vector< T > &arr, vector< int > &res)
Returns the indeces of a sort.
Definition: utils.hpp:500
vector< Slope > & GetSlopesUnlimited(void) const
Returns the unsloped limtied gradients.
std::vector< std::string > sticker_names
The names of the stickers.
void RemoveVector(vector< T > &v, vector< int > &indeces)
Removes the elements in v given by indeces.
Definition: utils.hpp:275
Abstract class for tessellation.
vector< vector< T > > CombineVectors(vector< vector< vector< T > > > const &data)
Reduces the dimension of the input vector.
Definition: utils.hpp:770
Abstract class for extensive update scheme in amr.
Definition: amr.hpp:42
virtual ~CellsToRefine(void)
Virtual destructor.
Definition: amr.cpp:18
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
virtual double de2p(double d, double e, tvector const &tracers=tvector(), vector< string > const &tracernames=vector< string >()) const =0
Calculates the pressure.
Vector2D momentum
momentum, in relativity it is = rho*h*gamma*v
Definition: extensive.hpp:31
Container for error reports.
bool PointInCell(vector< Vector2D > const &cpoints, Vector2D const &vec)
Checks if a point is inside a Voronoi cell.
Newtonian hydrodynamic simulation.
Definition: hdsim2d.hpp:43
Extensive ConvertPrimitveToExtensive(const ComputationalCell &cell, const EquationOfState &eos, double volume, TracerStickerNames const &tracerstickernames) const
Calculates the computational cell.
Definition: amr.cpp:39
virtual double calcVolume(const vector< Edge > &edge_list) const =0
Calculates the physical volume of a cell.
double getTime(void) const
Returns the time.
Definition: hdsim2d.cpp:729
double mass
rest mass times gamma
Definition: extensive.hpp:25
virtual Vector2D GetMeshPoint(int index) const =0
Returns Position of mesh generating point.
double max(vector< double > const &v)
returns the maximal term in a vector
Definition: utils.cpp:52
double energy
energy, in relativity it is = rho*h*gamma^2-P-rho
Definition: extensive.hpp:28
const Tessellation & getTessellation(void) const
Returns the tessellation.
Definition: hdsim2d.cpp:722
double y
Component in the y direction.
Definition: geometry.hpp:48
Abstract class for amr.
tvector tracers
Tracers (can transfer from one cell to another)
virtual Edge const & GetEdge(int index) const =0
Returns edge (interface between cells)
virtual ~AMRExtensiveUpdater(void)
Class destructor.
Definition: amr.cpp:14
double GetVelocity(Extensive const &cell, double G)
Calculates velocity from extensive in SR.
TracerStickerNames const & GetTracerStickerNames(void) const
Returns the TracerStickerNames.
Definition: hdsim2d.cpp:172
void GetNewPoints2(vector< size_t > const &ToRefine, Tessellation const &tess, vector< std::pair< size_t, Vector2D > > &NewPoints, vector< Vector2D > &Moved, OuterBoundary const &obc) const
Calculates the positions of the new points like AREPO.
Definition: amr.cpp:674
ComputationalCell ConvertExtensiveToPrimitve(const Extensive &extensive, const EquationOfState &eos, double volume, ComputationalCell const &old_cell, TracerStickerNames const &tracerstickernames) const
Calculates the computational cell.
Definition: amr.cpp:61
double pressure
Pressure.
const PhysicalGeometry & getPhysicalGeometry(void) const
Access to physical geometry.
Definition: hdsim2d.cpp:712
tvector tracers
tracers
Definition: extensive.hpp:34
SimpleAMRCellUpdater(vector< string > toskip)
class constructor
Definition: amr.cpp:59
const CacheData & getCacheData(void) const
Returns reference to the cached data.
Definition: hdsim2d.cpp:813
virtual vector< Vector2D > & GetMeshPoints(void)=0
Returns a reference to the point vector.
void ConvexHull(vector< Vector2D > &result, Tessellation const &tess, int index)
Returns the ConvexHull for a set of points.
Definition: ConvexHull.cpp:31
void GetNewPoints(vector< size_t > const &ToRefine, Tessellation const &tess, vector< std::pair< size_t, Vector2D > > &NewPoints, vector< Vector2D > &Moved, OuterBoundary const &obc, vector< Vector2D > const &proc_chull) const
Calculates the positions of the new points.
Definition: amr.cpp:714
double ScalarProd(Vector3D const &v1, Vector3D const &v2)
Scalar product of two vectors.
Definition: Vector3D.cpp:185
vector< size_t > RemoveNearBoundaryPoints(vector< size_t > const &ToRemove, Tessellation const &tess, vector< double > &merits) const
Removes points because they are near the edge of a cpu domain.
Definition: amr.cpp:1154
virtual Extensive ConvertPrimitveToExtensive(const ComputationalCell &cell, const EquationOfState &eos, double volume, TracerStickerNames const &tracerstickernames) const =0
Calculates the computational cell.
Linear gauss interpolation.
virtual ~CellsToRemove(void)
Virtual destructor.
Definition: amr.cpp:16
Base class for equation of state.
void UpdateCellsRefine(Tessellation &tess, OuterBoundary const &obc, vector< ComputationalCell > &cells, EquationOfState const &eos, vector< Extensive > &extensives, double time, Tessellation const &proctess, TracerStickerNames const &tracerstickernames, CacheData const &cd, PhysicalGeometry const &pg) const
Runs the refine.
Definition: amr.cpp:802
const CachedLazyList< double > volumes
List of cell volumes.
Definition: cache_data.hpp:81
Container for cache data.
Definition: cache_data.hpp:14
virtual double GetWidth(int index) const =0
Returns the effective width of a cell.
Simulation output to hdf5 file format.
std::vector< std::string > tracer_names
The names of the tracers.
const EquationOfState & getEos(void) const
Access to the equation of state.
Definition: hdsim2d.cpp:787
Abstract class for cell update scheme in amr.
Definition: amr.hpp:22
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
void UpdateCellsRemove(Tessellation &tess, OuterBoundary const &obc, vector< ComputationalCell > &cells, vector< Extensive > &extensives, EquationOfState const &eos, double time, Tessellation const &proctess, TracerStickerNames const &tracerstickernames, CacheData const &cd, PhysicalGeometry const &pg) const
Runs the removal.
Definition: amr.cpp:1095
Extensive ConvertPrimitveToExtensive(const ComputationalCell &cell, const EquationOfState &eos, double volume, TracerStickerNames const &tracerstickernames) const
Calculates the computational cell.
Definition: amr.cpp:22
svector stickers
Stickers (stick to the same cell)
virtual double GetVolume(int index) const =0
Returns the volume of a cell.
SimpleAMRCellUpdaterSR(double G, vector< string > toskip)
class constructor
Definition: amr.cpp:92
virtual ComputationalCell ConvertExtensiveToPrimitve(const Extensive &extensive, const EquationOfState &eos, double volume, ComputationalCell const &old_cell, TracerStickerNames const &tracerstickernames) const =0
Calculates the computational cell.
Chooses which cells should be remove.
Definition: amr.hpp:111
Class for keeping the names of the tracers and stickers.
vector< int > unique_index(vector< T > const &v)
Returns a vector containing only indeces of unique elements.
Definition: utils.hpp:397
Chooses which cells should be refined.
Definition: amr.hpp:131
virtual Tessellation * clone(void) const =0
Cloning function.
virtual double dp2e(double d, double p, tvector const &tracers=tvector(), vector< string > const &tracernames=vector< string >()) const =0
Calculates the thermal energy per unit mass.
void WriteTess(Tessellation const &tess, string const &filename)
Writes the tessellation data into an HDF5 file.
virtual ~AMR(void)
Virtual destructor.
Definition: amr.cpp:20
virtual vector< vector< int > > & GetDuplicatedPoints(void)=0
Returns the indeces of the points that where sent to other processors as ghost points.
void UpdateCellsRemove(Tessellation &tess, OuterBoundary const &obc, vector< ComputationalCell > &cells, vector< Extensive > &extensives, EquationOfState const &eos, double time, Tessellation const &proctess, TracerStickerNames const &tracerstickernames, CacheData const &cd, PhysicalGeometry const &pg) const
Runs the removal.
Definition: amr.cpp:876
double abs(Vector3D const &v)
Norm of a vector.
Definition: Vector3D.cpp:44
void UpdateCellsRefine(Tessellation &tess, OuterBoundary const &obc, vector< ComputationalCell > &cells, EquationOfState const &eos, vector< Extensive > &extensives, double time, Tessellation const &proctess, TracerStickerNames const &tracerstickernames, CacheData const &cd, PhysicalGeometry const &pg) const
Runs the refine.
Definition: amr.cpp:1038
void AddEntry(std::string const &field, double value)
Adds an entry to the list.
virtual vector< int > const & GetCellEdges(int index) const =0
Returns the indexes of a cell&#39;s edges.
Vector2D velocity
Velocity.
Abstract class for geometric boundary conditions for the tessellation.
const vector< ComputationalCell > & getAllCells(void) const
Returns a list of all computational cells.
Definition: hdsim2d.cpp:739
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
virtual vector< vector< int > > & GetGhostIndeces(void)=0
Returns the indeces of each ghost point in the vector of points that the tessellation holds...
2D Mathematical vector
Definition: geometry.hpp:15
double GetLength(void) const
Returns the length of the edge.
Definition: Edge.cpp:26
virtual vector< int > GetNeighbors(int index) const =0
Returns the indeces of the neighbors.
virtual double GetGridBoundary(Directions dir) const =0
Returns the boundary coordinate.
Base class for physical geometry.
double fastabs(Vector2D const &v)
Norm of a vector, less accurate.
Definition: geometry.cpp:24
double x
Component in the x direction.
Definition: geometry.hpp:45
const OuterBoundary & getOuterBoundary(void) const
Access to the geometric outer boundary.
Definition: hdsim2d.cpp:792
Computational cell.
const vector< Extensive > & getAllExtensives(void) const
Returns a list of extensive variables.
Definition: hdsim2d.cpp:797