Peano
Loading...
Searching...
No Matches
ccz4-main.cpp
Go to the documentation of this file.
1// **********************************************************************************************
2// This file is modifed from the original version generated by exahype2.
3// You are free to change the content here, but do not delete it or the
4// auto-generated main file will disable the additional step and causing compiling errors.
5// in some circumstance.
6// **********************************************************************************************
7
8#include <iomanip>
9
10#include "Constants.h"
11#include "ccz4-main.h"
12#include "exahype2/UnitTests.h"
13#include "exahype2/UserInterface.h"
14#include "observers/CreateGrid.h"
15#include "observers/CreateGridAndConvergeLoadBalancing.h"
16#include "observers/CreateGridButPostponeRefinement.h"
17#include "observers/InitGrid.h"
18#include "observers/PlotSolution.h"
19#include "observers/CheckpointSolution.h"
20#include "observers/TimeStep.h"
21#include "peano4/peano4.h"
22#include "peano4/UnitTests.h"
23#include "repositories/DataRepository.h"
24#include "repositories/SolverRepository.h"
25#include "repositories/StepRepository.h"
26#include "tarch/UnitTests.h"
27#include "peano4/grid/Spacetree.h"
28#include "peano4/parallel/SpacetreeSet.h"
29#include "tarch/logging/Log.h"
30#include "tarch/logging/LogFilter.h"
31#include "tarch/logging/Statistics.h"
32#include "tarch/multicore/Core.h"
33#include "tarch/multicore/multicore.h"
34#include "tarch/NonCriticalAssertions.h"
35#include "tarch/tests/TreeTestCaseCollection.h"
36#include "tarch/timing/Measurement.h"
37#include "tarch/timing/Watch.h"
38#include "toolbox/blockstructured/UnitTests.h"
39#include "toolbox/loadbalancing/loadbalancing.h"
40
42#if defined(USE_ADDITIONAL_MESH_TRAVERSAL)
43 #include "observers/AdditionalMeshTraversal.h"
44#endif
46
47using namespace applications::exahype2::ccz4;
48
49tarch::logging::Log _log("::");
50
51
52tarch::timing::Measurement timePerMeshSweepMeasurement;
53tarch::timing::Measurement gridConstructionMeasurement;
54tarch::timing::Measurement timeStepMeasurement;
55tarch::timing::Measurement plotMeasurement;
56
57
67 static bool gridConstructed = false;
68 static bool gridInitialised = false;
69 static bool gridBalanced = false;
70 static double nextMaxPlotTimeStamp = FirstPlotTimeStamp;
71 static double nextMinPlotTimeStamp = FirstPlotTimeStamp;
72 static double nextMaxCheckpointTimeStamp = FirstCheckpointTimeStamp;
73 static double nextMinCheckpointTimeStamp = FirstCheckpointTimeStamp;
74 static bool haveJustWrittenSnapshot = false;
75 static bool haveReceivedNoncriticialAssertion = false;
76 static bool addGridSweepWithoutGridRefinementNext = false;
77 static tarch::la::Vector<DIMENSIONS, double> minH = tarch::la::Vector<DIMENSIONS, double>(
78 std::numeric_limits<double>::max()
79 );
80 static int globalNumberOfTrees = 0;
81 bool continueToSolve = true;
82
83 if (tarch::hasNonCriticalAssertionBeenViolated() and not haveReceivedNoncriticialAssertion) {
84 peano4::parallel::Node::getInstance().setNextProgramStep(
85 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::PlotSolution)
86 );
87 haveReceivedNoncriticialAssertion = true;
88 logError(
89 "selectNextAlgorithmicStep()", "non-critical assertion has been triggered in code. Dump final state and terminate"
90 );
91 } else if (tarch::hasNonCriticalAssertionBeenViolated()) {
92 continueToSolve = false;
93 } else if (gridConstructed and not gridBalanced) {
94 if (not repositories::loadBalancer.isEnabled(true) and not repositories::loadBalancer.hasSplitRecently()) {
95 logInfo("selectNextAlgorithmicStep()", "all ranks have switched off their load balancing");
96 gridBalanced = true;
97 } else {
98 logInfo(
99 "selectNextAlgorithmicStep()", "wait for load balancing to become stable: " << repositories::loadBalancer
100 );
101 }
102
103 peano4::parallel::Node::getInstance().setNextProgramStep(repositories::StepRepository::toProgramStep(
104 repositories::StepRepository::Steps::CreateGridAndConvergeLoadBalancing
105 ));
106 } else if (gridBalanced and not gridInitialised) {
107 peano4::parallel::Node::getInstance().setNextProgramStep(
108 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::InitGrid)
109 );
110
111 gridInitialised = true;
112 } else if (not gridConstructed) {
113 if (tarch::la::max(peano4::parallel::SpacetreeSet::getInstance().getGridStatistics().getMinH()) < tarch::la::max(minH)) {
114 minH = peano4::parallel::SpacetreeSet::getInstance().getGridStatistics().getMinH();
115 logDebug(
116 "selectNextAlgorithmicStep()", "mesh has refined, so reset minH=" << minH << " and postpone further refinement"
117 );
118 addGridSweepWithoutGridRefinementNext = true;
119 } else if (repositories::loadBalancer.getGlobalNumberOfTrees() > globalNumberOfTrees) {
120 logInfo("selectNextAlgorithmicStep()", "mesh has rebalanced recently, so postpone further refinement)");
121 addGridSweepWithoutGridRefinementNext = true;
122 globalNumberOfTrees = repositories::loadBalancer.getGlobalNumberOfTrees();
123 }
124 else if (
125 peano4::parallel::SpacetreeSet::getInstance().getGridStatistics().getStationarySweeps()>5
126 and
127 // ensure that a proper creation has been ran before, so the mesh had the opportunity
128 // to refine further if it has not done yet
129 repositories::StepRepository::toStepEnum( peano4::parallel::Node::getInstance().getCurrentProgramStep() ) == repositories::StepRepository::Steps::CreateGrid
130 ) {
131 logInfo(
132 "selectNextAlgorithmicStep()", "grid has been stationary for quite some time. Terminate grid construction"
133 );
134 addGridSweepWithoutGridRefinementNext = false;
135 gridConstructed = true;
136 } else {
137 logInfo(
138 "selectNextAlgorithmicStep()",
139 "mesh rebalancing seems to be stationary, so study whether to refine mesh further in next sweep: "
140 << peano4::parallel::SpacetreeSet::getInstance().getGridStatistics().toString()
141 );
142 addGridSweepWithoutGridRefinementNext = false;
143 globalNumberOfTrees = repositories::loadBalancer.getGlobalNumberOfTrees();
144 }
145
146 // Actual grid traversal choice
147 if (addGridSweepWithoutGridRefinementNext) {
148 peano4::parallel::Node::getInstance().setNextProgramStep(repositories::StepRepository::toProgramStep(
149 repositories::StepRepository::Steps::CreateGridButPostponeRefinement
150 ));
151 } else {
152 peano4::parallel::Node::getInstance().setNextProgramStep(
153 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::CreateGrid)
154 );
155 }
156
157 continueToSolve = true;
158 } else {
159 if (TimeInBetweenPlots > 0.0 and repositories::getMinTimeStamp() < MinTerminalTime and repositories::getMaxTimeStamp() < MaxTerminalTime and (repositories::getMinTimeStamp() >= nextMinPlotTimeStamp or repositories::getMaxTimeStamp() >= nextMaxPlotTimeStamp) and repositories::mayPlot()) {
160 if (repositories::getMinTimeStamp() >= nextMinPlotTimeStamp) {
161 nextMinPlotTimeStamp += TimeInBetweenPlots;
162 }
163 if (repositories::getMaxTimeStamp() >= nextMaxPlotTimeStamp) {
164 nextMaxPlotTimeStamp += TimeInBetweenPlots;
165 }
166
167 if (nextMinPlotTimeStamp < repositories::getMinTimeStamp()) {
168 logWarning(
169 "selectNextAlgorithmicStep()",
170 "code is asked to plot every dt="
171 << TimeInBetweenPlots << ", but this seems to be less than the time step size of the solvers. "
172 << "So postpone next plot to t=" << (repositories::getMinTimeStamp() + TimeInBetweenPlots)
173 );
174 nextMinPlotTimeStamp = repositories::getMinTimeStamp() + TimeInBetweenPlots;
175 } else if (nextMaxPlotTimeStamp < repositories::getMaxTimeStamp()) {
176 logWarning(
177 "selectNextAlgorithmicStep()",
178 "code is asked to plot every dt="
179 << TimeInBetweenPlots << ", but this seems to be less than the time step size of the solvers. "
180 << "So postpone next plot to t=" << (repositories::getMaxTimeStamp() + TimeInBetweenPlots)
181 );
182 nextMaxPlotTimeStamp = repositories::getMaxTimeStamp() + TimeInBetweenPlots;
183 }
184
185 nextMaxPlotTimeStamp = std::max(nextMaxPlotTimeStamp, nextMinPlotTimeStamp);
186
187 peano4::parallel::Node::getInstance().setNextProgramStep(
188 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::PlotSolution)
189 );
190 haveJustWrittenSnapshot = true;
191 continueToSolve = true;
192 } else if (TimeInBetweenCheckpoints > 0.0 and repositories::getMinTimeStamp() < MinTerminalTime and repositories::getMaxTimeStamp() < MaxTerminalTime and (repositories::getMinTimeStamp() >= nextMinCheckpointTimeStamp or repositories::getMaxTimeStamp() >= nextMaxCheckpointTimeStamp) and repositories::mayPlot()) {
193 if (repositories::getMinTimeStamp() >= nextMinCheckpointTimeStamp) {
194 nextMinCheckpointTimeStamp += TimeInBetweenCheckpoints;
195 }
196 if (repositories::getMaxTimeStamp() >= nextMaxCheckpointTimeStamp) {
197 nextMaxCheckpointTimeStamp += TimeInBetweenCheckpoints;
198 }
199
200 if (nextMinCheckpointTimeStamp < repositories::getMinTimeStamp()) {
201 logWarning(
202 "selectNextAlgorithmicStep()",
203 "code is asked to Checkpoint every dt="
204 << TimeInBetweenCheckpoints << ", but this seems to be less than the time step size of the solvers. "
205 << "So postpone next Checkpoint to t=" << (repositories::getMinTimeStamp() + TimeInBetweenCheckpoints)
206 );
207 nextMinCheckpointTimeStamp = repositories::getMinTimeStamp() + TimeInBetweenCheckpoints;
208 } else if (nextMaxCheckpointTimeStamp < repositories::getMaxTimeStamp()) {
209 logWarning(
210 "selectNextAlgorithmicStep()",
211 "code is asked to Checkpoint every dt="
212 << TimeInBetweenCheckpoints << ", but this seems to be less than the time step size of the solvers. "
213 << "So postpone next Checkpoint to t=" << (repositories::getMaxTimeStamp() + TimeInBetweenCheckpoints)
214 );
215 nextMaxCheckpointTimeStamp = repositories::getMaxTimeStamp() + TimeInBetweenCheckpoints;
216 }
217
218 nextMaxCheckpointTimeStamp = std::max(nextMaxCheckpointTimeStamp, nextMinCheckpointTimeStamp);
219
220 peano4::parallel::Node::getInstance().setNextProgramStep(
221 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::CheckpointSolution)
222 );
223 haveJustWrittenSnapshot = true;
224 continueToSolve = true;
225 } else if (repositories::getMinTimeStamp() < MinTerminalTime and repositories::getMaxTimeStamp() < MaxTerminalTime) {
226 peano4::parallel::Node::getInstance().setNextProgramStep(
227 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::TimeStep)
228 );
229 continueToSolve = true;
230 haveJustWrittenSnapshot = false;
231 } else {
232 if (not haveJustWrittenSnapshot and TimeInBetweenPlots > 0.0 and repositories::mayPlot()) {
233 peano4::parallel::Node::getInstance().setNextProgramStep(
234 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::PlotSolution)
235 );
236 continueToSolve = true; // don't want to terminate immediately
237 haveJustWrittenSnapshot = true;
238 nextMinPlotTimeStamp = std::numeric_limits<double>::max();
239 nextMaxPlotTimeStamp = std::numeric_limits<double>::max();
240 } else if (not haveJustWrittenSnapshot and TimeInBetweenPlots > 0.0 and not repositories::mayPlot()) {
241 continueToSolve = true; // don't want to terminate immediately but to wait for incomplete time steps to complete
242 } else {
243 continueToSolve = false;
244 }
245 }
246 }
247
248 return continueToSolve;
249}
250
251
252void step() {
253 int stepIdentifier = peano4::parallel::Node::getInstance().getCurrentProgramStep();
254 auto stepName = repositories::StepRepository::toStepEnum(stepIdentifier);
255
256 static tarch::logging::Log _log("");
257#if PEANO_DEBUG > 0
258#else
259 if (tarch::mpi::Rank::getInstance().isGlobalMaster())
260#endif
261 logInfo("step()", "Starting AlgorithmicStep [" << repositories::StepRepository::toString(stepName)<<"]" );
262
263 static tarch::timing::Watch watch("::", "step()", false);
264
265 static int creepingNumberOfLocalCells = 0;
266
267 switch (stepName) {
268 case repositories::StepRepository::Steps::CreateGridButPostponeRefinement: {
269 tarch::logging::LogFilter::getInstance().switchProgramPhase("create-grid-but-postpone-refinement");
270
271 repositories::startGridConstructionStep();
272
273 observers::CreateGridButPostponeRefinement observer;
274 watch.start();
275 peano4::parallel::SpacetreeSet::getInstance().traverse(observer);
276 watch.stop();
277 gridConstructionMeasurement.setValue(watch.getCalendarTime());
278
279 repositories::finishGridConstructionStep();
280 } break;
281 case repositories::StepRepository::Steps::CreateGrid: {
282 tarch::logging::LogFilter::getInstance().switchProgramPhase("create-grid");
283
284 repositories::startGridConstructionStep();
285
286 observers::CreateGrid observer;
287 watch.start();
288 peano4::parallel::SpacetreeSet::getInstance().traverse(observer);
289 watch.stop();
290 gridConstructionMeasurement.setValue(watch.getCalendarTime());
291
292 repositories::finishGridConstructionStep();
293
294 // We always overestimate so give the convergence the opportunity to catch up. The constant
295 // here is a magic one.
296 creepingNumberOfLocalCells = ::toolbox::loadbalancing::getWeightOfHeaviestLocalSpacetree()
297 + tarch::multicore::Core::getInstance().getNumberOfThreads() * 3;
298 } break;
299 case repositories::StepRepository::Steps::CreateGridAndConvergeLoadBalancing: {
300 if (creepingNumberOfLocalCells < ::toolbox::loadbalancing::getWeightOfHeaviestLocalSpacetree() - 1) {
301 logInfo(
302 "step()",
303 "it seems the grid has just refined before we switched to the phase where we make the load balancing converge. Wait for a few iterations more to give load balancing chance to catch up"
304 );
305 creepingNumberOfLocalCells = ::toolbox::loadbalancing::getWeightOfHeaviestLocalSpacetree()
306 + tarch::multicore::Core::getInstance().getNumberOfThreads() * 3;
307 }
308
309 tarch::logging::LogFilter::getInstance().switchProgramPhase("create-grid-and-converge-load-balancing");
310
311 // The smaller here corresponds to the -1 below
312 if (::toolbox::loadbalancing::getWeightOfHeaviestLocalSpacetree() < 0 and repositories::loadBalancer.isEnabled(false)) {
313 logInfo("step()", "rank is degenerated so disable load balancing temporarily");
314 repositories::loadBalancer.enable(false);
315 }
316 if (
317 ::toolbox::loadbalancing::getWeightOfHeaviestLocalSpacetree() >= creepingNumberOfLocalCells
318 and
319 repositories::loadBalancer.isEnabled(false)
320 ) {
321 logInfo(
322 "step()",
323 "grid construction and decomposition on this rank seem to be stable as we have around "
324 << creepingNumberOfLocalCells << " local cells in the heaviest tree. Disable load balancing temporarily"
325 );
326 repositories::loadBalancer.enable(false);
327 }
328
329 repositories::startGridConstructionStep();
330
331 observers::CreateGridButPostponeRefinement observer;
332 watch.start();
333 peano4::parallel::SpacetreeSet::getInstance().traverse(observer);
334 watch.stop();
335 gridConstructionMeasurement.setValue(watch.getCalendarTime());
336
337 repositories::finishGridConstructionStep();
338
339 if (
340 ::toolbox::loadbalancing::getWeightOfHeaviestLocalSpacetree() <= creepingNumberOfLocalCells
341 and
342 not repositories::loadBalancer.hasSplitRecently()
343 and
344 repositories::loadBalancer.isEnabled(false)
345 ) {
346 logInfo(
347 "step()",
348 "have to decrement local cell counter "
349 << creepingNumberOfLocalCells << " as maximum weight is "
350 << ::toolbox::loadbalancing::getWeightOfHeaviestLocalSpacetree()
351 );
352 creepingNumberOfLocalCells = (creepingNumberOfLocalCells
353 + ::toolbox::loadbalancing::getWeightOfHeaviestLocalSpacetree())
354 / 2;
355 }
356 } break;
357 case repositories::StepRepository::Steps::InitGrid: {
358 tarch::logging::LogFilter::getInstance().switchProgramPhase("init-grid");
359 repositories::loadBalancer.enable(false);
360
361 repositories::startGridInitialisationStep();
362
363 observers::InitGrid observer;
364 observers::InitGrid::prepareTraversal();
365 watch.start();
366 peano4::parallel::SpacetreeSet::getInstance().traverse(observer);
367 watch.stop();
368 observers::InitGrid::unprepareTraversal();
369 gridConstructionMeasurement.setValue(watch.getCalendarTime());
370
371 repositories::finishGridInitialisationStep();
372 } break;
373 case repositories::StepRepository::Steps::PlotSolution: {
374 tarch::logging::LogFilter::getInstance().switchProgramPhase("plot-solution");
375 const double minTimeStamp = repositories::getMinTimeStamp();
376 const double maxTimeStamp = repositories::getMaxTimeStamp();
377 const double minTimeStepSize = repositories::getMinTimeStepSize();
378 const double maxTimeStepSize = repositories::getMaxTimeStepSize();
379
380 repositories::startPlottingStep(minTimeStamp, maxTimeStamp, minTimeStepSize, maxTimeStepSize);
381
382 observers::PlotSolution observer;
383 observers::PlotSolution::prepareTraversal();
384 watch.start();
385 peano4::parallel::SpacetreeSet::getInstance().traverse(observer);
386 watch.stop();
387 observers::PlotSolution::unprepareTraversal();
388 plotMeasurement.setValue(watch.getCalendarTime());
389
390 repositories::finishPlottingStep();
391 } break;
392 case repositories::StepRepository::Steps::CheckpointSolution: {
393 tarch::logging::LogFilter::getInstance().switchProgramPhase("Checkpoint-solution");
394 const double minTimeStamp = repositories::getMinTimeStamp();
395 const double maxTimeStamp = repositories::getMaxTimeStamp();
396 const double minTimeStepSize = repositories::getMinTimeStepSize();
397 const double maxTimeStepSize = repositories::getMaxTimeStepSize();
398
399 repositories::startPlottingStep(minTimeStamp, maxTimeStamp, minTimeStepSize, maxTimeStepSize);
400
401 observers::CheckpointSolution observer;
402 observers::CheckpointSolution::prepareTraversal();
403 watch.start();
404 peano4::parallel::SpacetreeSet::getInstance().traverse(observer);
405 watch.stop();
406 observers::CheckpointSolution::unprepareTraversal();
407 plotMeasurement.setValue(watch.getCalendarTime());
408
409 repositories::finishPlottingStep();
410 } break;
411 case repositories::StepRepository::Steps::TimeStep: {
412 tarch::logging::LogFilter::getInstance().switchProgramPhase("time-step");
413 if (repositories::loadBalancer.isEnabled(false)) {
414 logInfo("step()", "disable load balancing throughout initialisation (to be removed in later releases)");
415 repositories::loadBalancer.enable(false);
416 }
417
418 const double minTimeStamp = repositories::getMinTimeStamp();
419 const double maxTimeStamp = repositories::getMaxTimeStamp();
420 const double minTimeStepSize = repositories::getMinTimeStepSize();
421 const double maxTimeStepSize = repositories::getMaxTimeStepSize();
422 const double minMeshSize = repositories::getMinMeshSize();
423 const double maxMeshSize = repositories::getMaxMeshSize();
424
425 repositories::startTimeStep(minTimeStamp, maxTimeStamp, minTimeStepSize, maxTimeStepSize);
426
427 observers::TimeStep observer;
428 observers::TimeStep::prepareTraversal();
429 watch.start();
430 peano4::parallel::SpacetreeSet::getInstance().traverse(observer);
431 watch.stop();
432 observers::TimeStep::unprepareTraversal();
433 timeStepMeasurement.setValue(watch.getCalendarTime());
434
435 repositories::finishTimeStep();
436 } break;
438 #if defined(USE_ADDITIONAL_MESH_TRAVERSAL)
439 case repositories::StepRepository::Steps::AdditionalMeshTraversal:
440 {
441 tarch::logging::LogFilter::getInstance().switchProgramPhase( "additional-MeshTraversal" );
442
443 repositories::suspendSolversForOneGridSweep();
444 observers::AdditionalMeshTraversal observer;
445 observers::AdditionalMeshTraversal::prepareTraversal();
446 peano4::parallel::SpacetreeSet::getInstance().traverse(observer);
447 observers::AdditionalMeshTraversal::unprepareTraversal();
448 }
449 break;
450 #endif
452 case repositories::StepRepository::Steps::Undef:
453 assertion(false);
454 break;
455 }
456
457#if PEANO_DEBUG > 0
458#else
459 if (tarch::mpi::Rank::getInstance().isGlobalMaster())
460#endif
461 logInfo("step()", "Finishing [" << repositories::StepRepository::toString(stepName) << "] Current SolverState [" << AbstractCCZ4::toString(repositories::instanceOfCCZ4.getSolverState())<<"]" );
462}
463
464int main(int argc, char** argv) {
465 constexpr int ExitCodeSuccess = 0;
466 constexpr int ExitCodeUnitTestsFailed = 1;
467 constexpr int ExitCodeInvalidArguments = 2;
468 constexpr int ExitCodeInvalidBuild = 3;
469
470 static tarch::timing::Watch watch("::", "main()", false);
471
472 peano4::initParallelEnvironment(&argc, &argv);
473
474 // Do this early, so people can use logInfo properly.
475 repositories::initLogFilters();
476
477 tarch::initNonCriticalAssertionEnvironment();
478 peano4::fillLookupTables();
479
480 peano4::initSingletons(DomainOffset, DomainSize, PeriodicBC);
481
482 repositories::initSharedMemoryAndGPUEnvironment();
483
484 if (tarch::mpi::Rank::getInstance().getNumberOfRanks() > 1 and tarch::multicore::Core::getInstance().getNumberOfThreads() <= 1) {
485 logError("main()", "MPI runs without multithreading are not supported currently.");
486 return ExitCodeInvalidBuild;
487 }
488
489 repositories::DataRepository::initDatatypes();
490
491 #if PEANO_DEBUG >= 2
492 tarch::tests::TreeTestCaseCollection* unitTests = new tarch::tests::TreeTestCaseCollection();
493 unitTests->addTestCase(peano4::getUnitTests());
494 unitTests->addTestCase(tarch::getUnitTests());
495 unitTests->addTestCase(toolbox::blockstructured::getUnitTests());
496 unitTests->addTestCase(exahype2::getUnitTests());
497 unitTests->run();
498 if (unitTests->getNumberOfErrors() != 0) {
499 logError("main()", "unit tests failed. Quit.");
500 tarch::mpi::Rank::abort(ExitCodeUnitTestsFailed);
501 }
502 delete unitTests;
503#endif
504
505 repositories::startSimulation();
506
507 tarch::logging::Statistics::getInstance().clear();
508
509#if defined(WITH_OPENMP)
510#pragma omp parallel
511 {
512#pragma omp master
513 {
514#endif
515
516 const bool isGlobalMaster = tarch::mpi::Rank::getInstance().isGlobalMaster();
517 const bool isPeanoComputeNode = not tarch::mpi::Rank::getInstance().isGlobalMaster();
518
519 if (isGlobalMaster) {
520 while (selectNextAlgorithmicStep()) {
521 watch.start();
522 step();
523 watch.stop();
524
525 timePerMeshSweepMeasurement.setValue(watch.getCalendarTime());
526 logInfo("main()", "time per mesh sweep (current/average): " << std::fixed << std::setprecision(2) << watch.getCalendarTime() << " / " << timePerMeshSweepMeasurement.getValue() );
527 }
528
529 logInfo("main()", "terminated successfully");
530 logInfo(
531 "main()",
532 "initial grid construction: " << gridConstructionMeasurement.getAccumulatedValue(
533 ) << "s\t" << gridConstructionMeasurement.toString()
534 );
535 logInfo(
536 "main()",
537 "plotting: " << plotMeasurement.getAccumulatedValue() << "s\t" << plotMeasurement.toString()
538 );
539 logInfo(
540 "main()",
541 "time stepping: " << timeStepMeasurement.getAccumulatedValue(
542 ) << "s\t" << timeStepMeasurement.toString()
543 );
544 logInfo(
545 "main()",
546 "average time per mesh sweep: " << timePerMeshSweepMeasurement.getValue() << "\t" << timePerMeshSweepMeasurement.toString()
547 );
548 } else if (isPeanoComputeNode) {
549 while (peano4::parallel::Node::getInstance().continueToRun()) {
550 step();
551 }
552 }
553#if defined(WITH_OPENMP)
554 }
555 }
556#endif
557
558 tarch::logging::Statistics::getInstance().writeToCSV();
559
560 repositories::finishSimulation();
561
562 peano4::shutdownSingletons();
563 repositories::DataRepository::shutdownDatatypes();
564 tarch::shutdownNonCriticalAssertionEnvironment();
565 peano4::shutdownParallelEnvironment();
566
567 return ExitCodeSuccess;
568}
int main(int argc, char **argv)
bool selectNextAlgorithmicStep()
Decide which step to run next.
Definition ccz4-main.cpp:66
void step()
tarch::logging::Log _log("::")
tarch::timing::Measurement gridConstructionMeasurement
Definition ccz4-main.cpp:57
tarch::timing::Measurement timePerMeshSweepMeasurement
Definition ccz4-main.cpp:56
tarch::timing::Measurement timeStepMeasurement
Definition ccz4-main.cpp:58
tarch::timing::Measurement plotMeasurement
Definition ccz4-main.cpp:59