42 const std::string context =
"reportRuntime()";
43 constexpr int LabelWidth = 25;
45 if (measurement.getNumberOfMeasurements() == 0) {
46 logInfo(context,
"Timing Measurement Report: No data recorded.");
50 logInfo(context,
"---------- Timing Measurement Report ----------");
51 double avg = measurement.getValue();
52 double std_dev = measurement.getStandardDeviation();
53 double min_val = measurement.min();
54 double max_val = measurement.max();
55 int min_idx = measurement.getMinMeasurement();
56 int max_idx = measurement.getMaxMeasurement();
57 double min_dev_percent = (avg == 0) ? 0.0 : (min_val / avg - 1.0) * 100.0;
58 double max_dev_percent = (avg == 0) ? 0.0 : (max_val / avg - 1.0) * 100.0;
60 std::stringstream msg;
63 msg << std::left << std::setw(LabelWidth) <<
"Average Value:" << std::fixed << std::setprecision(8) << avg <<
"s";
64 logInfo(context, msg.str());
67 msg << std::left << std::setw(LabelWidth) <<
"Average Cell Updates:" << std::fixed << std::setprecision(0)
68 << _cells.size() / avg;
69 logInfo(context, msg.str());
72 msg << std::left << std::setw(LabelWidth) <<
"Standard Deviation:" << std::scientific << std::setprecision(8)
74 logInfo(context, msg.str());
77 msg << std::left << std::setw(LabelWidth) <<
"# Measurements:" << measurement.getNumberOfMeasurements();
78 logInfo(context, msg.str());
82 << std::left << std::setw(LabelWidth) <<
"Min Value:" << std::fixed << std::setprecision(8) << min_val <<
"s (at #"
84 <<
"[" << std::fixed << std::setprecision(2) << min_dev_percent <<
"%]";
85 logInfo(context, msg.str());
89 << std::left << std::setw(LabelWidth) <<
"Max Value:" << std::fixed << std::setprecision(8) << max_val <<
"s (at #"
90 << max_idx <<
") " << std::showpos
91 <<
"[" << std::fixed << std::setprecision(2) << max_dev_percent <<
"%]";
92 logInfo(context, msg.str());
95 msg << std::left << std::setw(LabelWidth) <<
"Most Recent Value:" << std::fixed << std::setprecision(8)
96 << measurement.getMostRecentValue() <<
"s";
97 logInfo(context, msg.str());
100 msg << std::left << std::setw(LabelWidth) <<
"Accumulated Time:" << std::fixed << std::setprecision(8)
101 << measurement.getAccumulatedValue() <<
"s";
102 logInfo(context, msg.str());
104 logInfo(context,
"-----------------------------------------------");
108 repositories::startPlottingStep();
109 static int counter = -1;
112 std::ostringstream snapshotFileName;
113 snapshotFileName <<
"solutions/solution-FVSolver-" << counter;
115 auto writer = tarch::plotter::griddata::blockstructured::PeanoTextPatchFileWriter(
117 snapshotFileName.str(),
118 "solutions/solution-FVSolver",
119 tarch::plotter::griddata::blockstructured::PeanoTextPatchFileWriter::IndexFileMode::AppendNewData,
120 0.5 * (repositories::getMinTimeStamp() + repositories::getMaxTimeStamp())
123 auto dataWriter = writer.createCellDataWriter(
125 AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch,
126 AbstractFVSolver::NumberOfUnknowns,
131 dataWriter->setPrecision(PlotterPrecision);
133 for (
auto& marker : _cells) {
134 const int patchIndex = writer.plotPatch(marker.x() - marker.h() * 0.5, marker.h());
135 int cellIndex = dataWriter->getFirstCellWithinPatch(patchIndex);
138 dfor(k, AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch) {
139 double* data = QOut + currentDoF;
141 dataWriter->plotCell(cellIndex, data);
143 currentDoF += AbstractFVSolver::NumberOfUnknowns;
147 writer.writeToFile();
149 repositories::finishPlottingStep();
165 const double ratio = DomainSize[0] /
CellSize[0];
166 const int depth =
static_cast<int>(std::round(std::log(ratio) / std::log(3.0)));
167 dfore(volume, GridLength, axis, 0) {
168 tarch::la::Vector<DIMENSIONS, double> faceOffset =
CellSize / 2.0;
170 tarch::la::Vector<DIMENSIONS, double>
171 faceCenterLow = tarch::la::multiplyComponents(tarch::la::convertScalar<double>(volume),
CellSize) + faceOffset
174 faceCenterLow[axis] = DomainOffset[axis];
177 tarch::la::Vector<DIMENSIONS, double> faceCenterHigh = faceCenterLow;
178 faceCenterHigh[axis] = DomainSize[axis] - faceOffset[axis] + DomainOffset[axis];
180 faceCenterHigh[axis] = DomainSize[axis] + DomainOffset[axis];
184 ::exahype2::fv::applyBoundaryConditions<double>(
190 AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch,
192 AbstractFVSolver::NumberOfUnknowns + AbstractFVSolver::NumberOfAuxiliaryVariables,
199 ::exahype2::fv::applyBoundaryConditions<double>(
205 AbstractFVSolver::NumberOfFiniteVolumesPerAxisPerPatch,
207 AbstractFVSolver::NumberOfUnknowns + AbstractFVSolver::NumberOfAuxiliaryVariables,
284int main(
int argc,
char** argv) {
285 int returnCode = EXIT_SUCCESS;
290 benchmarks::exahype2::kernelbenchmarks::DomainOffset,
291 benchmarks::exahype2::kernelbenchmarks::DomainSize
294 repositories::initLogFilters();
295 repositories::startSimulation();
298 logInfo(
"main()",
"Created grid with " << _cells.size() <<
" cells");
300 logInfo(
"main()",
"Initialised grid");
305 ::exahype2::CellData<double, double, 3> patchData(_cells.size(), tarch::MemoryLocation::Pinned);
307 double* QInFlattened = tarch::allocateMemory<double>(
308 _cells.size() *
grid.getCellQReconstructedCardinality(),
309 tarch::MemoryLocation::Pinned
312 double* QOutFlattened = tarch::allocateMemory<double>(
313 _cells.size() *
grid.getCellQCardinality(),
314 tarch::MemoryLocation::Pinned
316 double* QOutFlattenedHost =
grid.getCellQ(0);
318 tarch::la::Vector<DIMENSIONS, double>* cellCentresHost =
new tarch::la::Vector<DIMENSIONS, double>[_cells.size()];
319 tarch::la::Vector<DIMENSIONS, double>* cellSizeHost =
new tarch::la::Vector<DIMENSIONS, double>[_cells.size()];
321 for (
int patchIndex = 0; patchIndex < _cells.size(); patchIndex++) {
322 cellCentresHost[patchIndex] = _cells[patchIndex].x();
323 cellSizeHost[patchIndex] = _cells[patchIndex].h();
324 for (
int type = 0; type < 3; type++) {
325 for (
int face = 0; face < TWO_TIMES_D; face++) {
326 patchData.faces[patchIndex][type][face] =
grid.getFaceQNewDevice(
327 _cells[patchIndex].x(),
328 _cells[patchIndex].h(),
334 tarch::copyTo<tarch::la::Vector<DIMENSIONS, double>, tarch::la::Vector<DIMENSIONS, double>>(
335 patchData.cellCentre,
338 tarch::MemoryLocation::Pinned
340 tarch::copyTo<tarch::la::Vector<DIMENSIONS, double>, tarch::la::Vector<DIMENSIONS, double>>(
344 tarch::MemoryLocation::Pinned
347 tarch::copyTo<double, double>(
350 _cells.size() *
grid.getCellQCardinality(),
351 tarch::MemoryLocation::Pinned
354 patchData.QOutFlattened = QOutFlattened;
355 patchData.QInFlattened = QInFlattened;
357 tarch::timing::Measurement measurement(1.0);
358 tarch::timing::Watch timeStepWatch(
"::",
"main()",
false);
360 double nextMinPlotTimeStamp = FirstPlotTimeStamp;
361 double nextMaxPlotTimeStamp = FirstPlotTimeStamp;
362 bool continueToSolve =
true;
364 while (continueToSolve) {
365 if (repositories::getMinTimeStamp() >= nextMinPlotTimeStamp
366 or repositories::getMaxTimeStamp() >= nextMaxPlotTimeStamp) {
367 if (repositories::getMinTimeStamp() >= nextMinPlotTimeStamp) {
368 nextMinPlotTimeStamp += TimeInBetweenPlots;
370 if (repositories::getMaxTimeStamp() >= nextMaxPlotTimeStamp) {
371 nextMaxPlotTimeStamp += TimeInBetweenPlots;
374 if constexpr (ShouldPlot) {
379 timeStepWatch.start();
382 grid.copyFacesToDevice();
385 patchData.dt = repositories::instanceOfFVSolver.getAdmissibleTimeStepSize();
386 repositories::startTimeStep();
388 tarch::timing::Watch watch(
"",
"",
false);
389 benchmarks::exahype2::kernelbenchmarks::tasks::FVSolverEnclaveTask::fuse(patchData);
391 measurement.setValue(watch.getCalendarTime());
393 timeStamp += repositories::instanceOfFVSolver.getAdmissibleTimeStepSize();
394 repositories::finishTimeStep();
396 tarch::copyFrom<double, double>(
399 _cells.size() *
grid.getCellQCardinality(),
400 tarch::MemoryLocation::Pinned
403 grid.copyFacesFromDevice();
404 timeStepWatch.stop();
408 repositories::printTimeStep(
false);
410 logInfo(
"main()",
"Average cell updates per second: " << _cells.size() / measurement.getValue());
412 printNextTimeStep += repositories::PrintTimeStepIntervalInSeconds;
415 if (repositories::getMinTimeStamp() >= MinTerminalTime and repositories::getMaxTimeStamp() >= MaxTerminalTime) {
416 continueToSolve =
false;
419 if (tarch::hasNonCriticalAssertionBeenViolated() and not haveReceivedNonCriticalAssertion) {
420 continueToSolve =
false;
421 haveReceivedNonCriticalAssertion =
true;
422 logError(
"main()",
"Noncritical assertion has been triggered in code. Dump final state and terminate.");
427 if constexpr (ShouldPlot) {
430 repositories::finishSimulation();
432 if (haveReceivedNonCriticalAssertion) {
433 logWarning(
"main()",
"Terminated gracefully after noncritical assertion");
434 returnCode = EXIT_FAILURE;
437 repositories::printTimeStep(
false);
438 logInfo(
"main()",
"Terminated successfully");
439 returnCode = EXIT_SUCCESS;
444 delete[] cellCentresHost;
445 delete[] cellSizeHost;
446 tarch::freeMemory(QOutFlattened, tarch::MemoryLocation::Pinned);
447 tarch::freeMemory(QInFlattened, tarch::MemoryLocation::Pinned);
const tarch::la::Vector< DIMENSIONS, double > CellSize
tarch::timing::Measurement timeStepMeasurement
tarch::logging::Log _log("::")
peano4::datamanagement::CellMarker createMarkerFromIndex(const tarch ::la ::Vector< DIMENSIONS, int > &index)
void applyBoundaryConditionsToAxis(int axis, double t, double dt)
int main(int argc, char **argv)
void invokeFVSolverBoundaryConditions(const double *NOALIAS Qinside, double *NOALIAS Qoutside, const tarch::la::Vector< DIMENSIONS, double > &x, const tarch::la::Vector< DIMENSIONS, double > &h, double t, double dt, int normal)