Changed: Set initial time level for restart runs from previous.

The methods getTimeLevel() and getWritersTimeLevel() are then
no longer needed and removed for the sake of clarity.
Also removed unused method realTimeLevel(), which is incorrect
if used in restart runs with changed data dump stride.
Added: Optional print message when dumping results.
This commit is contained in:
Knut Morten Okstad
2021-05-07 09:44:16 +02:00
parent e2fb65447a
commit 06580f66c7
4 changed files with 40 additions and 54 deletions

View File

@@ -35,6 +35,7 @@ public:
SIMSolverStat(T1& s1, const char* head = nullptr) : SIMadmin(head), S1(s1)
{
exporter = nullptr;
startExpLevel = 0;
}
//! \brief The destructor deletes the results data exporter object.
@@ -52,11 +53,11 @@ public:
int saveInterval = 1)
{
if (IFEM::getOptions().discretization == ASM::Spectral && !hdf5file.empty())
IFEM::cout <<"\n ** HDF5 output is available for spline/lagrangian discretization"
<<" only. Deactivating...\n"<< std::endl;
IFEM::cout <<"\n ** HDF5 output is not available for spectral"
<<" discretization. Deactivating...\n"<< std::endl;
else
{
exporter = new DataExporter(true,saveInterval);
exporter = new DataExporter(true,saveInterval,startExpLevel);
exporter->registerWriter(new HDF5Writer(hdf5file,modelAdm));
S1.registerFields(*exporter);
IFEM::registerCallback(*exporter);
@@ -109,6 +110,7 @@ protected:
T1& S1; //!< The actual solver
DataExporter* exporter; //!< Administrator for result output to HDF5 file
int startExpLevel; //!< Initial time level for the DataExporter
};
@@ -124,7 +126,7 @@ public:
//! \brief The constructor initializes the reference to the actual solver.
explicit SIMSolver(T1& s1) : SIMSolverStat<T1>(s1,"Time integration driver")
{
saveDivergedSol = false;
saveDivergedSol = dumpLog = false;
restartAdm = nullptr;
}
@@ -222,14 +224,13 @@ protected:
if (saveRes && !this->S1.saveStep(tp,nBlock))
return false;
if (saveRes && SIMSolverStat<T1>::exporter) {
if (saveRes && restartAdm && restartAdm->dumpStep(tp)) {
HDF5Restart::SerializeData data;
if (restartAdm && restartAdm->dumpStep(tp) && this->serialize(data))
if (!restartAdm->writeData(tp,data))
return false;
return SIMSolverStat<T1>::exporter->dumpTimeLevel(&tp,newMesh);
if (this->serialize(data) && !restartAdm->writeData(tp,data))
return false;
}
if (saveRes && SIMSolverStat<T1>::exporter)
return SIMSolverStat<T1>::exporter->dumpTimeLevel(&tp,newMesh,dumpLog);
return true;
}
@@ -252,7 +253,11 @@ public:
<<"\n file = "<< restartFile
<<"\n step = "<< restartStep << std::endl;
if (this->deSerialize(data))
{
// Record time level in case we are saving results in the restart also
SIMSolverStat<T1>::startExpLevel = restartStep;
return restartStep+1;
}
else
restartStep = -2;
}
@@ -265,7 +270,8 @@ private:
bool saveDivergedSol; //!< If \e true, save also the diverged solution to VTF
protected:
TimeStep tp; //!< Time stepping information
bool dumpLog; //!< Set to \e true, to print out dump time levels
TimeStep tp; //!< Time stepping information
HDF5Restart* restartAdm; //!< Administrator for restart output
};

View File

@@ -64,6 +64,9 @@ public:
else if (!this->saveState(geoBlk,nBlock))
return 2;
// Activate printing of time level for result dumps
SIMSolver<T1>::dumpLog = true;
// Adaptive loop
while (!this->tp.finished())
{

View File

@@ -92,7 +92,7 @@ bool DataExporter::setFieldValue (const std::string& name,
}
bool DataExporter::dumpTimeLevel (const TimeStep* tp, bool geometryUpdated)
bool DataExporter::dumpTimeLevel (const TimeStep* tp, bool geoUpd, bool doLog)
{
if (tp) {
if (tp->step == m_last_step)
@@ -102,11 +102,19 @@ bool DataExporter::dumpTimeLevel (const TimeStep* tp, bool geometryUpdated)
m_last_step = tp->step;
}
else if (m_level < 0)
for (DataWriter* writer : m_writers) {
int lastLevel = writer->getLastTimeLevel();
if (lastLevel < m_level || m_level < 0)
m_level = lastLevel;
}
PROFILE1("DataExporter::dumpTimeLevel");
if (m_level == -1)
m_level = this->getWritersTimeLevel()+1;
++m_level;
if (tp && doLog)
IFEM::cout <<" Dumping results for step="<< tp->step <<" time="
<< tp->time.t <<" (time level "<< m_level <<")"<< std::endl;
for (DataWriter* writer : m_writers) {
writer->openFile(m_level);
@@ -119,7 +127,7 @@ bool DataExporter::dumpTimeLevel (const TimeStep* tp, bool geometryUpdated)
writer->writeVector(m_level,it);
break;
case SIM:
writer->writeSIM(m_level,it,geometryUpdated,it.second.prefix);
writer->writeSIM(m_level,it,geoUpd,it.second.prefix);
break;
case NODALFORCES:
writer->writeNodalForces(m_level,it);
@@ -141,7 +149,6 @@ bool DataExporter::dumpTimeLevel (const TimeStep* tp, bool geometryUpdated)
writer->closeFile(m_level);
}
m_level++;
// disable fields marked as once
for (std::pair<const std::string,FileEntry>& it : m_entry)
@@ -152,24 +159,6 @@ bool DataExporter::dumpTimeLevel (const TimeStep* tp, bool geometryUpdated)
}
int DataExporter::getTimeLevel ()
{
if (m_level == -1)
m_level = this->getWritersTimeLevel();
return m_level;
}
int DataExporter::getWritersTimeLevel () const
{
std::vector<int> levels;
for (DataWriter* writer : m_writers)
levels.push_back(writer->getLastTimeLevel());
return *min_element(levels.begin(),levels.end());
}
void DataExporter::setNormPrefixes(const std::vector<std::string>& prefix)
{
for (DataWriter* writer : m_writers)
@@ -177,12 +166,6 @@ void DataExporter::setNormPrefixes(const std::vector<std::string>& prefix)
}
int DataExporter::realTimeLevel(int filelevel) const
{
return filelevel*m_ndump;
}
void DataExporter::OnControl(const TiXmlElement* context)
{
const TiXmlElement* child = context->FirstChildElement();

View File

@@ -78,8 +78,9 @@ public:
//! \brief Default constructor.
//! \param[in] dynWriters If \e true, delete the writers on destruction
//! \param[in] ndump Interval between dumps
DataExporter(bool dynWriters = false, int ndump=1) :
m_delete(dynWriters), m_level(-1), m_ndump(ndump), m_last_step(-1) {}
//! \param[in] level0 Time level to start dumping from (in case of restart)
DataExporter(bool dynWriters = false, int ndump = 1, int level0 = 0) :
m_delete(dynWriters), m_ndump(ndump), m_level(level0-1), m_last_step(-1) {}
//! \brief The destructor deletes the writers if \a dynWriters was \e true.
virtual ~DataExporter();
@@ -113,14 +114,10 @@ public:
//! \brief Dumps all registered fields using the registered writers.
//! \param[in] tp Current time stepping info
//! \param[in] geometryUpdated Whether or not geometries are updated
bool dumpTimeLevel(const TimeStep* tp=nullptr, bool geometryUpdated=false);
//! \brief Returns the current time level of the exporter.
int getTimeLevel();
//! \brief Calculates the real time level taking ndump into account.
int realTimeLevel(int filelevel) const;
//! \param[in] geoUpd If \e true, write updated geometry as well
//! \param[in] doLog If \e true, write a log message when dumping data
bool dumpTimeLevel(const TimeStep* tp = nullptr,
bool geoUpd = false, bool doLog = false);
//! \brief Sets the prefices used for norm output.
void setNormPrefixes(const std::vector<std::string>& prefixes);
@@ -137,17 +134,14 @@ public:
int getStride() const { return m_ndump; }
protected:
//! \brief Internal helper function.
int getWritersTimeLevel() const;
//! A map of field names -> field info structures
std::map<std::string,FileEntry> m_entry;
//! A vector of registered data writers
std::vector<DataWriter*> m_writers;
bool m_delete; //!< If true, we are in charge of freeing up datawriters
int m_level; //!< Current time level
int m_ndump; //!< Time level stride for dumping
int m_level; //!< Current time level
int m_last_step; //!< Last time step we dumped for
};