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 "config.h"
11#include "Constants.h"
12#include "ccz4-main.h"
13#include "exahype2/UnitTests.h"
15#include "observers/CreateGrid.h"
16#include "observers/CreateGridAndConvergeLoadBalancing.h"
17#include "observers/CreateGridButPostponeRefinement.h"
18#include "observers/InitGrid.h"
19#include "observers/PlotSolution.h"
20#include "observers/TimeStep.h"
21#include "peano4/peano.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"
29#include "tarch/logging/Log.h"
38#include "tarch/timing/Watch.h"
41
43#if defined(USE_ADDITIONAL_MESH_TRAVERSAL)
44 #include "observers/AdditionalMeshTraversal.h"
45#endif
47
48using namespace applications::exahype2::ccz4;
49
51
52
57
58
68 static bool gridConstructed = false;
69 static bool gridInitialised = false;
70 static bool gridBalanced = false;
71 static double nextMaxPlotTimeStamp = FirstPlotTimeStamp;
72 static double nextMinPlotTimeStamp = FirstPlotTimeStamp;
73 static bool haveJustWrittenSnapshot = false;
74 static bool haveReceivedNoncriticialAssertion = false;
75 static bool addGridSweepWithoutGridRefinementNext = false;
77 std::numeric_limits<double>::max()
78 );
79 static int globalNumberOfTrees = 0;
80 bool continueToSolve = true;
81
82 if (tarch::hasNonCriticalAssertionBeenViolated() and not haveReceivedNoncriticialAssertion) {
84 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::PlotSolution)
85 );
86 haveReceivedNoncriticialAssertion = true;
88 "selectNextAlgorithmicStep()", "non-critical assertion has been triggered in code. Dump final state and terminate"
89 );
91 continueToSolve = false;
92 } else if (gridConstructed and not gridBalanced) {
93 if (not repositories::loadBalancer.isEnabled(true) and not repositories::loadBalancer.hasSplitRecently()) {
94 logInfo("selectNextAlgorithmicStep()", "all ranks have switched off their load balancing");
95 gridBalanced = true;
96 } else {
97 logInfo(
98 "selectNextAlgorithmicStep()", "wait for load balancing to become stable: " << repositories::loadBalancer
99 );
100 }
101
102 peano4::parallel::Node::getInstance().setNextProgramStep(repositories::StepRepository::toProgramStep(
103 repositories::StepRepository::Steps::CreateGridAndConvergeLoadBalancing
104 ));
105 } else if (gridBalanced and not gridInitialised) {
107 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::InitGrid)
108 );
109
110 gridInitialised = true;
111 } else if (not gridConstructed) {
112 if (tarch::la::max(peano4::parallel::SpacetreeSet::getInstance().getGridStatistics().getMinH()) < tarch::la::max(minH)) {
114 logDebug(
115 "selectNextAlgorithmicStep()", "mesh has refined, so reset minH=" << minH << " and postpone further refinement"
116 );
117 addGridSweepWithoutGridRefinementNext = true;
118 } else if (repositories::loadBalancer.getGlobalNumberOfTrees() > globalNumberOfTrees) {
119 logInfo("selectNextAlgorithmicStep()", "mesh has rebalanced recently, so postpone further refinement)");
120 addGridSweepWithoutGridRefinementNext = true;
121 globalNumberOfTrees = repositories::loadBalancer.getGlobalNumberOfTrees();
122 }
123 else if (
124 peano4::parallel::SpacetreeSet::getInstance().getGridStatistics().getStationarySweeps()>5
125 and
126 // ensure that a proper creation has been ran before, so the mesh had the opportunity
127 // to refine further if it has not done yet
128 repositories::StepRepository::toStepEnum( peano4::parallel::Node::getInstance().getCurrentProgramStep() ) == repositories::StepRepository::Steps::CreateGrid
129 ) {
130 logInfo(
131 "selectNextAlgorithmicStep()", "grid has been stationary for quite some time. Terminate grid construction"
132 );
133 addGridSweepWithoutGridRefinementNext = false;
134 gridConstructed = true;
135 } else {
136 logInfo(
137 "selectNextAlgorithmicStep()",
138 "mesh rebalancing seems to be stationary, so study whether to refine mesh further in next sweep: "
140 );
141 addGridSweepWithoutGridRefinementNext = false;
142 globalNumberOfTrees = repositories::loadBalancer.getGlobalNumberOfTrees();
143 }
144
145 // Actual grid traversal choice
146 if (addGridSweepWithoutGridRefinementNext) {
147 peano4::parallel::Node::getInstance().setNextProgramStep(repositories::StepRepository::toProgramStep(
148 repositories::StepRepository::Steps::CreateGridButPostponeRefinement
149 ));
150 } else {
152 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::CreateGrid)
153 );
154 }
155
156 continueToSolve = true;
157 } else {
159 #if defined(USE_ADDITIONAL_MESH_TRAVERSAL)
160 if (
161 repositories::isLastGridSweepOfTimeStep()
162 and
163 repositories::StepRepository::toStepEnum( peano4::parallel::Node::getInstance().getCurrentProgramStep() ) != repositories::StepRepository::Steps::AdditionalMeshTraversal
164 ) {
166 repositories::StepRepository::toProgramStep( repositories::StepRepository::Steps::AdditionalMeshTraversal )
167 );
168 continueToSolve = true;
169 } else
170 #endif
172 if (TimeInBetweenPlots > 0.0 and repositories::getMinTimeStamp() < MinTerminalTime and repositories::getMaxTimeStamp() < MaxTerminalTime and (repositories::getMinTimeStamp() >= nextMinPlotTimeStamp or repositories::getMaxTimeStamp() >= nextMaxPlotTimeStamp) and repositories::mayPlot()) {
173 if (repositories::getMinTimeStamp() >= nextMinPlotTimeStamp) {
174 nextMinPlotTimeStamp += TimeInBetweenPlots;
175 }
176 if (repositories::getMaxTimeStamp() >= nextMaxPlotTimeStamp) {
177 nextMaxPlotTimeStamp += TimeInBetweenPlots;
178 }
179
180 if (nextMinPlotTimeStamp < repositories::getMinTimeStamp()) {
182 "selectNextAlgorithmicStep()",
183 "code is asked to plot every dt="
184 << TimeInBetweenPlots << ", but this seems to be less than the time step size of the solvers. "
185 << "So postpone next plot to t=" << (repositories::getMinTimeStamp() + TimeInBetweenPlots)
186 );
187 nextMinPlotTimeStamp = repositories::getMinTimeStamp() + TimeInBetweenPlots;
188 } else if (nextMaxPlotTimeStamp < repositories::getMaxTimeStamp()) {
190 "selectNextAlgorithmicStep()",
191 "code is asked to plot every dt="
192 << TimeInBetweenPlots << ", but this seems to be less than the time step size of the solvers. "
193 << "So postpone next plot to t=" << (repositories::getMaxTimeStamp() + TimeInBetweenPlots)
194 );
195 nextMaxPlotTimeStamp = repositories::getMaxTimeStamp() + TimeInBetweenPlots;
196 }
197
198 nextMaxPlotTimeStamp = std::max(nextMaxPlotTimeStamp, nextMinPlotTimeStamp);
199
201 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::PlotSolution)
202 );
203 haveJustWrittenSnapshot = true;
204 continueToSolve = true;
205 } else if (repositories::getMinTimeStamp() < MinTerminalTime and repositories::getMaxTimeStamp() < MaxTerminalTime) {
207 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::TimeStep)
208 );
209 continueToSolve = true;
210 haveJustWrittenSnapshot = false;
211 } else {
212 if (not haveJustWrittenSnapshot and TimeInBetweenPlots > 0.0 and repositories::mayPlot()) {
214 repositories::StepRepository::toProgramStep(repositories::StepRepository::Steps::PlotSolution)
215 );
216 continueToSolve = true; // don't want to terminate immediately
217 haveJustWrittenSnapshot = true;
218 nextMinPlotTimeStamp = std::numeric_limits<double>::max();
219 nextMaxPlotTimeStamp = std::numeric_limits<double>::max();
220 } else if (not haveJustWrittenSnapshot and TimeInBetweenPlots > 0.0 and not repositories::mayPlot()) {
221 continueToSolve = true; // don't want to terminate immediately but to wait for incomplete time steps to complete
222 } else {
223 continueToSolve = false;
224 }
225 }
226 }
227
228 return continueToSolve;
229}
230
231
232void step() {
234 auto stepName = repositories::StepRepository::toStepEnum(stepIdentifier);
235
236 static tarch::logging::Log _log("");
237#if PeanoDebug > 0
238#else
239 if (tarch::mpi::Rank::getInstance().isGlobalMaster())
240#endif
241 logInfo("step()", "run " << repositories::StepRepository::toString(stepName) << "\t" << applications::exahype2::ccz4::AbstractCCZ4::toString(repositories::instanceOfCCZ4.getSolverState()));
242
243 static tarch::timing::Watch watch("::", "step()", false);
244
245 static int creepingNumberOfLocalCells = 0;
246
247 switch (stepName) {
248 case repositories::StepRepository::Steps::CreateGridButPostponeRefinement: {
249 tarch::logging::LogFilter::getInstance().switchProgramPhase("create-grid-but-postpone-refinement");
250
252
253 repositories::startGridConstructionStep();
254
255 OTTER_DEFINE_TASK(step_task, OTTER_NULL_TASK, otter_no_add_to_pool, otter::label::step);
256 OTTER_TASK_START(step_task);
257
258 observers::CreateGridButPostponeRefinement observer;
259 watch.start();
261 watch.stop();
263
264 OTTER_TASK_WAIT_IMPLICIT(children);
266 OTTER_TASK_WAIT_IMPLICIT(descendants);
267
268 repositories::finishGridConstructionStep();
269 } break;
270 case repositories::StepRepository::Steps::CreateGrid: {
272
274
275 repositories::startGridConstructionStep();
276
277 OTTER_DEFINE_TASK(step_task, OTTER_NULL_TASK, otter_no_add_to_pool, otter::label::step);
278 OTTER_TASK_START(step_task);
279
280 observers::CreateGrid observer;
281 watch.start();
283 watch.stop();
285
286 OTTER_TASK_WAIT_IMPLICIT(children);
288 OTTER_TASK_WAIT_IMPLICIT(descendants);
289
290 repositories::finishGridConstructionStep();
291
292 // We always overestimate so give the convergence the opportunity to catch up. The constant
293 // here is a magic one.
296 } break;
297 case repositories::StepRepository::Steps::CreateGridAndConvergeLoadBalancing: {
298 if (creepingNumberOfLocalCells < ::toolbox::loadbalancing::getWeightOfHeaviestLocalSpacetree() - 1) {
299 logInfo(
300 "step()",
301 "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"
302 );
305 }
306
307 tarch::logging::LogFilter::getInstance().switchProgramPhase("create-grid-and-converge-load-balancing");
308
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 (
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 OTTER_DEFINE_TASK(step_task, OTTER_NULL_TASK, otter_no_add_to_pool, otter::label::step);
332 OTTER_TASK_START(step_task);
333
334 observers::CreateGridButPostponeRefinement observer;
335 watch.start();
337 watch.stop();
339
340 OTTER_TASK_WAIT_IMPLICIT(children);
342 OTTER_TASK_WAIT_IMPLICIT(descendants);
343
344 repositories::finishGridConstructionStep();
345
346 if (
348 and
349 not repositories::loadBalancer.hasSplitRecently()
350 and
351 repositories::loadBalancer.isEnabled(false)
352 ) {
353 logInfo(
354 "step()",
355 "have to decrement local cell counter "
356 << creepingNumberOfLocalCells << " as maximum weight is "
358 );
359 creepingNumberOfLocalCells = (creepingNumberOfLocalCells
361 / 2;
362 }
363 } break;
364 case repositories::StepRepository::Steps::InitGrid: {
366 repositories::loadBalancer.enable(false);
367
369
370 repositories::startGridInitialisationStep();
371
372 OTTER_DEFINE_TASK(step_task, OTTER_NULL_TASK, otter_no_add_to_pool, otter::label::step);
373 OTTER_TASK_START(step_task);
374
375 observers::InitGrid observer;
376 watch.start();
378 watch.stop();
380
381 OTTER_TASK_WAIT_IMPLICIT(children);
383 OTTER_TASK_WAIT_IMPLICIT(descendants);
384
385 repositories::finishGridInitialisationStep();
386 } break;
387 case repositories::StepRepository::Steps::PlotSolution: {
389 const double minTimeStamp = repositories::getMinTimeStamp();
390 const double maxTimeStamp = repositories::getMaxTimeStamp();
391 const double minTimeStepSize = repositories::getMinTimeStepSize();
392 const double maxTimeStepSize = repositories::getMaxTimeStepSize();
393
395
396 repositories::startPlottingStep(minTimeStamp, maxTimeStamp, minTimeStepSize, maxTimeStepSize);
397
398 OTTER_DEFINE_TASK(step_task, OTTER_NULL_TASK, otter_no_add_to_pool, otter::label::step);
399 OTTER_TASK_START(step_task);
400
401 observers::PlotSolution observer;
402 watch.start();
404 watch.stop();
406
407 OTTER_TASK_WAIT_IMPLICIT(children);
409 OTTER_TASK_WAIT_IMPLICIT(descendants);
410
411 repositories::finishPlottingStep();
412 } break;
413 case repositories::StepRepository::Steps::TimeStep: {
415 if (repositories::loadBalancer.isEnabled(false)) {
416 logInfo("step()", "disable load balancing throughout initialisation (to be removed in later releases)");
417 repositories::loadBalancer.enable(false);
418 }
419
420 const double minTimeStamp = repositories::getMinTimeStamp();
421 const double maxTimeStamp = repositories::getMaxTimeStamp();
422 const double minTimeStepSize = repositories::getMinTimeStepSize();
423 const double maxTimeStepSize = repositories::getMaxTimeStepSize();
424 const double minMeshSize = repositories::getMinMeshSize();
425 const double maxMeshSize = repositories::getMaxMeshSize();
426
428
429 repositories::startTimeStep(minTimeStamp, maxTimeStamp, minTimeStepSize, maxTimeStepSize);
430
431 OTTER_DEFINE_TASK(step_task, OTTER_NULL_TASK, otter_no_add_to_pool, otter::label::step);
432 OTTER_TASK_START(step_task);
433
434 observers::TimeStep observer;
435 watch.start();
437 watch.stop();
439
440 OTTER_TASK_WAIT_IMPLICIT(children);
442 OTTER_TASK_WAIT_IMPLICIT(descendants);
443
444 repositories::finishTimeStep();
445 } break;
447 #if defined(USE_ADDITIONAL_MESH_TRAVERSAL)
448 case repositories::StepRepository::Steps::AdditionalMeshTraversal:
449 {
450 tarch::logging::LogFilter::getInstance().switchProgramPhase( "additional-MeshTraversal" );
451
452 repositories::suspendSolversForOneGridSweep();
453 observers::AdditionalMeshTraversal observer;
455 }
456 break;
457 #endif
459 case repositories::StepRepository::Steps::Undef:
460 assertion(false);
461 break;
462 }
463}
464
465int main(int argc, char** argv) {
466 const int ExitCodeSuccess = 0;
467 const int ExitCodeUnitTestsFailed = 1;
468 const int ExitCodeInvalidArguments = 2;
469 const int ExitCodeInvalidBuild = 3;
470
471 static tarch::timing::Watch watch("::", "main()", false);
472
474
475 // Do this early, so people can use logInfo properly.
476 repositories::initLogFilters();
477
481
482 peano4::initSingletons(DomainOffset, DomainSize, PeriodicBC);
483
484 repositories::initSharedMemoryAndGPUEnvironment();
485
486 if (tarch::mpi::Rank::getInstance().getNumberOfRanks() > 1 and tarch::multicore::Core::getInstance().getNumberOfThreads() <= 1) {
487 logError("main()", "MPI runs without multithreading are not supported currently.");
488 return ExitCodeInvalidBuild;
489 }
490
491 repositories::DataRepository::initDatatypes();
492
493 #if PeanoDebug >= 2
495 unitTests->addTestCase(peano4::getUnitTests());
496 unitTests->addTestCase(tarch::getUnitTests());
499 unitTests->run();
500 if (unitTests->getNumberOfErrors() != 0) {
501 logError("main()", "unit tests failed. Quit.");
502 tarch::mpi::Rank::abort(ExitCodeUnitTestsFailed);
503 }
504 delete unitTests;
505#endif
506
507 repositories::startSimulation();
508
510
512
513#if defined(SharedOMP)
514#pragma omp parallel
515 {
516#pragma omp master
517 {
518#endif
519
520#if defined(UseSmartMPI)
521 const bool isGlobalMaster = tarch::mpi::Rank::getInstance().isGlobalMaster() and smartmpi::isComputeRank();
522 const bool isPeanoComputeNode = not tarch::mpi::Rank::getInstance().isGlobalMaster() and smartmpi::isComputeRank();
523#else
524 const bool isGlobalMaster = tarch::mpi::Rank::getInstance().isGlobalMaster();
525 const bool isPeanoComputeNode = not tarch::mpi::Rank::getInstance().isGlobalMaster();
526#endif
527
528 if (isGlobalMaster) {
529 while (selectNextAlgorithmicStep()) {
530 watch.start();
531 step();
532 watch.stop();
533
535 logInfo("main()", "time per mesh sweep (current/average): " << std::fixed << std::setprecision(2) << watch.getCalendarTime() << " / " << timePerMeshSwepMeasurement.getValue() );
536 }
537
538 logInfo("main()", "terminated successfully");
539 logInfo(
540 "main()",
541 "initial grid construction: " << gridConstructionMeasurement.getAccumulatedValue(
543 );
544 logInfo(
545 "main()",
546 "plotting: " << plotMeasurement.getAccumulatedValue() << "s\t" << plotMeasurement.toString()
547 );
548 logInfo(
549 "main()",
550 "time stepping: " << timeStepMeasurement.getAccumulatedValue(
551 ) << "s\t" << timeStepMeasurement.toString()
552 );
553 logInfo(
554 "main()",
555 "average time per mesh sweep: " << timePerMeshSwepMeasurement.getValue() << "\t" << timePerMeshSwepMeasurement.toString()
556 );
557 } else if (isPeanoComputeNode) {
558 while (peano4::parallel::Node::getInstance().continueToRun()) {
559 step();
560 }
561 }
562#if defined(UseSmartMPI)
563 else {
564 while (smartmpi::continueToRun()) {
565 smartmpi::tick();
566 }
567 }
568#endif
569
570#if defined(SharedOMP)
571 }
572 }
573#endif
574
576
578
579 repositories::finishSimulation();
580
582 repositories::DataRepository::shutdownDatatypes();
586
587 return ExitCodeSuccess;
588}
#define assertion(expr)
#define logError(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:464
#define logDebug(methodName, logMacroMessageStream)
Definition Log.h:50
#define logWarning(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:440
#define logInfo(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:411
tarch::timing::Measurement gridConstructionMeasurement
Definition ccz4-main.cpp:54
tarch::logging::Log _log("::")
tarch::timing::Measurement timeStepMeasurement
Definition ccz4-main.cpp:55
bool selectNextAlgorithmicStep()
Decide which step to run next.
Definition ccz4-main.cpp:67
tarch::timing::Measurement plotMeasurement
Definition ccz4-main.cpp:56
void step()
tarch::timing::Measurement timePerMeshSwepMeasurement
Definition ccz4-main.cpp:53
int main()
Definition main.cpp:321
int getCurrentProgramStep() const
Definition Node.cpp:447
void setNextProgramStep(int number)
The user tells the set which program step to use, i.e.
Definition Node.cpp:441
static Node & getInstance()
This operation returns the singleton instance.
Definition Node.cpp:108
peano4::grid::GridStatistics getGridStatistics() const
Return statistics object for primary spacetree.
static SpacetreeSet & getInstance()
void traverse(peano4::grid::TraversalObserver &observer)
Invoke traverse on all spacetrees in parallel.
void switchProgramPhase(const std::string &activeProgramPhase)
static LogFilter & getInstance()
Log Device.
Definition Log.h:516
void writeToCSV(std::string filename="statistics")
Write data to csv file.
static Statistics & getInstance()
This is not the canonical realisation of singletons as I use it usually for stats in Peano.
bool isGlobalMaster() const
Is this node the global master process, i.e.
Definition Rank.cpp:424
static Rank & getInstance()
This operation returns the singleton instance.
Definition Rank.cpp:543
static void abort(int errorCode)
A proper abort in an MPI context has to use MPI_Abort.
Definition Rank.cpp:596
static Core & getInstance()
Definition Core.cpp:56
int getNumberOfThreads() const
Returns the number of threads that is used.
Definition Core.cpp:67
int getNumberOfErrors() const
Definition TestCase.cpp:11
void addTestCase(const std::string &fullQualifiedPath, TestCase *testCase)
Adds a new test case.
virtual void run()
Runs all test cases assigned.
double getAccumulatedValue() const
std::string toString() const
void setValue(const double &value)
Set the value.
A simple class that has to be included to measure the clock ticks required for an operation.
Definition Watch.h:45
double getCalendarTime()
This method returns the elapsed calendar time between the start and stop command of the timer,...
Definition Watch.cpp:74
void stop()
Stop timer.
Definition Watch.cpp:55
void start()
(Re)Start the Timer
Definition Watch.cpp:48
std::string toString(Filter filter)
Definition convert.cpp:170
tarch::tests::TestCase * getUnitTests()
Please destroy after usage.
Definition UnitTests.cpp:18
static const char * step
Definition otter.h:106
static const char * create_grid
Definition otter.h:113
static const char * init
Definition otter.h:110
static const char * plot
Definition otter.h:111
static const char * timestep
Definition otter.h:112
static const char * create_grid_converge
Definition otter.h:115
static const char * create_grid_no_refine
Definition otter.h:114
tarch::tests::TestCase * getUnitTests()
Please destroy after usage.
Definition UnitTests.cpp:12
void shutdownSingletons()
The very first thing I have to do is to shut down Node.
Definition peano.cpp:150
void fillLookupTables()
Fill Lookup Tables.
Definition peano.cpp:87
int initParallelEnvironment(int *argc, char ***argv)
Init Parallel Environment.
Definition peano.cpp:101
void initSingletons(const tarch::la::Vector< Dimensions, double > &offset, const tarch::la::Vector< Dimensions, double > &width, const std::bitset< Dimensions > &periodicBC=0)
Fire up all the singletons.
Definition peano.cpp:133
void shutdownParallelEnvironment()
Shutdown all the parallel environment, i.e.
Definition peano.cpp:127
double max(double a, double b, double c)
I need the maximum of three values all the time, to I decided to write a function for this.
Definition Scalar.cpp:8
void shutdownSmartMPI()
Definition multicore.cpp:49
void initSmartMPI()
Switch on SmartMPI.
Definition multicore.cpp:33
tarch::tests::TestCase * getUnitTests()
Please destroy after usage.
Definition UnitTests.cpp:17
bool hasNonCriticalAssertionBeenViolated()
void shutdownNonCriticalAssertionEnvironment()
peano4::shutdownParallelEnvironment().
void initNonCriticalAssertionEnvironment()
Register the assertion tag from the global communicator.
tarch::tests::TestCase * getUnitTests()
Please destroy after usage.
Definition UnitTests.cpp:11
int getWeightOfHeaviestLocalSpacetree()
This is a helper routine which is used by ExaHyPE's default main for for example.
#define OTTER_TASK_WAIT_IMPLICIT(...)
Definition otter.h:141
#define OTTER_FINALISE()
Definition otter.h:125
#define OTTER_TASK_END(...)
Definition otter.h:136
#define OTTER_INITIALISE()
Definition otter.h:124
#define OTTER_PHASE_SWITCH(...)
Definition otter.h:144
#define OTTER_TASK_START(...)
Definition otter.h:135
#define OTTER_DEFINE_TASK(...)
Definition otter.h:128
tarch::la::Vector< Dimensions, double > getMinH() const
Simple vector class.
Definition Vector.h:134