Peano
Loading...
Searching...
No Matches
MatrixFreeMain.template.cpp
Go to the documentation of this file.
1#include "{{MAIN_NAME}}.h"
2
3#include "peano4/peano.h"
4#include "peano4/UnitTests.h"
7
8#include "{{SUBDIRECTORY}}observers/CreateGrid.h"
9#include "{{SUBDIRECTORY}}observers/InitSolution.h"
10#include "{{SUBDIRECTORY}}observers/Solve.h"
11#include "{{SUBDIRECTORY}}observers/Plot.h"
12{% if SUBDIRECTORIES -%}
13{% for subdirectory in SUBDIRECTORIES %}
14#include "{{subdirectory}}repositories/DataRepository.h"
15#include "{{subdirectory}}repositories/StepRepository.h"
16#include "{{subdirectory}}repositories/SolverRepository.h"
17{% endfor -%}
18{% else %}
19#include "repositories/DataRepository.h"
20#include "repositories/StepRepository.h"
21#include "repositories/SolverRepository.h"
22{%- endif %}
23
24#include "tarch/UnitTests.h"
25#include "tarch/logging/Log.h"
34#include "tarch/timing/Watch.h"
37
38{% if FENV_ARGS is defined and FENV_ARGS != "" -%}
39#include <fenv.h>
40#pragma float_control(precise, on)
41#pragma STDC FENV_ACCESS ON
42{% endif -%}
43
44using namespace {{NAMESPACE | join("::")}};
45
46
48
53
54/*
55TODO: add in tarch::hasNonCriticalAssertionBeenViolated() clauses, which should set
56 continueToSolve to false.
57*/
58
60 static bool gridCreated = false;
61 static bool gridInitialised = false;
62 static bool gridBalanced = false;
63
64 static int solverSteps;
65 bool continueToSolve = true;
67 std::numeric_limits<double>::max()
68 );
69 static int globalNumberOfTrees = repositories::loadBalancer.getGlobalNumberOfTrees();
70
71 static bool plotThenExit = false;
72 const int MaxIterations = {{MAXITERATIONS}};
73
74 if (gridCreated){
76 auto stepName = {{SUBNAMESPACE}}repositories::StepRepository::toStepEnum(stepIdentifier);
77
78 switch ( stepName ) {
79 case {{SUBNAMESPACE}}repositories::StepRepository::Steps::CreateGrid:
80 {
82 {{SUBNAMESPACE}}repositories::StepRepository::toProgramStep( {{SUBNAMESPACE}}repositories::StepRepository::Steps::InitSolution )
83 );
84 }
85 break;
86
87 case {{SUBNAMESPACE}}repositories::StepRepository::Steps::InitSolution:
88 {
90 {{SUBNAMESPACE}}repositories::StepRepository::toProgramStep( {{SUBNAMESPACE}}repositories::StepRepository::Steps::Plot )
91 );
92 }
93 break;
94
95{% if PlotEachTimeStep %}
96
97 case {{SUBNAMESPACE}}repositories::StepRepository::Steps::Solve:
98 {
99 {
100 if (
101 ++solverSteps >= MaxIterations
102 or
103 {{SUBNAMESPACE}}repositories::terminationCriterionHolds()
104 ) plotThenExit = true;
105
107 {{SUBNAMESPACE}}repositories::StepRepository::toProgramStep( {{SUBNAMESPACE}}repositories::StepRepository::Steps::Plot )
108 );
109 }
110 } break;
111
112 case {{SUBNAMESPACE}}repositories::StepRepository::Steps::Plot:
113 {
114 if (plotThenExit) {
115 continueToSolve = false;
116 logInfo("selectNextAlgorithmicStep()", "terminating after " << solverSteps << " steps");
117 }
118
119 else
121 {{SUBNAMESPACE}}repositories::StepRepository::toProgramStep( {{SUBNAMESPACE}}repositories::StepRepository::Steps::Solve )
122 );
123 } break;
124
125{% else %}
126
127 case {{SUBNAMESPACE}}repositories::StepRepository::Steps::Solve:
128 {
129 if (
130 ++solverSteps >= MaxIterations
131 or
132 {{SUBNAMESPACE}}repositories::terminationCriterionHolds()
133 )
134 {
135 logInfo("selectNextAlgorithmicStep()", "terminating after " << solverSteps << " steps");
136 plotThenExit = true;
138 {{SUBNAMESPACE}}repositories::StepRepository::toProgramStep( {{SUBNAMESPACE}}repositories::StepRepository::Steps::Plot )
139 );
140 }
141 else
142 {
144 {{SUBNAMESPACE}}repositories::StepRepository::toProgramStep( {{SUBNAMESPACE}}repositories::StepRepository::Steps::Solve )
145 );
146 }
147 }
148 break;
149 case {{SUBNAMESPACE}}repositories::StepRepository::Steps::Plot:
150 {
151 if ( plotThenExit ) {
152 logInfo("selectNextAlgorithmicStep()", "terminating after " << solverSteps << " sweeps");
153 continueToSolve = false;
154 }
155 else
157 {{SUBNAMESPACE}}repositories::StepRepository::toProgramStep( {{SUBNAMESPACE}}repositories::StepRepository::Steps::Solve )
158 );
159 }
160 break;
161
162{% endif %}
163 case {{SUBNAMESPACE}}repositories::StepRepository::Steps::Undef:
164 {
165 assertionMsg(false, "should not be called" );
166 }
167 break;
168 }
169 }
170 else {
171
173 {{SUBNAMESPACE}}repositories::StepRepository::toProgramStep({{SUBNAMESPACE}}repositories::StepRepository::Steps::CreateGrid)
174 );
175
177 logInfo(
178 "selectNextAlgorithmicStep()", "mesh has been stationary for more than 5 grid sweeps. Stop grid construction"
179 );
180 gridCreated = true;
181 }
182 }
183 return continueToSolve;
184}
185
186void step() {
188 auto stepName = {{SUBNAMESPACE}}repositories::StepRepository::toStepEnum(stepIdentifier);
189
190 static tarch::logging::Log _log("");
191#if PeanoDebug > 0
192#else
193 if (tarch::mpi::Rank::getInstance().isGlobalMaster())
194#endif
195 logInfo("step()", "run " << {{SUBNAMESPACE}}repositories::StepRepository::toString(stepName));
196
197 static tarch::timing::Watch watch("::", "step()", false);
198
199 static int creepingNumberOfLocalCells = 0;
200
201 switch ( stepName ) {
202 case {{SUBNAMESPACE}}repositories::StepRepository::Steps::CreateGrid:
203 {
205
206 observers::CreateGrid observer;
207 observers::CreateGrid::prepareTraversal();
208 watch.start();
210 watch.stop();
211 observers::CreateGrid::unprepareTraversal();
212 createGridMeasurement.setValue( watch.getCalendarTime() );
213
214 repositories::endCreateGrid();
215 }
216 break;
217
218 case {{SUBNAMESPACE}}repositories::StepRepository::Steps::InitSolution:
219 {
221
222 observers::InitSolution observer;
223 observers::InitSolution::prepareTraversal();
224 watch.start();
226 watch.stop();
227 observers::InitSolution::unprepareTraversal();
228 initMeasurement.setValue( watch.getCalendarTime() );
229 }
230 break;
231
232 case {{SUBNAMESPACE}}repositories::StepRepository::Steps::Solve:
233 {
235
236 observers::Solve observer;
237 observers::Solve::prepareTraversal();
238 watch.start();
239 {{SUBNAMESPACE}}repositories::beginMeshSweep();
241 {{SUBNAMESPACE}}repositories::endMeshSweep();
242 watch.stop();
243 observers::Solve::unprepareTraversal();
244
245 solveMeasurement.setValue( watch.getCalendarTime() );
246 }
247 break;
248
249 case {{SUBNAMESPACE}}repositories::StepRepository::Steps::Plot:
250 {
252
253 repositories::incrementPlotCounter();
254
255 observers::Plot observer;
256 observers::Plot::prepareTraversal();
257 watch.start();
259 watch.stop();
260 observers::Plot::unprepareTraversal();
261 plotMeasurement.setValue( watch.getCalendarTime() );
262 }
263 break;
264 case {{SUBNAMESPACE}}repositories::StepRepository::Steps::Undef:
265 assertion(false);
266 break;
267 }
268}
269
270
271
272int main(int argc, char** argv) {
273 const int ExitCodeSuccess = 0;
274 const int ExitCodeUnitTestsFailed = 1;
275 const int ExitCodeInvalidArguments = 2;
276 const int ExitCodeInvalidBuild = 3;
277
281
282 tarch::la::Vector<Dimensions, double> x = {{DomainOffset}};
283 tarch::la::Vector<Dimensions, double> h = {{DomainSize}};
284
286
287 if (tarch::mpi::Rank::getInstance().getNumberOfRanks() > 1 and tarch::multicore::Core::getInstance().getNumberOfThreads() <= 1) {
288 logError("main()", "MPI runs without multithreading are not supported currently.");
289 return ExitCodeInvalidBuild;
290 }
291
292 if (not tarch::logging::LogFilterFileReader::parsePlainTextFile("mghype.log-filter")) {
294 "main()", "no mghype.log-filter file found or file has been corrupted. Use default logging configuration"
295 );
296 }
297
298 {{SUBNAMESPACE}}repositories::DataRepository::initDatatypes();
299
300 {% if FENV_ARGS is defined and FENV_ARGS != "" -%}
301 feenableexcept({{FENV_ARGS}} );
302 {% endif -%}
303
304#if PeanoDebug >= 2
306 unitTests->addTestCase(peano4::getUnitTests());
307 unitTests->addTestCase(tarch::getUnitTests());
309 unitTests->run();
310 if (unitTests->getNumberOfErrors() != 0) {
311 logError("main()", "unit tests failed. Quit.");
312 tarch::mpi::Rank::abort(ExitCodeUnitTestsFailed);
313 }
314 delete unitTests;
315#endif
316
318
320
321#if defined(SharedOMP)
322#pragma omp parallel
323 {
324#pragma omp master
325 {
326#endif
327
328#if defined(UseSmartMPI)
329 const bool isGlobalMaster = tarch::mpi::Rank::getInstance().isGlobalMaster() and smartmpi::isComputeRank();
330 const bool isPeanoComputeNode = not tarch::mpi::Rank::getInstance().isGlobalMaster() and smartmpi::isComputeRank();
331#else
332 const bool isGlobalMaster = tarch::mpi::Rank::getInstance().isGlobalMaster();
333 const bool isPeanoComputeNode = not tarch::mpi::Rank::getInstance().isGlobalMaster();
334#endif
335
336 if (isGlobalMaster) {
337 while (selectNextAlgorithmicStep()) {
338 step();
339 }
340
341 logInfo("main()", "terminated successfully");
342 logInfo(
343 "main()",
344 "grid construction: " << createGridMeasurement.getAccumulatedValue(
345 ) << "s\t" << createGridMeasurement.toString()
346 );
347 logInfo(
348 "main()",
350 ) << "s\t" << initMeasurement.toString()
351 );
352 logInfo(
353 "main()",
355 ) << "s\t" << solveMeasurement.toString()
356 );
357 logInfo(
358 "main()",
359 "plotting: " << plotMeasurement.getAccumulatedValue(
360 ) << "s\t" << plotMeasurement.toString()
361 );
362 } else if (isPeanoComputeNode) {
363 while (peano4::parallel::Node::getInstance().continueToRun()) {
364 step();
365 }
366 }
367#if defined(UseSmartMPI)
368 else {
369 while (smartmpi::continueToRun()) {
370 smartmpi::tick();
371 }
372 }
373#endif
374
375#if defined(SharedOMP)
376 }
377 }
378#endif
379
381
383
384
386 {{SUBNAMESPACE}}repositories::DataRepository::shutdownDatatypes();
389
390 return ExitCodeSuccess;
391}
392
#define assertionMsg(expr, message)
#define assertion(expr)
#define logError(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:464
#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 createGridMeasurement
tarch::logging::Log _log("::")
bool selectNextAlgorithmicStep()
tarch::timing::Measurement solveMeasurement
tarch::timing::Measurement initMeasurement
tarch::timing::Measurement plotMeasurement
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.
static bool parsePlainTextFile(const std::string &filename)
Tries to parse a simple text file where each line contains an entry.
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:420
static Rank & getInstance()
This operation returns the singleton instance.
Definition Rank.cpp:539
static void abort(int errorCode)
A proper abort in an MPI context has to use MPI_Abort.
Definition Rank.cpp:592
static Core & getInstance()
Definition Core.cpp:57
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
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
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
tarch::tests::TestCase * getUnitTests()
Please destroy after usage.
Definition UnitTests.cpp:11
#define OTTER_FINALISE()
Definition otter.h:125
#define OTTER_INITIALISE()
Definition otter.h:124
Simple vector class.
Definition Vector.h:150