Peano
Loading...
Searching...
No Matches
KernelBenchmarks-main.cpp
Go to the documentation of this file.
1// This file is part of the ExaHyPE2 project. For conditions of distribution and
2// use, please see the copyright notice at www.peano-framework.org
3#include "KernelBenchmarks-main.h"
4
5#include "AbstractFVSolver.h"
6#include "Constants.h"
7#include "DataRepository.h"
9#include "FVSolver.h"
10#include "exahype2/EnclaveBookkeeping.h"
11#include "exahype2/fv/BoundaryConditions.h"
12#include "exahype2/fv/PatchUtils.h"
13#include "kernels/FVSolver/HandleBoundaryFused.h"
14#include "kernels/FVSolver/ProjectPatchFused.h"
15#include "kernels/FVSolver/ReconstructPatch.h"
16#include "kernels/FVSolver/ReconstructPatchFused.h"
17#include "kernels/FVSolver/RiemannSolverFused.h"
18#include "peano4/Globals.h"
19#include "peano4/datamanagement/CellMarker.h"
20#include "peano4/datamanagement/FaceEnumerator.h"
21#include "peano4/peano4.h"
22#include "peano4/utils/Loop.h"
23#include "tarch/logging/Log.h"
24#include "tarch/plotter/AMRPlotter.h"
25#include "tarch/plotter/PVDTimeSeriesWriter.h"
26#include "tarch/plotter/VTUFileWriter.h"
27#include "tarch/timing/Measurement.h"
28#include "tarch/timing/Watch.h"
29#include "toolbox/blockstructured/Interpolation.h"
30#include "toolbox/blockstructured/Projection.h"
31#include "toolbox/blockstructured/Restriction.h"
32
34
35namespace {
36 tarch::logging::Log _log("");
37 tarch::timing::Measurement timeStepMeasurement;
38 double logNextTimeStep = 0.0;
39 bool haveReceivedNonCriticalAssertion = false;
40
41 std::vector<peano4::datamanagement::CellMarker> _cells;
42 const tarch::la::Vector<DIMENSIONS, double> CellSize = DomainSize / static_cast<double>(GridLength);
43
44 template <typename T>
45 std::string toScientificNotationString(T value, int precision = 4, bool considerSign = false, double threshold = 1e6) {
46 std::ostringstream out;
47 double v = static_cast<double>(value);
48
49 if (std::abs(v) < threshold) {
50 if (considerSign) {
51 out << std::showpos;
52 }
53 out << value;
54 return out.str();
55 }
56
57 out << std::scientific << std::setprecision(precision);
58 if (considerSign) {
59 out << std::showpos;
60 }
61 out << v;
62 return out.str();
63 }
64} // namespace
65
67 const tarch::timing::Measurement& measurement,
68 const tarch::timing::Measurement& measurementBoundary,
69 const tarch::timing::Measurement& measurementReconstruct,
70 const tarch::timing::Measurement& measurementRiemann,
71 const tarch::timing::Measurement& measurementProjection
72) {
73 if (measurementBoundary.getNumberOfMeasurements() > 0) {
74 logInfo(
75 "logFinalStatistics()",
76 "Boundary handling: "
77 << measurementBoundary.getAccumulatedValue() << "s\t" << measurementBoundary.toString()
78 );
79 }
80 if (measurementReconstruct.getNumberOfMeasurements() > 0) {
81 logInfo(
82 "logFinalStatistics()",
83 "Reconstruction: "
84 << measurementReconstruct.getAccumulatedValue() << "s\t" << measurementReconstruct.toString()
85 );
86 }
87 if (measurementRiemann.getNumberOfMeasurements() > 0) {
88 logInfo(
89 "logFinalStatistics()",
90 "Riemann solver: "
91 << measurementRiemann.getAccumulatedValue() << "s\t" << measurementRiemann.toString()
92 );
93 }
94 if (measurementProjection.getNumberOfMeasurements() > 0) {
95 logInfo(
96 "logFinalStatistics()",
97 "Projection: "
98 << measurementProjection.getAccumulatedValue() << "s\t" << measurementProjection.toString()
99 );
100 }
101
102 if (measurement.getNumberOfMeasurements() > 0) {
103 logInfo(
104 "logFinalStatistics()",
105 "Time stepping: "
106 << measurement.getAccumulatedValue() << "s\t" << measurement.toString()
107 );
108
109 const auto globalNumberOfPatches = _cells.size();
110 const auto totalNumberOfDoFs = globalNumberOfPatches
111 * std::pow(AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch, DIMENSIONS)
112 * (AbstractFVSolver::NumberOfUnknowns + AbstractFVSolver::NumberOfAuxiliaryVariables);
113
114 logInfo(
115 "logFinalStatistics()",
116 "Average patch updates per second: " << globalNumberOfPatches / measurement.getValue()
117 );
118 logInfo(
119 "logFinalStatistics()",
120 "Average DoF updates per second: " << totalNumberOfDoFs / measurement.getValue()
121 );
122 }
123}
124
125void plotGrid() {
126 repositories::startPlottingStep();
127
128 const std::string outputDirectory = "solutions";
129 const std::string solutionFileName = "FVSolver";
130
131 const double t = 0.5 * (repositories::getMinTimeStamp() + repositories::getMaxTimeStamp());
132
133 static tarch::plotter::PVDTimeSeriesWriter timeSeriesWriter;
134 tarch::plotter::VTUFileWriter fileWriter(outputDirectory, 1);
135 tarch::plotter::AMRPlotter amrPlotter(fileWriter, 0, 0.5, 0.0);
136
137 auto cellDataPlotter = fileWriter.createCellDataPlotter(0, "FVSolverQ", AbstractFVSolver::NumberOfUnknowns);
138
139 for (auto& marker : _cells) {
140 if (not marker.hasBeenRefined()) {
141 const auto& patchSize = marker.getH();
142 const auto& patchOffset = marker.getX() - patchSize * 0.5;
143
144 const auto cellSize = patchSize / static_cast<double>(AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch);
145 const auto* QOut = DataRepository::getInstance().getCellQ(marker.getX(), marker.getH());
146
147 int currentDoF = 0;
148 dfor(k, AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch) {
149#if DIMENSIONS == 2
150 tarch::la::Vector<2, double> cellOffset;
151 cellOffset(0) = patchOffset(0) + static_cast<double>(k(0)) * cellSize(0);
152 cellOffset(1) = patchOffset(1) + static_cast<double>(k(1)) * cellSize(1);
153 const int cellIndex = amrPlotter.plotCell2D(cellOffset, cellSize, 0);
154#else
155 tarch::la::Vector<3, double> cellOffset;
156 cellOffset(0) = patchOffset(0) + static_cast<double>(k(0)) * cellSize(0);
157 cellOffset(1) = patchOffset(1) + static_cast<double>(k(1)) * cellSize(1);
158 cellOffset(2) = patchOffset(2) + static_cast<double>(k(2)) * cellSize(2);
159 const int cellIndex = amrPlotter.plotCell3D(cellOffset, cellSize, 0);
160#endif
161
162 const auto* values = QOut + currentDoF;
163 cellDataPlotter->plotCellData(cellIndex, values, AbstractFVSolver::NumberOfUnknowns);
164
165 currentDoF += AbstractFVSolver::NumberOfUnknowns;
166 }
167 }
168 }
169
170 timeSeriesWriter.writeSnapshotFile(solutionFileName, t, fileWriter);
171 timeSeriesWriter.writeTimeSeriesMetaFile(outputDirectory, solutionFileName);
172
173 repositories::finishPlottingStep();
174}
175
177 for (auto& marker : _cells) {
178 if (marker.getH()[0] < CellSize[0]) { // Check if cell is in AMR region
179 auto parentSize = marker.getH() * 3.0;
180 auto parentCenter = marker.getInvokingParentCellsCentre();
181
182 for (int f = 0; f < TWO_TIMES_D; f++) {
183 int normal = f % DIMENSIONS;
184 if ((f >= DIMENSIONS and marker.getRelativePositionWithinFatherCell()[normal] == 2)
185 or (f < DIMENSIONS and marker.getRelativePositionWithinFatherCell()[normal] == 0)) {
186 peano4::datamanagement::FaceMarker faceMarker{};
187 faceMarker.relativePositionWithinFatherCell = marker.getRelativePositionWithinFatherCell();
188 faceMarker.selectedFace = f;
189 double* fineGridFace = DataRepository::getInstance().getFaceQNew(marker.getX(), marker.getH(), f);
190 double* coarseGridFace = DataRepository::getInstance().getFaceQNew(parentCenter, parentSize, f);
191 toolbox::blockstructured::restrictInnerHalfOfHaloLayer_AoS_inject(
192 faceMarker,
193 AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch,
194 1, // Halo size
195 AbstractFVSolver::NumberOfUnknowns,
196 fineGridFace,
197 coarseGridFace,
198 false
199 );
200 }
201 }
202 }
203 }
204 for (auto& marker : _cells) {
205 if (marker.getH()[0] < CellSize[0]) { // Check if cell is in AMR region
206 auto parentCenter = marker.getInvokingParentCellsCentre();
207 auto parentSize = marker.getH() * 3.0;
208
209 for (int f = 0; f < TWO_TIMES_D; f++) {
210 int normal = f % DIMENSIONS;
211 if ((f >= DIMENSIONS and marker.getRelativePositionWithinFatherCell()[normal] == 2)
212 or (f < DIMENSIONS and marker.getRelativePositionWithinFatherCell()[normal] == 0)) {
213 peano4::datamanagement::FaceMarker faceMarker{};
214 faceMarker.relativePositionWithinFatherCell = marker.getRelativePositionWithinFatherCell();
215 faceMarker.selectedFace = f;
216 double* fineGridFace = DataRepository::getInstance().getFaceQNew(marker.getX(), marker.getH(), f);
217 double* coarseGridFace = DataRepository::getInstance().getFaceQNew(parentCenter, parentSize, f);
218 toolbox::blockstructured::interpolateHaloLayer_AoS_piecewise_constant(
219 faceMarker,
220 AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch,
221 1, // Halo size
222 AbstractFVSolver::NumberOfUnknowns,
223 coarseGridFace,
224 fineGridFace
225 );
226 }
227 }
228 }
229 }
230}
231
233 for (auto& marker : _cells) {
234 if (not marker.hasBeenRefined()) {
235 double* QOut = DataRepository::getInstance().getCellQ(marker.getX(), marker.getH());
236 // Initialise cell data with initial conditions.
237 dfor(volume, AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch) {
238 int linearIndex = peano4::utils::dLinearised(volume, AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch)
239 * (AbstractFVSolver::NumberOfUnknowns + AbstractFVSolver::NumberOfAuxiliaryVariables);
240 FVSolver::initialCondition(
241 QOut + linearIndex,
242 ::exahype2::fv::getVolumeCentre(
243 marker.getX(),
244 marker.getH(),
245 AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch,
246 volume
247 ),
248 ::exahype2::fv::getVolumeSize(marker.getH(), AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch)
249 );
250 }
251 }
252 }
253}
254
255peano4::datamanagement::CellMarker createMarkerFromIndex(const tarch ::la ::Vector<DIMENSIONS, int>& index) {
256 tarch::la::Vector<DIMENSIONS, double> cellIndex = tarch::la::convertScalar<double>(index);
257 tarch::la::Vector<DIMENSIONS, double> cellPositionBase = DomainOffset + CellSize / 2.0;
258 tarch::la::Vector<DIMENSIONS, double>
259 cellPosition = cellPositionBase + tarch::la::multiplyComponents(cellIndex, CellSize);
260 peano4::datamanagement::CellMarker marker;
261 marker.h = CellSize;
262 marker.centre = cellPosition;
263 return marker;
264}
265
266std::vector<peano4::datamanagement::CellMarker> createRefinedMarkersFromIndex(
267 const tarch ::la ::Vector<DIMENSIONS, int>& index
268) {
269 tarch::la::Vector<DIMENSIONS, double> cellIndex = tarch::la::convertScalar<double>(index);
270 tarch::la::Vector<DIMENSIONS, double> deeperCellIndex = cellIndex * 3.0;
271 tarch::la::Vector<DIMENSIONS, double> deeperCellSize = CellSize / 3.0;
272 tarch::la::Vector<DIMENSIONS, double> cellPositionBase = DomainOffset + CellSize / 2.0;
273 tarch::la::Vector<DIMENSIONS, double> deepercellPositionBase = DomainOffset + deeperCellSize / 2.0;
274
275 std::vector<peano4::datamanagement::CellMarker> result;
276
277 tarch::la::Vector<DIMENSIONS, double>
278 cellPosition = cellPositionBase + tarch::la::multiplyComponents(cellIndex, CellSize);
279 peano4::datamanagement::CellMarker marker;
280 marker.centre = cellPosition;
281 marker.h = CellSize;
282 marker.flags |= peano4::datamanagement::CellMarker::HasBeenRefined;
283 result.push_back(marker);
284
285 dfor(offset, 3) {
286 tarch::la::Vector<DIMENSIONS, double> deepCellOffset = tarch::la::convertScalar<double>(offset);
287 tarch::la::Vector<DIMENSIONS, double> localCellIndex = deepCellOffset + deeperCellIndex;
288 tarch::la::Vector<DIMENSIONS, double>
289 deeperCellPosition = deepercellPositionBase + tarch::la::multiplyComponents(localCellIndex, deeperCellSize);
290 peano4::datamanagement::CellMarker marker;
291 marker.centre = deeperCellPosition;
292 marker.h = deeperCellSize;
293 marker.relativePositionWithinFatherCell = offset;
294 result.push_back(marker);
295 }
296 return result;
297}
298
300 repositories::startGridConstructionStep();
301 _cells.reserve(std::pow(GridLength, DIMENSIONS));
302 tarch::la::Vector<DIMENSIONS, double> DomainCenter = DomainOffset + DomainSize / 2.0;
303 dfor(volume, GridLength) {
304 peano4::datamanagement::CellMarker marker = createMarkerFromIndex(volume);
305 if (UseAMR and tarch::la::norm2(marker.getX() - DomainCenter) < 0.1) {
306 auto markers = createRefinedMarkersFromIndex(volume);
307 _cells.insert(std::end(_cells), std::begin(markers), std::end(markers));
308 } else {
309 _cells.push_back(marker);
310 }
311 }
312 repositories::finishGridConstructionStep();
313}
314
315void initGrid() {
316 repositories::startGridInitialisationStep();
318 repositories::finishGridInitialisationStep();
319}
320
321int main(int argc, char** argv) {
322 int returnCode = EXIT_SUCCESS;
323
324 peano4::init(&argc, &argv, DomainOffset, DomainSize);
325
326 repositories::loadBalancer.enable(false);
327 repositories::initLogFilters();
328 repositories::startSimulation();
329
330 createGrid();
331 initGrid();
332
334 enclaveGrid.startCollection();
335 for (auto& marker : _cells) {
336 if (not marker.hasBeenRefined()) {
337 enclaveGrid.bookmarkCell(marker.getX(), marker.getH());
338 }
339 }
340
341 enclaveGrid.buildFromBookmarks();
342
343 benchmarks::exahype2::kernelbenchmarks::kernels::FVSolver::projectPatchFused(
344 enclaveGrid.getQ(),
345 enclaveGrid.getFacePool(),
346 enclaveGrid.getFaceIndices(),
347 enclaveGrid.getNumberOfEnclaveCells(),
348 0
349 );
350
351 tarch::timing::Measurement measurement(1.0);
352 tarch::timing::Measurement measurementBoundary(1.0);
353 tarch::timing::Measurement measurementReconstruct(1.0);
354 tarch::timing::Measurement measurementRiemann(1.0);
355 tarch::timing::Measurement measurementProjection(1.0);
356 tarch::timing::Watch timeStepWatch("::", "main()", false);
357 double timeStamp = 0.0;
358 double nextMinPlotTimeStamp = FirstPlotTimeStamp;
359 double nextMaxPlotTimeStamp = FirstPlotTimeStamp;
360 bool continueToSolve = true;
361 int count = 0;
362
363 while (continueToSolve) {
364 if (Samples > 0 and count++ >= Samples) {
365 continueToSolve = false;
366 }
367 if (repositories::getMinTimeStamp() >= nextMinPlotTimeStamp
368 or repositories::getMaxTimeStamp() >= nextMaxPlotTimeStamp) {
369 if (repositories::getMinTimeStamp() >= nextMinPlotTimeStamp) {
370 nextMinPlotTimeStamp += TimeInBetweenPlots;
371 }
372 if (repositories::getMaxTimeStamp() >= nextMaxPlotTimeStamp) {
373 nextMaxPlotTimeStamp += TimeInBetweenPlots;
374 }
375
376 if constexpr (ShouldPlot) {
377 enclaveGrid.syncCellsDeviceToHost();
378 plotGrid();
379 }
380 }
381 if (UseAMR) {
382 enclaveGrid.syncFacesDeviceToHost();
384 enclaveGrid.syncFacesHostToDevice();
385 // Hack to make static AMR work in the mini-app. The full-app uses face updates that get interpolated between
386 // coarse and fine faces. In the mini-app we do interpolation a bit different because we only use one face type to
387 // keep things simple. We therefore first restrict the fine grid faces into the coarse grid faces, we do this for
388 // all faces that have been refined. We then interpolate these coarse grid faces onto the fine grid faces. This is
389 // needed at the AMR boundary, but not at the internal faces of the refined region. I have currently implemented
390 // no way to distinguish between internal faces in the AMR region and those at the boundary. The interpolation
391 // step therefore introduces a loss of precision at the internal faces of the AMR region. We can circumvent this
392 // by reprojecting the cell data onto the faces for all cells. This is less than ideal and should be improved.
393 benchmarks::exahype2::kernelbenchmarks::kernels::FVSolver::projectPatchFused(
394 enclaveGrid.getQ(),
395 enclaveGrid.getFacePool(),
396 enclaveGrid.getFaceIndices(),
397 enclaveGrid.getNumberOfEnclaveCells(),
398 0
399 );
400 }
401
402 timeStepWatch.start();
403 repositories::startTimeStep();
404
405 double dt = repositories::instanceOfFVSolver.getAdmissibleTimeStepSize();
406
407 tarch::timing::Watch watch("", "", false);
408 watch.start();
409
410 tarch::timing::Watch watchBoundary("", "", false);
411 watchBoundary.start();
412 benchmarks::exahype2::kernelbenchmarks::kernels::FVSolver::handleBoundaryFused(
413 repositories::instanceOfFVSolver,
414 enclaveGrid.getFacePool(),
415 enclaveGrid.getBoundaryFaceIndices(),
416 enclaveGrid.getBoundaryFaceNumbers(),
417 enclaveGrid.getBoundaryCellIndices(),
418 enclaveGrid.getCellCentres(),
419 enclaveGrid.getCellSizes(),
420 timeStamp,
421 dt,
422 enclaveGrid.getNumberOfBoundaryFaces(),
423 enclaveGrid.getNumberOfEnclaveCells(),
424 0
425 );
426 watchBoundary.stop();
427
428 tarch::timing::Watch watchReconstruct("", "", false);
429 watchReconstruct.start();
430 benchmarks::exahype2::kernelbenchmarks::kernels::FVSolver::reconstructPatchFused(
431 enclaveGrid.getQ(),
432 enclaveGrid.getFacePool(),
433 enclaveGrid.getFaceIndices(),
434 enclaveGrid.getQReconstructed(),
435 enclaveGrid.getNumberOfEnclaveCells(),
436 0
437 );
438 watchReconstruct.stop();
439
440 tarch::timing::Watch watchRiemann("", "", false);
441 watchRiemann.start();
442 const auto maxEigenvalue = benchmarks::exahype2::kernelbenchmarks::kernels::FVSolver::riemannSolverFused(
443 repositories::instanceOfFVSolver,
444 enclaveGrid.getQReconstructed(),
445 enclaveGrid.getQ(),
446 timeStamp,
447 dt,
448 enclaveGrid.getCellCentres()[0].data(),
449 enclaveGrid.getCellSizes()[0].data(),
450 enclaveGrid.getNumberOfEnclaveCells(),
451 0
452 );
453 watchRiemann.stop();
454
455 tarch::timing::Watch watchProjection("", "", false);
456 watchProjection.start();
457 benchmarks::exahype2::kernelbenchmarks::kernels::FVSolver::projectPatchFused(
458 enclaveGrid.getQ(),
459 enclaveGrid.getFacePool(),
460 enclaveGrid.getFaceIndices(),
461 enclaveGrid.getNumberOfEnclaveCells(),
462 0
463 );
464 watchProjection.stop();
465 watch.stop();
466
467 measurement.setValue(watch.getCalendarTime());
468 measurementBoundary.setValue(watchBoundary.getCalendarTime());
469 measurementReconstruct.setValue(watchReconstruct.getCalendarTime());
470 measurementRiemann.setValue(watchRiemann.getCalendarTime());
471 measurementProjection.setValue(watchProjection.getCalendarTime());
472
473 repositories::instanceOfFVSolver.setMaxEigenvalue(maxEigenvalue);
474 const auto newTimeStepSize = repositories::instanceOfFVSolver.getAdmissibleTimeStepSize();
475 repositories::instanceOfFVSolver
476 .update(newTimeStepSize, timeStamp + dt, enclaveGrid.getMinVolumeH(), enclaveGrid.getMaxVolumeH());
477
478 timeStamp += repositories::instanceOfFVSolver.getAdmissibleTimeStepSize();
479 repositories::finishTimeStep();
480
481 timeStepWatch.stop();
482 timeStepMeasurement.setValue(timeStepWatch.getCalendarTime());
483
484 if (timeStepMeasurement.getAccumulatedValue() >= logNextTimeStep) {
485 const auto totalPersistentMemory = DataRepository::getInstance().getMemoryUsageInBytes();
486
487 const auto globalNumberOfPatches = _cells.size();
488 const auto totalNumberOfDoFs
489 = globalNumberOfPatches * std::pow(AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch, DIMENSIONS)
490 * (AbstractFVSolver::NumberOfUnknowns + AbstractFVSolver::NumberOfAuxiliaryVariables);
491
492 std::ostringstream msg;
493 msg
494 << "Patches=" << toScientificNotationString(globalNumberOfPatches) << ", DoFs="
495 << toScientificNotationString(totalNumberOfDoFs) << ", Memory=" << std::fixed << std::setprecision(2)
496 << tarch::convertMemorySize(totalPersistentMemory, tarch::chooseMemoryUsageFormat(totalPersistentMemory)) << " "
497 << tarch::toString(tarch::chooseMemoryUsageFormat(totalPersistentMemory));
498 logInfo("main()", msg.str());
499
500 if (timeStepMeasurement.getNumberOfMeasurements() > 0) {
501 const auto dt = measurement.getMostRecentValue();
502 const auto patchesPerSecond = globalNumberOfPatches / dt;
503 const auto dofsPerSecond = totalNumberOfDoFs / dt;
504
505 logInfo(
506 "main()",
507 "Patch updates per second: "
508 << toScientificNotationString(patchesPerSecond)
509 << ", DoF updates per second: " << toScientificNotationString(dofsPerSecond)
510 );
511 }
512
513 repositories::logTimeStep();
514 logNextTimeStep += repositories::LogTimeStepIntervalInSeconds;
515 }
516
517 if (repositories::getMinTimeStamp() >= MinTerminalTime and repositories::getMaxTimeStamp() >= MaxTerminalTime) {
518 continueToSolve = false;
519 }
520
521 if (tarch::hasNonCriticalAssertionBeenViolated() and not haveReceivedNonCriticalAssertion) {
522 continueToSolve = false;
523 haveReceivedNonCriticalAssertion = true;
524 logError("main()", "Noncritical assertion has been triggered in code. Dump final state and terminate.");
525 }
526 }
527
528 // Plot last timestep
529 if constexpr (ShouldPlot) {
530 enclaveGrid.syncCellsDeviceToHost();
531 plotGrid();
532 }
533 repositories::finishSimulation();
534
535 if (haveReceivedNonCriticalAssertion) {
536 logWarning("main()", "Terminated gracefully after noncritical assertion");
537 returnCode = EXIT_FAILURE;
538 } else {
539 // Log final timestep information
540 repositories::logTimeStep();
541 logInfo("main()", "Terminated successfully");
542 returnCode = EXIT_SUCCESS;
543 }
544
546 measurement,
547 measurementBoundary,
548 measurementReconstruct,
549 measurementRiemann,
550 measurementProjection
551 );
552
553 enclaveGrid.clear();
554
555 peano4::shutdown();
556
557 return returnCode;
558}
constexpr double timeStamp
const tarch::la::Vector< DIMENSIONS, double > cellSize
const tarch::la::Vector< DIMENSIONS, double > CellSize
tarch::timing::Measurement timeStepMeasurement
Definition ccz4-main.cpp:58
tarch::logging::Log _log("::")
double * getFaceQNew(int index, int depth, int axis)
double * getCellQ(const tarch::la::Vector< DIMENSIONS, double > &cellCentre, const tarch::la::Vector< DIMENSIONS, double > &cellSize)
Manages GPU data for a sparse subset of active leaf cells.
void bookmarkCell(const tarch::la::Vector< DIMENSIONS, double > &cellCentre, const tarch::la::Vector< DIMENSIONS, double > &cellSize)
peano4::datamanagement::CellMarker createMarkerFromIndex(const tarch ::la ::Vector< DIMENSIONS, int > &index)
int main(int argc, char **argv)
void logFinalStatistics(const tarch::timing::Measurement &measurement, const tarch::timing::Measurement &measurementBoundary, const tarch::timing::Measurement &measurementReconstruct, const tarch::timing::Measurement &measurementRiemann, const tarch::timing::Measurement &measurementProjection)
void applyInitialConditions()
void initGrid()
void plotGrid()
void createGrid()
std::vector< peano4::datamanagement::CellMarker > createRefinedMarkersFromIndex(const tarch ::la ::Vector< DIMENSIONS, int > &index)
void interpolateBetweenAMRBorder()
v
Definition ccz4.py:65