IFEM 90A354
SIMSolverTS.h
Go to the documentation of this file.
1// $Id$
2//==============================================================================
12//==============================================================================
13
14#ifndef _SIM_SOLVER_TS_H_
15#define _SIM_SOLVER_TS_H_
16
17#include "SIMSolver.h"
18
19
30template<class T1> class SIMSolverTS : public SIMSolver<T1>
31{
32public:
35 {
37 maxRef = 2;
38 preRef = 0;
39 refTol = 0.0;
40 minFrac = 0.1;
41 aStart = beta = -1.0;
42 dumpGrid = 0;
43 lastRLev = -1;
44 }
45
47 virtual ~SIMSolverTS() {}
48
50 virtual bool read(const char* file)
51 {
52 if (!this->SIMadmin::read(file))
53 return false;
54 else if (preRef < 1)
55 return true;
56
57 // Perform some pre-refinement to resolve geometric features, etc.
58 return this->S1.preRefine(maxRef,preRef,refTol);
59 }
60
62 virtual int solveProblem(char* infile, const char* heading)
63 {
64 if (this->tp.step == 0)
65 {
66 // Perform some initial refinement to resolve geometric features, etc.
67 if (maxRef > preRef && !this->S1.initialRefine(beta,minFrac,maxRef))
68 return 4;
69
70 // Dump the initial (refined) mesh
71 if (maxRef > preRef || preRef > 0)
72 this->dumpMesh(infile,false);
73 }
74
75 // Save the initial FE model (and state) to VTF and HDF5 for visualization
76 int geoBlk = 0, nBlock = 0;
77 if (!this->saveState(geoBlk,nBlock,true,infile,preRef<1))
78 return 2;
79
80 this->printHeading(heading);
81
82 // Pre-adaptive loop, solve for a certain time period on the initial mesh
83 while (this->tp.time.t < aStart-1.0e-12 && this->advanceStep())
84 if (!this->S1.solveStep(this->tp))
85 return 3;
86 else if (!this->saveState(geoBlk,nBlock))
87 return 2;
88
89 // Activate printing of time level for result dumps
91
92 // Adaptive loop
93 while (!this->tp.finished())
94 {
95 this->S1.saveState(); // Save current solution state internally
96 int tranStep = this->tp.step; // Time step of next solution transfer
97 int lastRef = 1, refElms = 0;
98
99 // Prediction cycle loop, disable staggering cycles
100 if (maxPred < 0) this->S1.enableStaggering(false);
101 for (int iPred = 0; iPred < abs(maxPred) && lastRef > 0; iPred++)
102 {
103 lastRef = 0;
104 if (iPred > 0)
105 {
106 // Reset time step counter to the last saved state
107 this->tp.reset(tranStep);
108 // Save current solution state internally for the refined mesh
109 this->S1.saveState();
110 }
111
112 // Solve for (up to) nPredict steps without saving results on disk
113 for (size_t i = 0; i < nPredict && this->advanceStep(); i++)
114 if (!this->S1.solveStep(this->tp))
115 return 3;
116
117 if (maxPred > 0 && this->S1.stopped())
118 break; // Terminated due to other user-criterion
119 else if (this->tp.finished())
120 break; // Stop time reached
121
122 // Adapt the mesh based on current solution, and
123 // transfer the old solution variables onto the new mesh
124 IFEM::cout <<"\n >>> Paused for mesh refinement at time="
125 << this->tp.time.t << std::endl;
126 if ((lastRef = this->S1.adaptMesh(beta,minFrac,maxRef)))
127 this->dumpMesh(infile,false);
128
129 refElms += lastRef; // Total number of refined elements
130 }
131
132 if (lastRef < 0)
133 return 4; // Something went wrong, bailing
134 else if (refElms == 0 && !this->tp.finished() && !this->S1.stopped())
135 IFEM::cout <<" No refinement, resume from current state"<< std::endl;
136
137 if (lastRef == 0 && maxPred > 0)
138 {
139 // The mesh is sufficiently refined at this state.
140 // Save the current results to VTF and HDF5, and continue.
141 // Note: We then miss the results from the preceding nPredict-1 steps.
142 if (!this->saveState(geoBlk,nBlock,refElms > 0))
143 return 2;
144 }
145 else
146 {
147 // Either the mesh was refined or we were doing prediction steps
148 // without staggering cycles. Now continue (at most) nForward steps
149 // without checking for further refinement at those steps.
150 this->tp.reset(tranStep);
151 IFEM::cout <<"\n >>> Resuming simulation from time="<< this->tp.time.t;
152 if (lastRef > 0)
153 {
154 IFEM::cout <<" on the new mesh."<< std::endl;
156 lastRLev = SIMSolver<T1>::restartAdm->getTimeLevel()+1;
157 }
158 else
159 {
160 IFEM::cout <<" on current mesh."<< std::endl;
161 this->S1.restoreState(); // Solution transfer was not performed
162 }
163
164 // Solve for each time step up to final time,
165 // but only up to nForward steps on this mesh
166 this->S1.enableStaggering(true);
167 for (size_t j = 0; j < nForward && this->advanceStep(); j++)
168 if (!this->S1.solveStep(this->tp))
169 return 3;
170 else if (!this->saveState(geoBlk,nBlock,j < 1))
171 return 2;
172 }
173 }
174
175 return this->dumpMesh(infile) ? 0 : 2;
176 }
177
181 {
182 if (lastRLev < 0 && SIMSolver<T1>::restartAdm && this->S1.getRefined())
183 lastRLev = SIMSolver<T1>::restartAdm->getTimeLevel()+1;
184
185 if (lastRLev >= 0)
186 data[this->S1.getName()+"::basis"] = std::to_string(lastRLev);
187 return this->SIMSolver<T1>::serialize(data);
188 }
189
190protected:
191 using SIMSolver<T1>::parse;
193 virtual bool parse(const tinyxml2::XMLElement* elem)
194 {
195 if (strcasecmp(elem->Value(),"adaptive"))
196 return this->SIMSolver<T1>::parse(elem);
197
198 utl::getAttribute(elem,"start",aStart);
199 utl::getAttribute(elem,"dump",dumpGrid);
201
202 const char* value = nullptr;
203 const tinyxml2::XMLElement* child = elem->FirstChildElement();
204 for (; child; child = child->NextSiblingElement())
205 if ((value = utl::getValue(child,"forward_steps")))
206 nForward = atoi(value);
207 else if ((value = utl::getValue(child,"predict_steps")))
208 nPredict = atoi(value);
209 else if ((value = utl::getValue(child,"beta")))
210 beta = atof(value);
211 else if ((value = utl::getValue(child,"nrefinements")))
212 maxRef = atoi(value);
213 else if ((value = utl::getValue(child,"max_prediction")))
214 maxPred = atoi(value);
215 else if ((value = utl::getValue(child,"min_frac")))
216 minFrac = atof(value);
217 else if (this->S1.getRefined())
218 continue; // ignore pre-refinement tags if mesh already refined
219 else if ((value = utl::getValue(child,"prerefine")))
220 {
221 if (utl::getAttribute(child,"levels",preRef))
222 this->S1.parsePreref(child);
223 else
224 preRef = atoi(value);
225 utl::getAttribute(child,"tol",refTol);
226 }
227 else if (!strcasecmp(child->Value(),"prerefine"))
228 {
229 utl::getAttribute(child,"levels",preRef);
230 utl::getAttribute(child,"tol",refTol);
231 }
232
233 if (preRef > 0)
234 IFEM::cout <<"\tNumber of pre-refinement cycles: "<< preRef
235 <<"\n\tPre-refinement tolerance: "<< refTol <<"\n";
236 IFEM::cout <<"\tNumber of trial steps before refinement: "<< nPredict
237 <<"\n\tNumber of steps between each refinement: "<< nForward
238 <<"\n\tMax. number of trial cycles at refinement: "<< maxPred
239 <<"\n\tMax. number of refinements of an element: "<< maxRef
240 <<"\n\tRelative refinement threshold: "<< minFrac;
241 if (beta > 0.0)
242 IFEM::cout <<"\n\tPercentage of elements to refine: "<< beta;
243 if (aStart > 0.0)
244 IFEM::cout <<"\n\tMesh adaptation starting at time: "<< aStart;
245
246 IFEM::cout << std::endl;
247 return true;
248 }
249
251 bool dumpMesh(char* infile, bool done = true) const
252 {
253 if (dumpGrid < 1)
254 return true;
255 else if (dumpGrid == 1) // Dump the final grid only
256 return done ? this->S1.dumpMesh(strcat(strtok(infile,"."),".lr")) : true;
257 else if (done)
258 return true;
259
260 // Dump grid after each refinement step
261 char fileName[128];
262 static int gridNo = 1;
263 sprintf(fileName,"%s_m%d.lr",strtok(infile,"."),++gridNo);
264 return this->S1.dumpMesh(fileName);
265 }
266
267private:
268 size_t nForward;
269 size_t nPredict;
271 int maxRef;
272 int preRef;
273 double refTol;
274 double minFrac;
275 double beta;
276 double aStart;
277 char dumpGrid;
279};
280
281#endif
SIM solver class template.
static const double T1[2]
1-point rule coordinates.
Definition TriangleQuadrature.C:19
std::map< std::string, std::string > SerializeData
Convenience type.
Definition HDF5Restart.h:34
static utl::LogStream cout
Combined standard out for parallel processes.
Definition IFEM.h:62
T1 & S1
The actual solver.
Definition SIMSolver.h:109
void printHeading(const char *heading)
Writes an application-specific heading, if provided.
Definition SIMSolver.h:69
Template class for time-slab adaptive simulator drivers.
Definition SIMSolverTS.h:31
int maxPred
Maximum number of prediction cycles.
Definition SIMSolverTS.h:270
virtual int solveProblem(char *infile, const char *heading)
Solves the problem up to the final time.
Definition SIMSolverTS.h:62
virtual ~SIMSolverTS()
Empty destructor.
Definition SIMSolverTS.h:47
double refTol
Pre-refinement threshold.
Definition SIMSolverTS.h:273
int maxRef
Number of refinements to allow for a single element.
Definition SIMSolverTS.h:271
virtual bool read(const char *file)
Reads solver data from the specified input file.
Definition SIMSolverTS.h:50
bool dumpMesh(char *infile, bool done=true) const
Dumps the refined LR-mesh to file.
Definition SIMSolverTS.h:251
virtual bool serialize(HDF5Restart::SerializeData &data)
Serialize internal state for restarting purposes.
Definition SIMSolverTS.h:180
int preRef
Number of pre-refinement cycles.
Definition SIMSolverTS.h:272
virtual bool parse(const tinyxml2::XMLElement *elem)
Parses a data section from an XML element.
Definition SIMSolverTS.h:193
size_t nForward
Number of steps to advance on new mesh.
Definition SIMSolverTS.h:268
size_t nPredict
Number of steps to use for prediction.
Definition SIMSolverTS.h:269
double aStart
Time from where to check for mesh adaptation.
Definition SIMSolverTS.h:276
char dumpGrid
Option for mesh output: 0=none, 1=last, 2=all.
Definition SIMSolverTS.h:277
double beta
Percentage of elements to refine.
Definition SIMSolverTS.h:275
SIMSolverTS(T1 &s1)
The constructor forwards to the parent class constructor.
Definition SIMSolverTS.h:34
int lastRLev
Restart time level for last mesh refinement.
Definition SIMSolverTS.h:278
double minFrac
Element-level refinement threshold.
Definition SIMSolverTS.h:274
Template class for transient simulator drivers.
Definition SIMSolver.h:123
bool advanceStep()
Advances the time step one step forward.
Definition SIMSolver.h:144
TimeStep tp
Time stepping information.
Definition SIMSolver.h:304
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(char *keyw, std::istream &is)
Parses a data section from an input stream.
Definition SIMSolver.h:210
virtual bool read(const char *fileName)
Reads model data from the specified input file *fileName.
Definition SIMadmin.C:68
int step
Time step counter.
Definition TimeStep.h:72
bool reset(int istep=0)
Resets the time step to the specified step.
Definition TimeStep.C:203
bool finished() const
Returns true if the end of the simulation has been reached.
Definition TimeStep.C:331
TimeDomain time
Time domain data.
Definition TimeStep.h:74
const char * getValue(const tinyxml2::XMLNode *xml, const char *tag)
Returns the value (if any) of the specified XML-node.
Definition Utilities.C:335
int getAttribute(const tinyxml2::XMLElement *xml, const char *att, bool &val)
Extracts a boolean attribute value from the specified XML-element.
Definition Utilities.C:204
double t
Current time (or pseudo time, load parameter)
Definition TimeDomain.h:24