hdsim2d.cpp
1 #include <cmath>
2 #include <algorithm>
3 #include "hdsim2d.hpp"
4 #include "hydrodynamics_2d.hpp"
5 #include "AreaFix.hpp"
6 #ifdef RICH_MPI
7 #include "../../mpi/mpi_commands.hpp"
8 #endif //RICH_MPI
9 #include <iostream>
10 #include "hdf5_diagnostics.hpp"
11 
12 using namespace std;
13 
14 namespace
15 {
16  class CellEdgesGetter : public LazyList<Edge>
17  {
18  public:
19 
20  CellEdgesGetter(const Tessellation& tess, int n) :
21  tess_(tess), edge_indices_(tess.GetCellEdges(n)) {}
22 
23  size_t size(void) const
24  {
25  return edge_indices_.size();
26  }
27 
28  Edge operator[](size_t i) const
29  {
30  return tess_.GetEdge(edge_indices_[i]);
31  }
32 
33  private:
34  const Tessellation& tess_;
35  const vector<int> edge_indices_;
36  };
37 }
38 
39 namespace
40 {
41  vector<Extensive> init_extensives(const Tessellation& tess,
42  const PhysicalGeometry& pg,
43  const vector<ComputationalCell>& cells,
44  const EquationOfState& eos,
45  TracerStickerNames const& tracernames,
46  bool relativistic)
47  {
48  size_t Nloop = static_cast<size_t>(tess.GetPointNo());
49  vector<Extensive> res(Nloop);
50  if (!relativistic)
51  {
52  for (size_t i = 0; i < Nloop; ++i)
53  {
54  const ComputationalCell& cell = cells[i];
55  const double volume =
56  pg.calcVolume
57  (serial_generate(CellEdgesGetter(tess, static_cast<int>(i))));
58  const double mass = volume * cell.density;
59  res[i].mass = mass;
60  res[i].energy = eos.dp2e(cell.density, cell.pressure, cell.tracers, tracernames.tracer_names)*mass +
61  0.5*mass*ScalarProd(cell.velocity, cell.velocity);
62  res[i].momentum = mass * cell.velocity;
63  size_t N = cell.tracers.size();
64  res[i].tracers.resize(N);
65  for (size_t j = 0; j < N; ++j)
66  res[i].tracers[j] = cell.tracers[j] * mass;
67  }
68  }
69  else
70  {
71  for (size_t i = 0; i < Nloop; ++i)
72  {
73  const ComputationalCell& cell = cells[i];
74  const double volume =
75  pg.calcVolume
76  (serial_generate(CellEdgesGetter(tess, static_cast<int>(i))));
77  double gamma = 1 / std::sqrt(1 - ScalarProd(cell.velocity, cell.velocity));
78  const double mass = volume * cell.density * gamma;
79  res[i].mass = mass;
80  const double enthalpy = eos.dp2e(cell.density, cell.pressure, cell.tracers, tracernames.tracer_names);
81  if (fastabs(cell.velocity) < 1e-5)
82  res[i].energy = (gamma*enthalpy + 0.5*ScalarProd(cell.velocity, cell.velocity))* mass - cell.pressure*volume;
83  else
84  res[i].energy = (gamma*enthalpy + (gamma - 1))* mass - cell.pressure*volume;
85  res[i].momentum = mass * (enthalpy+1)*gamma*cell.velocity;
86  size_t N = cell.tracers.size();
87  res[i].tracers.resize(N);
88  for (size_t j = 0; j < N; ++j)
89  res[i].tracers[j] = cell.tracers[j] * mass;
90  }
91  }
92  return res;
93  }
94 }
95 
96 hdsim::hdsim
97 (
98 #ifdef RICH_MPI
99  Tessellation& proctess,
100 #endif
101  Tessellation& tess,
102  const OuterBoundary& obc,
103  const PhysicalGeometry& pg,
104  const vector<ComputationalCell>& cells,
105  const EquationOfState& eos,
106  const PointMotion& point_motion,
107  const EdgeVelocityCalculator& evc,
108  const SourceTerm& source,
109  const TimeStepFunction& tsf,
110  const FluxCalculator& fc,
111  const ExtensiveUpdater& eu,
112  const CellUpdater& cu,
113  TracerStickerNames tracer_sticker_names,
114  bool relativistic
115 #ifdef RICH_MPI
116  ,const ProcessorUpdate* proc_update
117 #endif
118  ) :
119 #ifdef RICH_MPI
120  proctess_(proctess),
121 #endif
122  tess_(tess),
123  obc_(obc),
124  eos_(eos),
125  cells_(cells),
126  extensives_
127  (init_extensives
128  (tess,
129  pg,
130  cells,
131  eos,
132  tracer_sticker_names,relativistic)),
133  point_motion_(point_motion),
134  edge_velocity_calculator_(evc),
135  source_(source),
136  time_(0),
137  cycle_(0),
138  pg_(pg),
139  tsf_(tsf),
140  fc_(fc),
141  eu_(eu),
142  cu_(cu),
143  tracer_sticker_names_(tracer_sticker_names),
144  cache_data_(tess, pg)
145 #ifdef RICH_MPI
146  , proc_update_(proc_update)
147 #endif
148 {
149  // sort tracers and stickers
150  size_t N = cells_.size();
151  vector<size_t> tindex = sort_index(tracer_sticker_names_.tracer_names);
152  vector<size_t> sindex = sort_index(tracer_sticker_names_.sticker_names);
153  tracer_sticker_names_.tracer_names = VectorValues(tracer_sticker_names_.tracer_names, tindex);
154  tracer_sticker_names_.sticker_names = VectorValues(tracer_sticker_names_.sticker_names, sindex);
155  for (size_t i = 0; i < N; ++i)
156  {
157  for (size_t j = 0; j < tindex.size(); ++j)
158  {
159  cells_[i].tracers[j] = cells[i].tracers[tindex[j]];
160  extensives_[i].tracers[j] = cells_[i].tracers[j] * extensives_[i].mass;
161  }
162  for (size_t j = 0; j < sindex.size(); ++j)
163  cells_[i].stickers[j] = cells[i].stickers[sindex[j]];
164  }
165 #ifdef RICH_MPI
166  MPI_exchange_data(tess_, cells_, true);
167 #endif
168 }
169 
171 
173 {
174  return tracer_sticker_names_;
175 }
176 
178 {
179  vector<Vector2D> point_velocities =
180  point_motion_(tess_, cells_, time_,tracer_sticker_names_);
181 
182 #ifdef RICH_MPI
183  MPI_exchange_data(tess_, point_velocities, true);
184 #endif
185 
186  vector<Vector2D> edge_velocities =
187  edge_velocity_calculator_(tess_, point_velocities);
188 
189  const double dt = tsf_(tess_,
190  cells_,
191  eos_,
192  edge_velocities,
193  time_,tracer_sticker_names_);
194 
195  point_velocities = point_motion_.ApplyFix(tess_, cells_, time_, dt, point_velocities,tracer_sticker_names_);
196 #ifdef RICH_MPI
197  MPI_exchange_data(tess_, point_velocities, true);
198 #endif
199 
200  edge_velocities =
201  edge_velocity_calculator_(tess_, point_velocities);
202 
203  const vector<Extensive> fluxes =
204  fc_
205  (tess_,
206  edge_velocities,
207  cells_,
208  extensives_,
209  cache_data_,
210  eos_,
211  time_,
212  dt,tracer_sticker_names_);
213 
214 
215  // update_extensives(fluxes,
216  eu_(fluxes,
217  pg_,
218  tess_,
219  dt,
220  cache_data_,
221  cells_,
222  extensives_,
223  time_,tracer_sticker_names_);
224 
226  pg_,
227  cache_data_,
228  cells_,
229  fluxes,
230  point_velocities,
231  source_,
232  time_,
233  dt,
234  extensives_,tracer_sticker_names_);
235 
236 #ifdef RICH_MPI
237  if (proc_update_ != 0)
238  proc_update_->Update(proctess_, tess_);
239  vector<int> HilbertIndeces = MoveMeshPoints(point_velocities, dt, tess_, proctess_, cycle_ % 10 == 0);
240  if (cycle_ % 10 == 0)
241  {
242  extensives_ = VectorValues(extensives_, HilbertIndeces);
243  cells_ = VectorValues(cells_, HilbertIndeces);
244  point_velocities = VectorValues(point_velocities, HilbertIndeces);
245  }
246  // Keep relevant points
247  MPI_exchange_data(tess_, extensives_, false);
248  MPI_exchange_data(tess_, cells_, false);
249 #else
250  vector<int> HilbertIndeces = MoveMeshPoints(point_velocities, dt, tess_, cycle_ % 25 == 0);
251  if (cycle_ % 25 == 0)
252  {
253  extensives_ = VectorValues(extensives_, HilbertIndeces);
254  cells_ = VectorValues(cells_, HilbertIndeces);
255  point_velocities = VectorValues(point_velocities, HilbertIndeces);
256  }
257 
258 #endif
259  cache_data_.reset();
260 
261  cells_ = cu_(tess_, pg_, eos_, extensives_, cells_,cache_data_,tracer_sticker_names_, time_);
262 
263 #ifdef RICH_MPI
264  MPI_exchange_data(tess_, cells_, true);
265 #endif
266 
267  time_ += dt;
268  cycle_++;
269 }
270 
272 {
273  vector<Vector2D> point_velocities =
274  point_motion_(tess_, cells_, time_,tracer_sticker_names_);
275 
276  vector<Vector2D> edge_velocities =
277  edge_velocity_calculator_(tess_, point_velocities);
278 
279  const double dt = tsf_(tess_,
280  cells_,
281  eos_,
282  edge_velocities,
283  time_,tracer_sticker_names_);
284 
285  point_velocities = point_motion_.ApplyFix(tess_, cells_, time_, dt, point_velocities,tracer_sticker_names_);
286 
287  edge_velocities =
288  edge_velocity_calculator_(tess_, point_velocities);
289 
290  const vector<Extensive> fluxes =
291  fc_
292  (tess_,
293  edge_velocities,
294  cells_,
295  extensives_,
296  cache_data_,
297  eos_,
298  time_,
299  dt,tracer_sticker_names_);
300 
301 
302  // update_extensives(fluxes,
303  eu_(fluxes,
304  pg_,
305  tess_,
306  dt,
307  cache_data_,
308  cells_,
309  extensives_, time_,tracer_sticker_names_);
310 
312  pg_,
313  cache_data_,
314  cells_,
315  fluxes,
316  point_velocities,
317  source_,
318  time_,
319  dt,
320  extensives_,tracer_sticker_names_);
321 
322  boost::scoped_ptr<Tessellation> oldtess(tess_.clone());
323 
324  MoveMeshPoints(point_velocities, dt, tess_, false);
325 
326  extensives_ = extensives_ + FluxFix2(*oldtess, *oldtess, tess_, point_velocities, dt, cells_, fluxes, edge_velocities, obc_, eos_);
327 
328  cache_data_.reset();
329 
330  cells_ = cu_(tess_, pg_, eos_, extensives_, cells_,cache_data_,tracer_sticker_names_, time_);
331 
332  time_ += dt;
333  cycle_++;
334 }
335 
336 
337 namespace
338 {
339  vector<Extensive> average_extensive
340  (const vector<Extensive>& extensives_1,
341  const vector<Extensive>& extensives_2)
342  {
343  assert(extensives_1.size() == extensives_2.size());
344  vector<Extensive> res(extensives_1.size());
345  for (size_t i = 0; i < extensives_1.size(); ++i)
346  res[i] = 0.5*(extensives_1[i] + extensives_2[i]);
347  return res;
348  }
349 }
350 
352 {
353 #ifdef RICH_DEBUG_PRINT
354  int rank = 0;
355  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
356  MPI_Barrier(MPI_COMM_WORLD);
357  if (rank == 0)
358  std::cout << "Here 0" << std::endl;
359 #endif
360  vector<Vector2D> point_velocities = point_motion_(tess_, cells_, time_,tracer_sticker_names_);
361 
362 #ifdef RICH_MPI
363  MPI_exchange_data(tess_, point_velocities, true);
364 #endif
365 
366  vector<Vector2D> edge_velocities =
367  edge_velocity_calculator_(tess_, point_velocities);
368 #ifdef RICH_DEBUG_PRINT
369  MPI_Barrier(MPI_COMM_WORLD);
370  if (rank == 0)
371  std::cout << "Here 1" << std::endl;
372 #endif
373 
374  double dt = tsf_(tess_, cells_, eos_, edge_velocities, time_,tracer_sticker_names_);
375 
376 #ifdef RICH_DEBUG_PRINT
377  MPI_Barrier(MPI_COMM_WORLD);
378  if (rank == 0)
379  std::cout << "Here 2" << std::endl;
380 #endif
381 
382  point_velocities = point_motion_.ApplyFix(tess_, cells_, time_, dt, point_velocities,tracer_sticker_names_);
383 
384 #ifdef RICH_MPI
385  MPI_exchange_data(tess_, point_velocities, true);
386 #endif
387  edge_velocities =
388  edge_velocity_calculator_(tess_, point_velocities);
389 
390  dt = tsf_(tess_, cells_, eos_, edge_velocities, time_, tracer_sticker_names_);
391 #ifdef RICH_DEBUG_PRINT
392  MPI_Barrier(MPI_COMM_WORLD);
393  if (rank == 0)
394  std::cout << "Here 3" << std::endl;
395 #endif
396 
397  const vector<Extensive> mid_fluxes =
398  fc_
399  (tess_,
400  edge_velocities,
401  cells_,
402  extensives_,
403  cache_data_,
404  eos_,
405  time_,
406  dt,tracer_sticker_names_);
407 #ifdef RICH_DEBUG_PRINT
408  MPI_Barrier(MPI_COMM_WORLD);
409  if (rank == 0)
410  std::cout << "Here 4" << std::endl;
411 #endif
412 
413  vector<Extensive> mid_extensives = extensives_;
414 
416  (tess_,
417  pg_,
418  cache_data_,
419  cells_,
420  mid_fluxes,
421  point_velocities,
422  source_,
423  time_,
424  dt,
425  mid_extensives,tracer_sticker_names_);
426 #ifdef RICH_DEBUG_PRINT
427  MPI_Barrier(MPI_COMM_WORLD);
428  if (rank == 0)
429  std::cout << "Here 5" << std::endl;
430 #endif
431 
432  eu_(mid_fluxes, pg_, tess_, dt, cache_data_, cells_, mid_extensives, time_,tracer_sticker_names_);
433 
434 #ifdef RICH_DEBUG_PRINT
435  MPI_Barrier(MPI_COMM_WORLD);
436  if (rank == 0)
437  std::cout << "Here 6" << std::endl;
438 #endif
439 
440 #ifdef RICH_MPI
441  if (proc_update_ != 0)
442  proc_update_->Update(proctess_, tess_);
443  vector<int> HilbertIndeces = MoveMeshPoints(point_velocities, dt, tess_, proctess_, cycle_ % 10 == 0);
444  if (cycle_ % 10 == 0)
445  {
446  mid_extensives = VectorValues(mid_extensives, HilbertIndeces);
447  extensives_ = VectorValues(extensives_, HilbertIndeces);
448  cells_ = VectorValues(cells_, HilbertIndeces);
449  point_velocities = VectorValues(point_velocities, HilbertIndeces);
450  }
451  // Keep relevant points
452  MPI_exchange_data(tess_, mid_extensives, false);
453  MPI_exchange_data(tess_, extensives_, false);
454  MPI_exchange_data(tess_, cells_, false);
455  MPI_exchange_data(tess_, point_velocities, false);
456  MPI_exchange_data(tess_, point_velocities, true);
457 #else
458  vector<int> HilbertIndeces = MoveMeshPoints(point_velocities, dt, tess_, cycle_ % 25 == 0);
459  if (cycle_ % 25 == 0)
460  {
461  mid_extensives = VectorValues(mid_extensives, HilbertIndeces);
462  extensives_ = VectorValues(extensives_, HilbertIndeces);
463  cells_ = VectorValues(cells_, HilbertIndeces);
464  point_velocities = VectorValues(point_velocities, HilbertIndeces);
465 }
466 #endif
467 #ifdef RICH_DEBUG_PRINT
468  MPI_Barrier(MPI_COMM_WORLD);
469  if (rank == 0)
470  std::cout << "Here 7" << std::endl;
471 #endif
472 
473  cache_data_.reset();
474 
475  vector<ComputationalCell> mid_cells = cu_(tess_, pg_, eos_, mid_extensives, cells_, cache_data_,
476  tracer_sticker_names_, time_ + dt);
477 #ifdef RICH_DEBUG_PRINT
478  MPI_Barrier(MPI_COMM_WORLD);
479  if (rank == 0)
480  std::cout << "Here 8" << std::endl;
481 #endif
482 
483 #ifdef RICH_MPI
484  MPI_exchange_data(tess_, mid_cells, true);
485  MPI_exchange_data(tess_, cells_, true);
486 #endif
487  edge_velocities =
488  edge_velocity_calculator_(tess_, point_velocities);
489 
490  const vector<Extensive> fluxes =
491  fc_
492  (tess_,
493  edge_velocities,
494  mid_cells,
495  mid_extensives,
496  cache_data_,
497  eos_,
498  time_,
499  dt,tracer_sticker_names_);
500 
501 #ifdef RICH_DEBUG_PRINT
502  MPI_Barrier(MPI_COMM_WORLD);
503  if (rank == 0)
504  std::cout << "Here 9" << std::endl;
505 #endif
506 
508  (tess_,
509  pg_,
510  cache_data_,
511  mid_cells,
512  fluxes,
513  point_velocities,
514  source_,
515  time_ + dt,
516  dt,
517  mid_extensives,tracer_sticker_names_);
518 
519  eu_(fluxes, pg_, tess_, dt, cache_data_, cells_, mid_extensives, time_ + dt,tracer_sticker_names_);
520 
521 #ifdef RICH_DEBUG_PRINT
522  MPI_Barrier(MPI_COMM_WORLD);
523  if (rank == 0)
524  std::cout << "Here 10" << std::endl;
525 #endif
526 
527 
528  extensives_ = average_extensive(mid_extensives, extensives_);
529 
530  cells_ = cu_(tess_, pg_, eos_, extensives_, cells_, cache_data_,tracer_sticker_names_, time_ + dt);
531 
532 #ifdef RICH_DEBUG_PRINT
533  MPI_Barrier(MPI_COMM_WORLD);
534  if (rank == 0)
535  std::cout << "Here 11" << std::endl;
536 #endif
537 
538 #ifdef RICH_MPI
539  MPI_exchange_data(tess_, cells_, true);
540 #endif
541 
542  time_ += dt;
543  ++cycle_;
544 }
545 
547 {
548  vector<Vector2D> point_velocities = point_motion_(tess_, cells_, time_,tracer_sticker_names_);
549 
550  vector<Vector2D> edge_velocities = edge_velocity_calculator_(tess_, point_velocities);
551 
552  const double dt = tsf_(tess_, cells_, eos_, edge_velocities, time_,tracer_sticker_names_);
553 
554  point_velocities = point_motion_.ApplyFix(tess_, cells_, time_, dt, point_velocities,tracer_sticker_names_);
555 
556  edge_velocities = edge_velocity_calculator_(tess_, point_velocities);
557 
558  vector<Extensive> fluxes = fc_(tess_, edge_velocities, cells_, extensives_, cache_data_, eos_, time_, 0.5*dt,
559  tracer_sticker_names_);
560 
561  vector<Extensive> mid_extensives = extensives_;
562 
563  boost::scoped_ptr<Tessellation> oldtess(tess_.clone());
564 
565  vector<Vector2D> old_points = tess_.GetMeshPoints();
566  old_points.resize(static_cast<size_t>(tess_.GetPointNo()));
567  MoveMeshPoints(point_velocities, 0.5*dt, tess_, false);
568 
569  CacheData data_temp(*oldtess, pg_);
570 
571  mid_extensives = mid_extensives + FluxFix2(*oldtess, *oldtess, tess_, point_velocities, 0.5*dt, cells_, fluxes,
572  edge_velocities, obc_, eos_);
573 
574  eu_(fluxes, pg_, *oldtess, 0.5*dt, data_temp, cells_, mid_extensives, time_,tracer_sticker_names_);
575 
576  ExternalForceContribution(*oldtess, pg_, data_temp, cells_, fluxes, point_velocities, source_, time_, 0.5*dt,
577  mid_extensives,tracer_sticker_names_);
578 
579  time_ += 0.5*dt;
580  cache_data_.reset();
581 
582  vector<ComputationalCell> mid_cells = cu_(tess_, pg_, eos_, mid_extensives, cells_, cache_data_,tracer_sticker_names_, time_);
583 
584  edge_velocities = edge_velocity_calculator_(tess_, point_velocities);
585 
586  fluxes = fc_(tess_, edge_velocities, mid_cells, mid_extensives, cache_data_, eos_, time_, dt,tracer_sticker_names_);
587 
588  boost::scoped_ptr<Tessellation> midtess(tess_.clone());
589 
590  MoveMeshPoints(point_velocities, dt, tess_, false, old_points);
591 
592  CacheData cachetemp2(*midtess, pg_);
593 
594  extensives_ = extensives_ + FluxFix2(*oldtess, *midtess, tess_, point_velocities, dt, mid_cells, fluxes,
595  edge_velocities, obc_, eos_);
596 
597  eu_(fluxes, pg_, *midtess, dt, cachetemp2, cells_, extensives_, time_,tracer_sticker_names_);
598 
599  ExternalForceContribution(*midtess, pg_, cachetemp2, mid_cells, fluxes, point_velocities, source_, time_, dt,
600  extensives_,tracer_sticker_names_);
601 
602  cache_data_.reset();
603  cells_ = cu_(tess_, pg_, eos_, extensives_, cells_, cache_data_,tracer_sticker_names_, time_ + 0.5 * dt);
604 
605  if (cycle_ % 25 == 0)
606  {
607  vector<int> HilbertIndeces = MoveMeshPoints(point_velocities, dt, tess_, cycle_ % 25 == 0, old_points);
608  extensives_ = VectorValues(extensives_, HilbertIndeces);
609  cells_ = VectorValues(cells_, HilbertIndeces);
610  cache_data_.reset();
611  }
612 
613  time_ += 0.5*dt;
614  ++cycle_;
615 }
616 
618 {
619  vector<Vector2D> point_velocities = point_motion_(tess_, cells_, time_,tracer_sticker_names_);
620 
621  vector<Vector2D> edge_velocities = edge_velocity_calculator_(tess_, point_velocities);
622 
623  const double dt = tsf_(tess_, cells_, eos_, edge_velocities, time_,tracer_sticker_names_);
624 
625  point_velocities = point_motion_.ApplyFix(tess_, cells_, time_, dt, point_velocities,tracer_sticker_names_);
626 
627  edge_velocities = edge_velocity_calculator_(tess_, point_velocities);
628 
629  vector<Extensive> fluxes = fc_(tess_, edge_velocities, cells_, extensives_, cache_data_, eos_, time_, 0.5*dt,
630  tracer_sticker_names_);
631 
632  vector<Extensive> mid_extensives = extensives_;
633 
634  eu_(fluxes, pg_, tess_, 0.5*dt, cache_data_, cells_, mid_extensives, time_,tracer_sticker_names_);
635 
636  ExternalForceContribution(tess_, pg_, cache_data_, cells_, fluxes, point_velocities, source_, time_, 0.5*dt,
637  mid_extensives,tracer_sticker_names_);
638 
639  vector<Vector2D> old_points = tess_.GetMeshPoints();
640  old_points.resize(static_cast<size_t>(tess_.GetPointNo()));
641 
642  boost::scoped_ptr<Tessellation> oldtess(tess_.clone());
643 
644  vector<int> HilbertIndeces = MoveMeshPoints(point_velocities, 0.5*dt, tess_, cycle_ % 25 == 0);
645  if (cycle_ % 25 == 0)
646  {
647  mid_extensives = VectorValues(mid_extensives, HilbertIndeces);
648  extensives_ = VectorValues(extensives_, HilbertIndeces);
649  cells_ = VectorValues(cells_, HilbertIndeces);
650  point_velocities = VectorValues(point_velocities, HilbertIndeces);
651  old_points = VectorValues(old_points, HilbertIndeces);
652  }
653 
654 
655  time_ += 0.5*dt;
656 
657  cache_data_.reset();
658 
659  vector<ComputationalCell> mid_cells = cu_(tess_, pg_, eos_, mid_extensives, cells_, cache_data_,
660  tracer_sticker_names_, time_);
661 
662  edge_velocities = edge_velocity_calculator_(tess_, point_velocities);
663 
664  fluxes = fc_(tess_, edge_velocities, mid_cells, mid_extensives, cache_data_, eos_, time_, dt,
665  tracer_sticker_names_);
666 
667  eu_(fluxes, pg_, tess_, dt, cache_data_, cells_, extensives_, time_,tracer_sticker_names_);
668 
669  ExternalForceContribution(tess_, pg_, cache_data_, mid_cells, fluxes, point_velocities, source_, time_, dt,
670  extensives_,tracer_sticker_names_);
671 
672  boost::scoped_ptr<Tessellation> midtess(tess_.clone());
673 
674  MoveMeshPoints(point_velocities, dt, tess_, false, old_points);
675  cache_data_.reset();
676 
677  cells_ = cu_(tess_, pg_, eos_, extensives_, cells_, cache_data_,tracer_sticker_names_, time_ + 0.5 * dt);
678 
679  time_ += 0.5*dt;
680  ++cycle_;
681 }
682 
683 namespace {
684 
685  template<class T> class AverageCalculator : public LazyList<T>
686  {
687  public:
688 
689  AverageCalculator(const vector<T>& ll1,
690  const vector<T>& ll2) :
691  ll1_(ll1), ll2_(ll2)
692  {
693  assert(ll1.size() == ll2.size());
694  }
695 
696  size_t getLength(void) const
697  {
698  return ll1_.size();
699  }
700 
701  T operator()(size_t i) const
702  {
703  return 0.5*(ll1_[i] + ll2_[i]);
704  }
705 
706  private:
707  const vector<T>& ll1_;
708  const vector<T>& ll2_;
709  };
710 }
711 
713 {
714  return pg_;
715 }
716 
718 {
719  return tess_;
720 }
721 
723 {
724  return tess_;
725 }
726 
727 // Diagnostics
728 
729 double hdsim::getTime(void) const
730 {
731  return time_;
732 }
733 
734 int hdsim::getCycle(void) const
735 {
736  return cycle_;
737 }
738 
739 const vector<ComputationalCell>& hdsim::getAllCells(void) const
740 {
741  return cells_;
742 }
743 
744 vector<ComputationalCell>& hdsim::getAllCells(void)
745 {
746  return cells_;
747 }
748 
750 {
751  cells_ = cu_(tess_, pg_, eos_, extensives_, cells_,
752  cache_data_,tracer_sticker_names_, time_);
753 #ifdef RICH_MPI
754  MPI_exchange_data(tess_, cells_, true);
755 #endif
756 
757 }
758 
760 {
761  for (size_t i = 0; i < extensives_.size(); ++i)
762  {
763  const ComputationalCell& cell = cells_[i];
764  const double volume = cache_data_.volumes[i];
765  const double mass = volume*cell.density;
766  extensives_[i].mass = mass;
767  extensives_[i].energy = eos_.dp2e(cell.density, cell.pressure, cell.tracers,tracer_sticker_names_.tracer_names)
768  *mass + 0.5*mass*ScalarProd(cell.velocity, cell.velocity);
769  extensives_[i].momentum = mass*cell.velocity;
770  extensives_[i].tracers.resize(cell.tracers.size());
771  size_t N = cell.tracers.size();
772  for (size_t j = 0; j < N; ++j)
773  extensives_[i].tracers[j] = cell.tracers[j] * mass;
774  }
775 }
776 
777 void hdsim::setCycle(int cycle)
778 {
779  cycle_ = cycle;
780 }
781 
782 void hdsim::setStartTime(double t_start)
783 {
784  time_ = t_start;
785 }
786 
787 const EquationOfState& hdsim::getEos(void) const
788 {
789  return eos_;
790 }
791 
793 {
794  return obc_;
795 }
796 
797 const vector<Extensive>& hdsim::getAllExtensives(void) const
798 {
799  return extensives_;
800 }
801 
802 vector<Extensive>& hdsim::getAllExtensives(void)
803 {
804  return extensives_;
805 }
806 
807 double hdsim::getCellVolume(size_t index) const
808 {
809  return pg_.calcVolume
810  (serial_generate(CellEdgesGetter(tess_, static_cast<int>(index))));
811 }
812 
813 const CacheData& hdsim::getCacheData(void) const
814 {
815  return cache_data_;
816 }
817 
818 #ifdef RICH_MPI
820 {
821  return proctess_;
822 }
823 #endif// RICH_MPI
const Tessellation & GetProcTessellation(void) const
Returns the processor tessellation.
Definition: hdsim2d.cpp:819
vector< T > VectorValues(vector< T > const &v, vector< int > const &index)
Returns only the values with indeces in index.
Definition: utils.hpp:326
void sort_index(const vector< T > &arr, vector< int > &res)
Returns the indeces of a sort.
Definition: utils.hpp:500
Base class for extensive update scheme.
Abstract class for tessellation.
virtual int GetPointNo(void) const =0
Get Total number of mesh generating points.
Fixes the area inconsistency problem.
Two dimensional, newtonian simulation.
virtual double calcVolume(const vector< Edge > &edge_list) const =0
Calculates the physical volume of a cell.
vector< T > serial_generate(const LazyList< T > &ll)
Creates a vector from an LazyList.
Definition: lazy_list.hpp:49
double getTime(void) const
Returns the time.
Definition: hdsim2d.cpp:729
Interface between two cells.
Definition: Edge.hpp:13
void recalculatePrimitives(void)
Recalculates the primitives from the extensive variables.
Definition: hdsim2d.cpp:749
Base class for a scheme to calculate the velocity on the edges.
Abstract class for motion of mesh generating points.
const Tessellation & getTessellation(void) const
Returns the tessellation.
Definition: hdsim2d.cpp:722
void recalculateExtensives(void)
Recalculates extensives (in case computational cells were changed manually)
Definition: hdsim2d.cpp:759
tvector tracers
Tracers (can transfer from one cell to another)
Ordered list whose terms are evaluated lazily.
Definition: lazy_list.hpp:17
void setCycle(int cycle)
Sets the cycle.
Definition: hdsim2d.cpp:777
TracerStickerNames const & GetTracerStickerNames(void) const
Returns the TracerStickerNames.
Definition: hdsim2d.cpp:172
Abstract class for external forces.
Definition: SourceTerm.hpp:17
double pressure
Pressure.
int getCycle(void) const
Returns the number cycles.
Definition: hdsim2d.cpp:734
const PhysicalGeometry & getPhysicalGeometry(void) const
Access to physical geometry.
Definition: hdsim2d.cpp:712
const CacheData & getCacheData(void) const
Returns reference to the cached data.
Definition: hdsim2d.cpp:813
Updates the positions of the processes.
double ScalarProd(Vector3D const &v1, Vector3D const &v2)
Scalar product of two vectors.
Definition: Vector3D.cpp:185
Base class for flux calculator.
Base class for equation of state.
void ExternalForceContribution(const Tessellation &tess, const PhysicalGeometry &pg, const CacheData &cd, const vector< ComputationalCell > &cells, const vector< Extensive > &fluxes, const vector< Vector2D > &point_velocities, const SourceTerm &source, double t, double dt, vector< Extensive > &extensives, TracerStickerNames const &tracerstickernames)
Adds force contribution to the extensive conserved variables.
Container for cache data.
Definition: cache_data.hpp:14
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
Base class for cell update scheme.
Class for keeping the names of the tracers and stickers.
void TimeAdvance2MidPointClip(void)
Second order time advance, mid point method with area fix.
Definition: hdsim2d.cpp:546
void TimeAdvance2MidPoint(void)
Second order time advance, mid point method.
Definition: hdsim2d.cpp:617
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.
Various manipulations of hydrodynamic variables.
void TimeAdvance(void)
Advances the simulation in time.
Definition: hdsim2d.cpp:177
Abstract class for time step function.
~hdsim(void)
Class destructor.
Definition: hdsim2d.cpp:170
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
void TimeAdvanceClip(void)
Advances the simulation in time with area fix.
Definition: hdsim2d.cpp:271
void setStartTime(double t_start)
Sets the start time.
Definition: hdsim2d.cpp:782
void TimeAdvance2Heun(void)
Second order time advance.
Definition: hdsim2d.cpp:351
vector< int > MoveMeshPoints(vector< Vector2D > const &pointvelocity, double dt, Tessellation &tessellation, bool reorder, vector< Vector2D > oldpoints=vector< Vector2D >())
Move mesh points.
Base class for physical geometry.
double fastabs(Vector2D const &v)
Norm of a vector, less accurate.
Definition: geometry.cpp:24
double getCellVolume(size_t index) const
Returns the volume of a certain cell.
Definition: hdsim2d.cpp:807
vector< Extensive > FluxFix2(Tessellation const &tessold, Tessellation const &tessmid, Tessellation const &tessnew, vector< Vector2D > const &pointvelocity, double dt, vector< ComputationalCell > const &cells, vector< Extensive > const &fluxes, vector< Vector2D > const &fv, OuterBoundary const &outer, EquationOfState const &eos)
Fixes the flux to propely converge second order.
Definition: AreaFix.cpp:523
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