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 
31 template<class T1> class SIMSolverStat : public SIMadmin
32 {
33 public:
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 
67 protected:
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 
82 public:
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 
102  if (exporter && !exporter->dumpTimeLevel())
103  return 5;
104 
105  return 0;
106  }
107 
108 protected:
109  T1& S1;
110 
113 };
114 
115 
122 template<class T1> class SIMSolver : public SIMSolverStat<T1>
123 {
124 public:
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,
191  startRstLevel);
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 
208 protected:
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 
256 public:
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 
299 private:
301 
302 protected:
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
int readData(SerializeData &data, int level=-1, bool basis=false)
Reads restart data from file.
Definition: HDF5Restart.C:160
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 SIMoptions & getOptions()
Returns a reference to the general input options.
Definition: IFEM.h:55
static utl::LogStream cout
Combined standard out for parallel processes.
Definition: IFEM.h:62
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
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
const TimeStep & getTimePrm() const
Returns a const reference to the time stepping information.
Definition: SIMSolver.h:141
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