fvbaseproblem.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
28#ifndef EWOMS_FV_BASE_PROBLEM_HH
29#define EWOMS_FV_BASE_PROBLEM_HH
30
31#include <dune/common/fvector.hh>
32
36
39
41
42#include <functional>
43#include <iostream>
44#include <limits>
45#include <string>
46
47namespace Opm::Properties {
48
49template <class TypeTag, class MyTypeTag>
50struct NewtonMethod;
51
52} // namespace Opm::Properties
53
54namespace Opm {
55
65template<class TypeTag>
67{
68private:
69 using Implementation = GetPropType<TypeTag, Properties::Problem>;
71
72 static const int vtkOutputFormat = getPropValue<TypeTag, Properties::VtkOutputFormat>();
74
80
83
88
89 enum {
90 dim = GridView::dimension,
91 dimWorld = GridView::dimensionworld
92 };
93
94 using Element = typename GridView::template Codim<0>::Entity;
95 using Vertex = typename GridView::template Codim<dim>::Entity;
96 using VertexIterator = typename GridView::template Codim<dim>::Iterator;
97
98 using CoordScalar = typename GridView::Grid::ctype;
99 using GlobalPosition = Dune::FieldVector<CoordScalar, dimWorld>;
100
101public:
102 // the default restriction and prolongation for adaptation is simply an empty one
104
105private:
106 // copying a problem is not a good idea
107 FvBaseProblem(const FvBaseProblem& ) = delete;
108
109public:
118 : nextTimeStepSize_(0.0)
119 , gridView_(simulator.gridView())
120 , elementMapper_(gridView_, Dune::mcmgElementLayout())
121 , vertexMapper_(gridView_, Dune::mcmgVertexLayout())
122 , boundingBoxMin_(std::numeric_limits<double>::max())
123 , boundingBoxMax_(-std::numeric_limits<double>::max())
124 , simulator_(simulator)
125 , defaultVtkWriter_(0)
126 {
127 // calculate the bounding box of the local partition of the grid view
128 VertexIterator vIt = gridView_.template begin<dim>();
129 const VertexIterator vEndIt = gridView_.template end<dim>();
130 for (; vIt!=vEndIt; ++vIt) {
131 for (unsigned i=0; i<dim; i++) {
132 boundingBoxMin_[i] = std::min(boundingBoxMin_[i], vIt->geometry().corner(0)[i]);
133 boundingBoxMax_[i] = std::max(boundingBoxMax_[i], vIt->geometry().corner(0)[i]);
134 }
135 }
136
137 // communicate to get the bounding box of the whole domain
138 for (unsigned i = 0; i < dim; ++i) {
139 boundingBoxMin_[i] = gridView_.comm().min(boundingBoxMin_[i]);
140 boundingBoxMax_[i] = gridView_.comm().max(boundingBoxMax_[i]);
141 }
142
143 if (enableVtkOutput_()) {
144 bool asyncVtkOutput =
145 simulator_.gridView().comm().size() == 1 &&
146 Parameters::Get<Parameters::EnableAsyncVtkOutput>();
147
148 // asynchonous VTK output currently does not work in conjunction with grid
149 // adaptivity because the async-IO code assumes that the grid stays
150 // constant. complain about that case.
151 bool enableGridAdaptation = Parameters::Get<Parameters::EnableGridAdaptation>();
152 if (asyncVtkOutput && enableGridAdaptation)
153 throw std::runtime_error("Asynchronous VTK output currently cannot be used "
154 "at the same time as grid adaptivity");
155
156 std::string outputDir = asImp_().outputDir();
157
158 defaultVtkWriter_ =
159 new VtkMultiWriter(asyncVtkOutput, gridView_, outputDir, asImp_().name());
160 }
161 }
162
164 { delete defaultVtkWriter_; }
165
170 static void registerParameters()
171 {
172 Model::registerParameters();
173 Parameters::Register<Parameters::MaxTimeStepSize<Scalar>>
174 ("The maximum size to which all time steps are limited to [s]");
175 Parameters::Register<Parameters::MinTimeStepSize<Scalar>>
176 ("The minimum size to which all time steps are limited to [s]");
177 Parameters::Register<Parameters::MaxTimeStepDivisions>
178 ("The maximum number of divisions by two of the timestep size "
179 "before the simulation bails out");
180 Parameters::Register<Parameters::EnableAsyncVtkOutput>
181 ("Dispatch a separate thread to write the VTK output");
182 Parameters::Register<Parameters::ContinueOnConvergenceError>
183 ("Continue with a non-converged solution instead of giving up "
184 "if we encounter a time step size smaller than the minimum time "
185 "step size.");
186 }
187
196 { return true; }
197
206 std::string outputDir() const
207 {
208 return simulatorOutputDir();
209 }
210
217 static std::string helpPreamble(int,
218 const char **argv)
219 {
220 std::string desc = Implementation::briefDescription();
221 if (!desc.empty())
222 desc = desc + "\n";
223
224 return
225 "Usage: "+std::string(argv[0]) + " [OPTIONS]\n"
226 + desc;
227 }
228
235 static std::string briefDescription()
236 { return ""; }
237
238 // TODO (?): detailedDescription()
239
256 static int handlePositionalParameter(std::function<void(const std::string&,
257 const std::string&)>,
258 std::set<std::string>&,
259 std::string& errorMsg,
260 int,
261 const char** argv,
262 int paramIdx,
263 int)
264 {
265 errorMsg = std::string("Illegal parameter \"")+argv[paramIdx]+"\".";
266 return 0;
267 }
268
275 { }
276
281 void prefetch(const Element&) const
282 {
283 // do nothing by default
284 }
285
290 {
291#if DUNE_VERSION_NEWER(DUNE_GRID, 2, 8)
292 elementMapper_.update(gridView_);
293 vertexMapper_.update(gridView_);
294#else
295 elementMapper_.update();
296 vertexMapper_.update();
297#endif
298
299 if (enableVtkOutput_())
300 defaultVtkWriter_->gridChanged();
301 }
302
312 template <class Context>
313 void boundary(BoundaryRateVector&,
314 const Context&,
315 unsigned,
316 unsigned) const
317 { throw std::logic_error("Problem does not provide a boundary() method"); }
318
329 template <class Context>
330 void constraints(Constraints&,
331 const Context&,
332 unsigned,
333 unsigned) const
334 { throw std::logic_error("Problem does not provide a constraints() method"); }
335
348 template <class Context>
349 void source(RateVector&,
350 const Context&,
351 unsigned,
352 unsigned) const
353 { throw std::logic_error("Problem does not provide a source() method"); }
354
365 template <class Context>
366 void initial(PrimaryVariables&,
367 const Context&,
368 unsigned,
369 unsigned) const
370 { throw std::logic_error("Problem does not provide a initial() method"); }
371
387 template <class Context>
388 Scalar extrusionFactor(const Context&,
389 unsigned,
390 unsigned) const
391 { return asImp_().extrusionFactor(); }
392
393 Scalar extrusionFactor() const
394 { return 1.0; }
395
401 {}
402
407 { }
408
413 { }
414
419 { }
420
425 { }
426
434 { }
435
442 {
443 std::cerr << "The end of episode " << simulator().episodeIndex() + 1 << " has been "
444 << "reached, but the problem does not override the endEpisode() method. "
445 << "Doing nothing!\n";
446 }
447
451 void finalize()
452 {
453 const auto& executionTimer = simulator().executionTimer();
454
455 Scalar executionTime = executionTimer.realTimeElapsed();
456 Scalar setupTime = simulator().setupTimer().realTimeElapsed();
457 Scalar prePostProcessTime = simulator().prePostProcessTimer().realTimeElapsed();
458 Scalar localCpuTime = executionTimer.cpuTimeElapsed();
459 Scalar globalCpuTime = executionTimer.globalCpuTimeElapsed();
460 Scalar writeTime = simulator().writeTimer().realTimeElapsed();
461 Scalar linearizeTime = simulator().linearizeTimer().realTimeElapsed();
462 Scalar solveTime = simulator().solveTimer().realTimeElapsed();
463 Scalar updateTime = simulator().updateTimer().realTimeElapsed();
464 unsigned numProcesses = static_cast<unsigned>(this->gridView().comm().size());
465 unsigned threadsPerProcess = ThreadManager::maxThreads();
466 if (gridView().comm().rank() == 0) {
467 std::cout << std::setprecision(3)
468 << "Simulation of problem '" << asImp_().name() << "' finished.\n"
469 << "\n"
470 << "------------------------ Timing ------------------------\n"
471 << "Setup time: " << setupTime << " seconds"
472 << humanReadableTime(setupTime)
473 << ", " << setupTime/(executionTime + setupTime)*100 << "%\n"
474 << "Simulation time: " << executionTime << " seconds"
475 << humanReadableTime(executionTime)
476 << ", " << executionTime/(executionTime + setupTime)*100 << "%\n"
477 << " Linearization time: " << linearizeTime << " seconds"
478 << humanReadableTime(linearizeTime)
479 << ", " << linearizeTime/executionTime*100 << "%\n"
480 << " Linear solve time: " << solveTime << " seconds"
481 << humanReadableTime(solveTime)
482 << ", " << solveTime/executionTime*100 << "%\n"
483 << " Newton update time: " << updateTime << " seconds"
484 << humanReadableTime(updateTime)
485 << ", " << updateTime/executionTime*100 << "%\n"
486 << " Pre/postprocess time: " << prePostProcessTime << " seconds"
487 << humanReadableTime(prePostProcessTime)
488 << ", " << prePostProcessTime/executionTime*100 << "%\n"
489 << " Output write time: " << writeTime << " seconds"
490 << humanReadableTime(writeTime)
491 << ", " << writeTime/executionTime*100 << "%\n"
492 << "First process' simulation CPU time: " << localCpuTime << " seconds"
493 << humanReadableTime(localCpuTime) << "\n"
494 << "Number of processes: " << numProcesses << "\n"
495 << "Threads per processes: " << threadsPerProcess << "\n"
496 << "Total CPU time: " << globalCpuTime << " seconds"
497 << humanReadableTime(globalCpuTime) << "\n"
498 << "\n"
499 << "----------------------------------------------------------------\n"
500 << std::endl;
501 }
502 }
503
509 {
510 unsigned maxFails = asImp_().maxTimeIntegrationFailures();
511 Scalar minTimeStepSize = asImp_().minTimeStepSize();
512
513 std::string errorMessage;
514 for (unsigned i = 0; i < maxFails; ++i) {
515 bool converged = model().update();
516 if (converged)
517 return;
518
519 Scalar dt = simulator().timeStepSize();
520 Scalar nextDt = dt / 2.0;
521 if (dt < minTimeStepSize*(1 + 1e-9)) {
522 if (asImp_().continueOnConvergenceError()) {
523 if (gridView().comm().rank() == 0)
524 std::cout << "Newton solver did not converge with minimum time step of "
525 << dt << " seconds. Continuing with unconverged solution!\n"
526 << std::flush;
527 return;
528 }
529 else {
530 errorMessage =
531 "Time integration did not succeed with the minumum time step size of "
532 + std::to_string(double(minTimeStepSize)) + " seconds. Giving up!";
533 break; // give up: we can't make the time step smaller anymore!
534 }
535 }
536 else if (nextDt < minTimeStepSize)
537 nextDt = minTimeStepSize;
538 simulator().setTimeStepSize(nextDt);
539
540 // update failed
541 if (gridView().comm().rank() == 0)
542 std::cout << "Newton solver did not converge with "
543 << "dt=" << dt << " seconds. Retrying with time step of "
544 << nextDt << " seconds\n" << std::flush;
545 }
546
547 if (errorMessage.empty())
548 errorMessage =
549 "Newton solver didn't converge after "
550 +std::to_string(maxFails)+" time-step divisions. dt="
551 +std::to_string(double(simulator().timeStepSize()));
552 throw std::runtime_error(errorMessage);
553 }
554
558 Scalar minTimeStepSize() const
559 { return Parameters::Get<Parameters::MinTimeStepSize<Scalar>>(); }
560
566 { return Parameters::Get<Parameters::MaxTimeStepDivisions>(); }
567
574 { return Parameters::Get<Parameters::ContinueOnConvergenceError>(); }
575
579 void setNextTimeStepSize(Scalar dt)
580 { nextTimeStepSize_ = dt; }
581
587 Scalar nextTimeStepSize() const
588 {
589 if (nextTimeStepSize_ > 0.0)
590 return nextTimeStepSize_;
591
592 Scalar dtNext = std::min(Parameters::Get<Parameters::MaxTimeStepSize<Scalar>>(),
593 newtonMethod().suggestTimeStepSize(simulator().timeStepSize()));
594
595 if (dtNext < simulator().maxTimeStepSize()
596 && simulator().maxTimeStepSize() < dtNext*2)
597 {
598 dtNext = simulator().maxTimeStepSize()/2 * 1.01;
599 }
600
601 return dtNext;
602 }
603
613 {
614 return simulator().timeStepIndex() > 0 &&
615 (simulator().timeStepIndex() % 10 == 0);
616 }
617
626 bool shouldWriteOutput() const
627 { return true; }
628
635 { model().advanceTimeLevel(); }
636
644 std::string name() const
645 { return "sim"; }
646
650 const GridView& gridView() const
651 { return gridView_; }
652
657 const GlobalPosition& boundingBoxMin() const
658 { return boundingBoxMin_; }
659
664 const GlobalPosition& boundingBoxMax() const
665 { return boundingBoxMax_; }
666
670 const VertexMapper& vertexMapper() const
671 { return vertexMapper_; }
672
676 const ElementMapper& elementMapper() const
677 { return elementMapper_; }
678
682 Simulator& simulator()
683 { return simulator_; }
684
688 const Simulator& simulator() const
689 { return simulator_; }
690
694 Model& model()
695 { return simulator_.model(); }
696
700 const Model& model() const
701 { return simulator_.model(); }
702
706 NewtonMethod& newtonMethod()
707 { return model().newtonMethod(); }
708
712 const NewtonMethod& newtonMethod() const
713 { return model().newtonMethod(); }
714 // \}
715
721 {
723 }
724
733 {
734 return 0;
735 }
736
750 template <class Restarter>
751 void serialize(Restarter& res)
752 {
753 if (enableVtkOutput_())
754 defaultVtkWriter_->serialize(res);
755 }
756
767 template <class Restarter>
768 void deserialize(Restarter& res)
769 {
770 if (enableVtkOutput_())
771 defaultVtkWriter_->deserialize(res);
772 }
773
780 void writeOutput(bool verbose = true)
781 {
782 if (!enableVtkOutput_())
783 return;
784
785 if (verbose && gridView().comm().rank() == 0)
786 std::cout << "Writing visualization results for the current time step.\n"
787 << std::flush;
788
789 // calculate the time _after_ the time was updated
790 Scalar t = simulator().time() + simulator().timeStepSize();
791
792 defaultVtkWriter_->beginWrite(t);
793 model().prepareOutputFields();
794 model().appendOutputFields(*defaultVtkWriter_);
795 defaultVtkWriter_->endWrite();
796
797 }
798
804 { return defaultVtkWriter_; }
805
806protected:
808
809private:
810 bool enableVtkOutput_() const
811 { return Parameters::Get<Parameters::EnableVtkOutput>(); }
812
814 Implementation& asImp_()
815 { return *static_cast<Implementation *>(this); }
816
818 const Implementation& asImp_() const
819 { return *static_cast<const Implementation *>(this); }
820
821 // Grid management stuff
822 const GridView gridView_;
823 ElementMapper elementMapper_;
824 VertexMapper vertexMapper_;
825 GlobalPosition boundingBoxMin_;
826 GlobalPosition boundingBoxMax_;
827
828 // Attributes required for the actual simulation
829 Simulator& simulator_;
830 mutable VtkMultiWriter *defaultVtkWriter_;
831};
832
833} // namespace Opm
834
835#endif
Definition: restrictprolong.hh:142
Base class for all problems which use a finite volume spatial discretization.
Definition: fvbaseproblem.hh:67
static int handlePositionalParameter(std::function< void(const std::string &, const std::string &)>, std::set< std::string > &, std::string &errorMsg, int, const char **argv, int paramIdx, int)
Handles positional command line parameters.
Definition: fvbaseproblem.hh:256
std::string name() const
The problem name.
Definition: fvbaseproblem.hh:644
const Simulator & simulator() const
Returns Simulator object used by the simulation.
Definition: fvbaseproblem.hh:688
void writeOutput(bool verbose=true)
Write the relevant secondary variables of the current solution into an VTK output file.
Definition: fvbaseproblem.hh:780
void boundary(BoundaryRateVector &, const Context &, unsigned, unsigned) const
Evaluate the boundary conditions for a boundary segment.
Definition: fvbaseproblem.hh:313
void finalize()
Called after the simulation has been run sucessfully.
Definition: fvbaseproblem.hh:451
Simulator & simulator()
Returns Simulator object used by the simulation.
Definition: fvbaseproblem.hh:682
const Model & model() const
Returns numerical model used for the problem.
Definition: fvbaseproblem.hh:700
static void registerParameters()
Registers all available parameters for the problem and the model.
Definition: fvbaseproblem.hh:170
void source(RateVector &, const Context &, unsigned, unsigned) const
Evaluate the source term for all phases within a given sub-control-volume.
Definition: fvbaseproblem.hh:349
bool recycleFirstIterationStorage() const
Return if the storage term of the first iteration is identical to the storage term for the solution o...
Definition: fvbaseproblem.hh:195
unsigned maxTimeIntegrationFailures() const
Returns the maximum number of subsequent failures for the time integration before giving up.
Definition: fvbaseproblem.hh:565
unsigned markForGridAdaptation()
Mark grid cells for refinement or coarsening.
Definition: fvbaseproblem.hh:732
void serialize(Restarter &res)
This method writes the complete state of the problem to the harddisk.
Definition: fvbaseproblem.hh:751
void beginIteration()
Called by the simulator before each Newton-Raphson iteration.
Definition: fvbaseproblem.hh:418
~FvBaseProblem()
Definition: fvbaseproblem.hh:163
void endTimeStep()
Called by the simulator after each time integration.
Definition: fvbaseproblem.hh:433
FvBaseProblem(Simulator &simulator)
Definition: fvbaseproblem.hh:117
const GlobalPosition & boundingBoxMax() const
The coordinate of the corner of the GridView's bounding box with the largest values.
Definition: fvbaseproblem.hh:664
RestrictProlongOperator restrictProlongOperator()
return restriction and prolongation operator
Definition: fvbaseproblem.hh:720
void timeIntegration()
Called by Opm::Simulator in order to do a time integration on the model.
Definition: fvbaseproblem.hh:508
Model & model()
Returns numerical model used for the problem.
Definition: fvbaseproblem.hh:694
Scalar extrusionFactor() const
Definition: fvbaseproblem.hh:393
void endEpisode()
Called when the end of an simulation episode is reached.
Definition: fvbaseproblem.hh:441
void beginTimeStep()
Called by the simulator before each time integration.
Definition: fvbaseproblem.hh:412
static std::string helpPreamble(int, const char **argv)
Returns the string that is printed before the list of command line parameters in the help message.
Definition: fvbaseproblem.hh:217
void deserialize(Restarter &res)
This method restores the complete state of the problem from disk.
Definition: fvbaseproblem.hh:768
void prefetch(const Element &) const
Allows to improve the performance by prefetching all data which is associated with a given element.
Definition: fvbaseproblem.hh:281
Scalar extrusionFactor(const Context &, unsigned, unsigned) const
Return how much the domain is extruded at a given sub-control volume.
Definition: fvbaseproblem.hh:388
bool shouldWriteRestartFile() const
Returns true if a restart file should be written to disk.
Definition: fvbaseproblem.hh:612
Scalar nextTimeStepSize() const
Called by Opm::Simulator whenever a solution for a time step has been computed and the simulation tim...
Definition: fvbaseproblem.hh:587
Scalar minTimeStepSize() const
Returns the minimum allowable size of a time step.
Definition: fvbaseproblem.hh:558
void beginEpisode()
Called at the beginning of an simulation episode.
Definition: fvbaseproblem.hh:406
void initial(PrimaryVariables &, const Context &, unsigned, unsigned) const
Evaluate the initial value for a control volume.
Definition: fvbaseproblem.hh:366
std::string outputDir() const
Determine the directory for simulation output.
Definition: fvbaseproblem.hh:206
Scalar nextTimeStepSize_
Definition: fvbaseproblem.hh:807
const VertexMapper & vertexMapper() const
Returns the mapper for vertices to indices.
Definition: fvbaseproblem.hh:670
void gridChanged()
Handle changes of the grid.
Definition: fvbaseproblem.hh:289
const GlobalPosition & boundingBoxMin() const
The coordinate of the corner of the GridView's bounding box with the smallest values.
Definition: fvbaseproblem.hh:657
static std::string briefDescription()
Returns a human readable description of the problem for the help message.
Definition: fvbaseproblem.hh:235
void endIteration()
Called by the simulator after each Newton-Raphson update.
Definition: fvbaseproblem.hh:424
void setNextTimeStepSize(Scalar dt)
Impose the next time step size to be used externally.
Definition: fvbaseproblem.hh:579
bool continueOnConvergenceError() const
Returns if we should continue with a non-converged solution instead of giving up if we encounter a ti...
Definition: fvbaseproblem.hh:573
void constraints(Constraints &, const Context &, unsigned, unsigned) const
Evaluate the constraints for a control volume.
Definition: fvbaseproblem.hh:330
void finishInit()
Called by the Opm::Simulator in order to initialize the problem.
Definition: fvbaseproblem.hh:274
const NewtonMethod & newtonMethod() const
Returns object which implements the Newton method.
Definition: fvbaseproblem.hh:712
const GridView & gridView() const
The GridView which used by the problem.
Definition: fvbaseproblem.hh:650
EmptyRestrictProlong RestrictProlongOperator
Definition: fvbaseproblem.hh:103
NewtonMethod & newtonMethod()
Returns object which implements the Newton method.
Definition: fvbaseproblem.hh:706
bool shouldWriteOutput() const
Returns true if the current solution should be written to disk (i.e. as a VTK file)
Definition: fvbaseproblem.hh:626
void initialSolutionApplied()
Callback used by the model to indicate that the initial solution has been determined for all degrees ...
Definition: fvbaseproblem.hh:400
void advanceTimeLevel()
Called by the simulator after everything which can be done about the current time step is finished an...
Definition: fvbaseproblem.hh:634
VtkMultiWriter & defaultVtkWriter() const
Method to retrieve the VTK writer which should be used to write the default ouput after each time ste...
Definition: fvbaseproblem.hh:803
const ElementMapper & elementMapper() const
Returns the mapper for elements to indices.
Definition: fvbaseproblem.hh:676
static unsigned maxThreads()
Return the maximum number of threads of the current process.
Definition: threadmanager.hpp:66
Simplifies writing multi-file VTK datasets.
Definition: vtkmultiwriter.hh:66
void endWrite(bool onlyDiscard=false)
Finalizes the current writer.
Definition: vtkmultiwriter.hh:389
void deserialize(Restarter &res)
Read the multi-writer's state from a restart file.
Definition: vtkmultiwriter.hh:442
void gridChanged()
Updates the internal data structures after mesh refinement.
Definition: vtkmultiwriter.hh:165
void beginWrite(double t)
Called whenever a new time step must be written.
Definition: vtkmultiwriter.hh:179
void serialize(Restarter &res)
Write the multi-writer's state to a restart file.
Definition: vtkmultiwriter.hh:408
Declare the properties used by the infrastructure code of the finite volume discretizations.
Declare the properties used by the infrastructure code of the finite volume discretizations.
Definition: fvbaseprimaryvariables.hh:141
auto Get(bool errorIfNotRegistered=true)
Retrieve a runtime parameter.
Definition: parametersystem.hpp:185
Definition: blackoilmodel.hh:72
Definition: blackoilboundaryratevector.hh:37
std::string humanReadableTime(double timeInSeconds, bool isAmendment=true)
Given a time step size in seconds, return it in a format which is more easily parsable by humans.
std::string simulatorOutputDir()
Determine and check the configured directory for simulation output.
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:235
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t)
Specify the maximum size of a time integration [s].
Definition: fvbaseparameters.hh:106