IFEM 90A354
SIMSolver.h
Go to the documentation of this file.
1// $Id$
2//==============================================================================
12//==============================================================================
13
14#ifndef _SIM_SOLVER_H_
15#define _SIM_SOLVER_H_
16
17#include "IFEM.h"
18#include "SIMadmin.h"
19#include "TimeStep.h"
20#include "HDF5Restart.h"
21#include "HDF5Writer.h"
22#include "tinyxml2.h"
23
24
31template<class T1> class SIMSolverStat : public SIMadmin
32{
33public:
35 explicit SIMSolverStat(T1& s1, const char* head = nullptr) : SIMadmin(head), S1(s1)
36 {
37 exporter = nullptr;
38 startExpLevel = 0;
39 }
40
42 virtual ~SIMSolverStat() { delete exporter; }
43
45 virtual bool read(const char*) { return true; }
46
51 void handleDataOutput(const std::string& hdf5file,
52 const ProcessAdm& modelAdm,
53 int saveInterval = 1)
54 {
55 if (IFEM::getOptions().discretization == ASM::Spectral && !hdf5file.empty())
56 IFEM::cout <<"\n ** HDF5 output is not available for spectral"
57 <<" discretization. Deactivating...\n"<< std::endl;
58 else
59 {
60 exporter = new DataExporter(true,saveInterval,startExpLevel);
61 exporter->registerWriter(new HDF5Writer(hdf5file,modelAdm));
62 S1.registerFields(*exporter);
64 }
65 }
66
67protected:
69 void printHeading(const char* heading)
70 {
71 if (heading)
72 {
73 std::string myHeading(heading);
74 size_t n = myHeading.find_last_of('\n');
75 if (n+1 < myHeading.size()) n = myHeading.size()-n;
76 IFEM::cout <<"\n\n"<< myHeading <<"\n";
77 for (size_t i = 0; i < n && i < myHeading.size(); i++) IFEM::cout <<'=';
78 IFEM::cout << std::endl;
79 }
80 }
81
82public:
84 virtual int solveProblem(char* infile, const char* heading = nullptr)
85 {
86 // Save FE model to VTF for visualization
87 int geoBlk = 0, nBlock = 0;
88 if (!S1.saveModel(infile,geoBlk,nBlock))
89 return 1;
90
91 this->printHeading(heading);
92
93 // Solve the stationary problem
94 TimeStep dummy;
95 if (!S1.solveStep(dummy))
96 return 2;
97
98 // Save the results
99 if (!S1.saveStep(dummy,nBlock))
100 return 4;
101
103 return 5;
104
105 return 0;
106 }
107
108protected:
110
113};
114
115
122template<class T1> class SIMSolver : public SIMSolverStat<T1>
123{
124public:
126 explicit SIMSolver(T1& s1) : SIMSolverStat<T1>(s1,"Time integration driver")
127 {
128 saveDivergedSol = dumpLog = false;
129 restartAdm = nullptr;
130 restartProcAdm = nullptr;
131 startRstLevel = 0;
132 }
133
135 virtual ~SIMSolver() { delete restartAdm; delete restartProcAdm; }
136
138 virtual bool read(const char* file) { return this->SIMadmin::read(file); }
139
141 const TimeStep& getTimePrm() const { return tp; }
142
144 bool advanceStep() { return tp.increment() && this->S1.advanceStep(tp); }
145
147 virtual int solveProblem(char* infile, const char* heading = nullptr)
148 {
149 // Save FE model to VTF and HDF5 for visualization.
150 // Save the initial configuration also if multi-step simulation.
151 int geoBlk = 0, nBlock = 0;
152 if (!this->saveState(geoBlk,nBlock,true,infile,tp.multiSteps()))
153 return 2;
154
155 this->printHeading(heading);
156
157 // Solve for each time step up to final time
158 while (this->advanceStep())
159 if (!this->S1.solveStep(tp))
160 return saveDivergedSol && !this->S1.saveStep(tp,nBlock) ? 4 : 3;
161 else if (!this->saveState(geoBlk,nBlock))
162 return 4;
163 else
165
166 return 0;
167 }
168
174 void handleDataOutput(const std::string& hdf5file,
175 const ProcessAdm& modelAdm,
176 int saveInterval = 1,
177 int restartInterval = 0)
178 {
179 this->SIMSolverStat<T1>::handleDataOutput(hdf5file, modelAdm, saveInterval);
180 if (restartInterval < 1) return; // No restart output
181
182 const ProcessAdm* adm = nullptr;
183 if (!modelAdm.dd.isPartitioned())
184 adm = &modelAdm;
185 else if (modelAdm.getProcId() == 0)
186 adm = restartProcAdm = new ProcessAdm();
187 else
188 return; // Restart output on processor 0 only
189
190 restartAdm = new HDF5Restart(hdf5file+"_restart", *adm, restartInterval,
192 }
193
197 {
198 return tp.serialize(data) && this->S1.serialize(data);
199 }
200
203 virtual bool deSerialize(const HDF5Restart::SerializeData& data)
204 {
205 return tp.deSerialize(data) && this->S1.deSerialize(data);
206 }
207
208protected:
210 virtual bool parse(char* keyw, std::istream& is) { return tp.parse(keyw,is); }
211
213 virtual bool parse(const tinyxml2::XMLElement* elem)
214 {
215 if (strcasecmp(elem->Value(),"postprocessing"))
216 return tp.parse(elem);
217
218 const tinyxml2::XMLElement* child = elem->FirstChildElement();
219 for (; child; child = child->NextSiblingElement())
220 if (!strncasecmp(child->Value(),"savediverg",10))
221 saveDivergedSol = true;
222 else if (!strncasecmp(child->Value(),"dumplog",7))
223 dumpLog = true;
224
225 return true;
226 }
227
229 bool saveState(int& geoBlk, int& nBlock, bool newMesh = false,
230 char* infile = nullptr, bool saveRes = true)
231 {
232 if (newMesh && !this->S1.saveModel(infile,geoBlk,nBlock))
233 return false; // saving new geometry to VTF failed
234 else if (!saveRes)
235 return true; // no result saving
236 else if (!this->S1.saveStep(tp,nBlock))
237 return false; // saving results to VTF failed
238
240 if (exportAdm && !exportAdm->dumpTimeLevel(&tp,newMesh,dumpLog))
241 return false; // saving results to HDF5 failed
242
243 if (!restartAdm || !restartAdm->dumpStep(tp))
244 return true; // no restart output for this step
245
246 if (dumpLog)
247 IFEM::cout <<" Serializing simulator state for restart (time level "
248 << restartAdm->getTimeLevel()+1 <<")"<< std::endl;
249
251 if (exportAdm)
252 data["TimeLevel"] = std::to_string(exportAdm->getTimeLevel());
253 return this->serialize(data) ? restartAdm->writeData(data) : true;
254 }
255
256public:
262 int restart(const std::string& restartFile, int restartStep)
263 {
264 if (restartFile.empty()) return 0;
265
266 ProcessAdm oneAdm;
267 const ProcessAdm& adm = this->S1.getProcessAdm();
268 HDF5Restart hdf(restartFile, adm.dd.isPartitioned() ? oneAdm : adm);
269
271 if ((restartStep = hdf.readData(data,restartStep-1)) >= 0)
272 {
273 IFEM::cout <<"\n === Restarting from a serialized state ==="
274 <<"\n file = "<< restartFile
275 <<"\n step = "<< restartStep+1;
276 if (this->deSerialize(data))
277 {
278 // Record time levels in case we are saving results in the restart also
279 startRstLevel = restartStep;
280 HDF5Restart::SerializeData::const_iterator it = data.find("TimeLevel");
281 if (it != data.end())
282 {
283 SIMSolverStat<T1>::startExpLevel = atoi(it->second.c_str());
285 }
286 else
288 }
289 else
290 restartStep = -2;
291 IFEM::cout << std::endl;
292 }
293
294 if (restartStep < 0)
295 std::cerr <<" *** SIMSolver: Failed to read restart data."<< std::endl;
296 return restartStep;
297 }
298
299private:
301
302protected:
303 bool dumpLog;
308};
309
310#endif
Output of restart data to HDF5.
Output of model and results to HDF5 file.
Initialization of the IFEM library.
Administration base class for FEM simulators.
Class for encapsulation of general time stepping parameters.
static const double T1[2]
1-point rule coordinates.
Definition TriangleQuadrature.C:19
Administer and write data using DataWriters.
Definition DataExporter.h:38
bool dumpTimeLevel(const TimeStep *tp=nullptr, bool geoUpd=false, bool doLog=false)
Dumps all registered fields using the registered writers.
Definition DataExporter.C:95
void registerWriter(DataWriter *writer)
Adds the data writer to the list of registered writers.
Definition DataExporter.h:90
int getTimeLevel() const
Returns current time level of the exporter.
Definition DataExporter.h:132
bool isPartitioned() const
Returns whether a graph based partition is used.
Definition DomainDecomposition.h:198
Write and read restart data using a HDF5 file.
Definition HDF5Restart.h:32
int getTimeLevel() const
Returns current time level.
Definition HDF5Restart.h:60
bool dumpStep(const TimeStep &tp)
Returns whether or not restart data should be output.
Definition HDF5Restart.C:40
bool writeData(const SerializeData &data)
Writes restart data to file.
Definition HDF5Restart.C:50
std::map< std::string, std::string > SerializeData
Convenience type.
Definition HDF5Restart.h:34
Write data to a HDF5 file.
Definition HDF5Writer.h:30
static void registerCallback(ControlCallback &cb)
Registers a fifo instruction callback.
Definition IFEM.C:189
static bool pollControllerFifo()
Polls the control fifo for instructions.
Definition IFEM.C:195
static utl::LogStream cout
Combined standard out for parallel processes.
Definition IFEM.h:62
static SIMoptions & getOptions()
Returns a reference to the general input options.
Definition IFEM.h:55
Class for administration of MPI processes in IFEM library.
Definition ProcessAdm.h:33
int getProcId() const
Return process id.
Definition ProcessAdm.h:66
DomainDecomposition dd
Decomain decomposition.
Definition ProcessAdm.h:45
Template class for stationary simulator drivers.
Definition SIMSolver.h:32
virtual ~SIMSolverStat()
The destructor deletes the results data exporter object.
Definition SIMSolver.h:42
void handleDataOutput(const std::string &hdf5file, const ProcessAdm &modelAdm, int saveInterval=1)
Handles application data output.
Definition SIMSolver.h:51
virtual int solveProblem(char *infile, const char *heading=nullptr)
Solves the stationary problem.
Definition SIMSolver.h:84
virtual bool read(const char *)
Nothing to read for this template.
Definition SIMSolver.h:45
SIMSolverStat(T1 &s1, const char *head=nullptr)
The constructor initializes the reference to the actual solver.
Definition SIMSolver.h:35
DataExporter * exporter
Administrator for result output to HDF5 file.
Definition SIMSolver.h:111
T1 & S1
The actual solver.
Definition SIMSolver.h:109
int startExpLevel
Initial time level for the DataExporter.
Definition SIMSolver.h:112
void printHeading(const char *heading)
Writes an application-specific heading, if provided.
Definition SIMSolver.h:69
Template class for transient simulator drivers.
Definition SIMSolver.h:123
const TimeStep & getTimePrm() const
Returns a const reference to the time stepping information.
Definition SIMSolver.h:141
int restart(const std::string &restartFile, int restartStep)
Handles application restarts by reading a serialized solver state.
Definition SIMSolver.h:262
bool dumpLog
Set to true, to print out dump time levels.
Definition SIMSolver.h:303
bool advanceStep()
Advances the time step one step forward.
Definition SIMSolver.h:144
virtual bool read(const char *file)
Reads solver data from the specified input file.
Definition SIMSolver.h:138
virtual bool deSerialize(const HDF5Restart::SerializeData &data)
Set internal state from a serialized state.
Definition SIMSolver.h:203
void handleDataOutput(const std::string &hdf5file, const ProcessAdm &modelAdm, int saveInterval=1, int restartInterval=0)
Handles application data output.
Definition SIMSolver.h:174
TimeStep tp
Time stepping information.
Definition SIMSolver.h:304
int startRstLevel
Initial time level for the restart output.
Definition SIMSolver.h:307
virtual bool serialize(HDF5Restart::SerializeData &data)
Serialize internal state for restarting purposes.
Definition SIMSolver.h:196
bool saveState(int &geoBlk, int &nBlock, bool newMesh=false, char *infile=nullptr, bool saveRes=true)
Saves geometry and results to VTF and HDF5 for current time step.
Definition SIMSolver.h:229
virtual bool parse(const tinyxml2::XMLElement *elem)
Parses a data section from an XML element.
Definition SIMSolver.h:213
SIMSolver(T1 &s1)
The constructor initializes the reference to the actual solver.
Definition SIMSolver.h:126
virtual bool parse(char *keyw, std::istream &is)
Parses a data section from an input stream.
Definition SIMSolver.h:210
virtual ~SIMSolver()
The destructor deletes the restart data handler.
Definition SIMSolver.h:135
bool saveDivergedSol
If true, save also the diverged solution to VTF.
Definition SIMSolver.h:300
virtual int solveProblem(char *infile, const char *heading=nullptr)
Solves the problem up to the final time.
Definition SIMSolver.h:147
HDF5Restart * restartAdm
Administrator for restart output.
Definition SIMSolver.h:305
ProcessAdm * restartProcAdm
Process admin used for restart output.
Definition SIMSolver.h:306
Administration base class for FEM simulators.
Definition SIMadmin.h:32
std::string myHeading
Heading written before reading the input file.
Definition SIMadmin.h:91
virtual bool read(const char *fileName)
Reads model data from the specified input file *fileName.
Definition SIMadmin.C:68
ProcessAdm adm
Parallel administrator.
Definition SIMadmin.h:88
Class for encapsulation of general time stepping parameters.
Definition TimeStep.h:31
bool serialize(std::map< std::string, std::string > &data) const
Serialize internal state for restarting purposes.
Definition TimeStep.C:355
bool multiSteps() const
Returns true if the simulation consists of several time steps.
Definition TimeStep.C:184
bool increment()
Advances the time increments one step further.
Definition TimeStep.C:223
bool parse(char *keyWord, std::istream &is)
Parses a data section from an input stream.
Definition TimeStep.C:62
bool deSerialize(const std::map< std::string, std::string > &data)
Set internal state from a serialized state.
Definition TimeStep.C:371