Commit 41212019 authored by Chris Cantwell's avatar Chris Cantwell

Merge branch 'fix/dont_overwrite_chk' into 'master'

dont overwrite chk files if the solver was restarted

in case f a restart, read the number from the restart file and use this as starting point for the next chk files, so that when restarting from foo_215.chk, the first chk file written is not foo_0.chk but foo_215_0.chk (which contains the initial conditions and should in most cases be identical to foo_215.chk). The next file will be foo_216.chk with the new timestep.

In case foo_215_0.chk already exists, we write foo_215_1.chk and so on.

The filters still overwrite everything, maybe we should change that too?

See merge request !707
parents fd5eb756 b7b72298
......@@ -85,6 +85,7 @@ enum FieldIOType {
eHDF5
};
/**
* @brief Determine file type of given input file.
*
......@@ -234,7 +235,8 @@ FieldIOSharedPtr FieldIO::CreateForFile(
void Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap)
const FieldMetaDataMap &fieldinfomap,
const bool backup)
{
#ifdef NEKTAR_USE_MPI
int size;
......@@ -256,7 +258,7 @@ void Write(const std::string &outFile,
#endif
CommSharedPtr c = GetCommFactory().CreateInstance("Serial", 0, 0);
FieldIOSharedPtr f = GetFieldIOFactory().CreateInstance("Xml", c, false);
f->Write(outFile, fielddefs, fielddata, fieldinfomap);
f->Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
}
/**
......@@ -395,7 +397,7 @@ void FieldIO::AddInfoTag(TagWriterSharedPtr root,
*
* @return Absolute path to resulting file.
*/
std::string FieldIO::SetUpOutput(const std::string outname, bool perRank)
std::string FieldIO::SetUpOutput(const std::string outname, bool perRank, bool backup)
{
ASSERTL0(!outname.empty(), "Empty path given to SetUpOutput()");
......@@ -406,6 +408,37 @@ std::string FieldIO::SetUpOutput(const std::string outname, bool perRank)
// serial.
fs::path specPath(outname), fulloutname;
// in case we are rank 0 or not on a shared filesystem, check if the specPath already exists
if (backup && (rank == 0 || !m_sharedFilesystem) && fs::exists(specPath))
{
// rename. foo/bar_123.chk -> foo/bar_123.bak0.chk and in case
// foo/bar_123.bak0.chk already exists, foo/bar_123.chk -> foo/bar_123.bak1.chk
fs::path bakPath = specPath;
int cnt = 0;
while (fs::exists(bakPath))
{
bakPath = specPath.parent_path();
bakPath += specPath.stem();
bakPath += fs::path(".bak" + boost::lexical_cast<std::string>(cnt++));
bakPath += specPath.extension();
}
std::cout << "renaming " << specPath << " -> " << bakPath << std::endl;
try
{
fs::rename(specPath, bakPath);
}
catch (fs::filesystem_error &e)
{
ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
"Filesystem error: " + string(e.what()));
}
}
// wait until rank 0 has backed up the old specPath
if (backup)
{
m_comm->Block();
}
if (nprocs == 1)
{
fulloutname = specPath;
......
......@@ -184,7 +184,8 @@ LIB_UTILITIES_EXPORT void Write(
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap);
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const bool backup = false);
LIB_UTILITIES_EXPORT void Import(
const std::string &infilename,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
......@@ -234,7 +235,8 @@ public:
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap);
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const bool backup = false);
LIB_UTILITIES_EXPORT inline void Import(
const std::string &infilename,
......@@ -280,14 +282,15 @@ protected:
}
LIB_UTILITIES_EXPORT std::string SetUpOutput(
const std::string outname, bool perRank);
const std::string outname, bool perRank, bool backup = false);
/// @copydoc FieldIO::Write
LIB_UTILITIES_EXPORT virtual void v_Write(
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap) = 0;
const FieldMetaDataMap &fieldinfomap,
const bool backup = false) = 0;
/// @copydoc FieldIO::Import
LIB_UTILITIES_EXPORT virtual void v_Import(
......@@ -317,9 +320,10 @@ typedef boost::shared_ptr<FieldIO> FieldIOSharedPtr;
inline void FieldIO::Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap)
const FieldMetaDataMap &fieldinfomap,
const bool backup)
{
v_Write(outFile, fielddefs, fielddata, fieldinfomap);
v_Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
}
/**
......
......@@ -173,7 +173,8 @@ FieldIOHdf5::FieldIOHdf5(LibUtilities::CommSharedPtr pComm,
void FieldIOHdf5::v_Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldmetadatamap)
const FieldMetaDataMap &fieldmetadatamap,
const bool backup)
{
std::stringstream prfx;
prfx << m_comm->GetRank() << ": FieldIOHdf5::v_Write(): ";
......@@ -184,7 +185,7 @@ void FieldIOHdf5::v_Write(const std::string &outFile,
tm0 = m_comm->Wtime();
}
SetUpOutput(outFile, false);
SetUpOutput(outFile, false, backup);
// We make a number of assumptions in this code:
// 1. All element ids have the same type: unsigned int
......
......@@ -241,7 +241,8 @@ private:
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap);
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const bool backup = false);
LIB_UTILITIES_EXPORT virtual void v_Import(
const std::string &infilename,
......
......@@ -87,7 +87,8 @@ FieldIOXml::FieldIOXml(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
void FieldIOXml::v_Write(const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldmetadatamap)
const FieldMetaDataMap &fieldmetadatamap,
const bool backup)
{
double tm0 = 0.0, tm1 = 0.0;
if (m_comm->GetRank() == 0)
......@@ -112,7 +113,7 @@ void FieldIOXml::v_Write(const std::string &outFile,
// Prepare to write out data. In parallel, we must create directory and
// determine the full pathname to the file to write out. Any existing
// file/directory which is in the way is removed.
std::string filename = SetUpOutput(outFile, true);
std::string filename = SetUpOutput(outFile, true, backup);
SetUpFieldMetaData(outFile, fielddefs, fieldmetadatamap);
// Create the file (partition)
......
......@@ -242,7 +242,8 @@ private:
const std::string &outFile,
std::vector<FieldDefinitionsSharedPtr> &fielddefs,
std::vector<std::vector<NekDouble> > &fielddata,
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap);
const FieldMetaDataMap &fieldinfomap = NullFieldMetaDataMap,
const bool backup = false);
LIB_UTILITIES_EXPORT virtual DataSourceSharedPtr v_ImportFieldMetaData(
const std::string &filename, FieldMetaDataMap &fieldmetadatamap);
......
......@@ -54,55 +54,6 @@ namespace Nektar
namespace LibUtilities
{
void Import(const string &inFile, PtsFieldSharedPtr &ptsField)
{
#ifdef NEKTAR_USE_MPI
int size;
int init;
MPI_Initialized(&init);
// If MPI has been initialised we can check the number of processes
// and, if > 1, tell the user he should not be running this
// function in parallel. If it is not initialised, we do not
// initialise it here, and assume the user knows what they are
// doing.
if (init)
{
MPI_Comm_size(MPI_COMM_WORLD, &size);
ASSERTL0(size == 1,
"This static function is not available in parallel. Please "
"instantiate a FieldIO object for parallel use.");
}
#endif
CommSharedPtr c = GetCommFactory().CreateInstance("Serial", 0, 0);
PtsIO p(c);
p.Import(inFile, ptsField);
}
void Write(const string &outFile, const PtsFieldSharedPtr &ptsField)
{
#ifdef NEKTAR_USE_MPI
int size;
int init;
MPI_Initialized(&init);
// If MPI has been initialised we can check the number of processes
// and, if > 1, tell the user he should not be running this
// function in parallel. If it is not initialised, we do not
// initialise it here, and assume the user knows what they are
// doing.
if (init)
{
MPI_Comm_size(MPI_COMM_WORLD, &size);
ASSERTL0(size == 1,
"This static function is not available in parallel. Please "
"instantiate a FieldIO object for parallel use.");
}
#endif
CommSharedPtr c = GetCommFactory().CreateInstance("Serial", 0, 0);
PtsIO p(c);
p.Write(outFile, ptsField);
}
PtsIO::PtsIO(CommSharedPtr pComm, bool sharedFilesystem)
: FieldIOXml(pComm, sharedFilesystem)
......@@ -202,12 +153,13 @@ void PtsIO::Import(const string &inFile,
* @param ptsField the pts field
*/
void PtsIO::Write(const string &outFile,
const Nektar::LibUtilities::PtsFieldSharedPtr &ptsField)
const Nektar::LibUtilities::PtsFieldSharedPtr &ptsField,
const bool backup)
{
int nTotvars = ptsField->GetNFields() + ptsField->GetDim();
int np = ptsField->GetNpoints();
std::string filename = SetUpOutput(outFile, true);
std::string filename = SetUpOutput(outFile, true, backup);
SetUpFieldMetaData(outFile);
// until tinyxml gains support for line break, write the xml manually
......
......@@ -61,12 +61,6 @@ using namespace std;
typedef std::map<std::string, std::string> PtsMetaDataMap;
static PtsMetaDataMap NullPtsMetaDataMap;
LIB_UTILITIES_EXPORT void Import(const string &inFile,
PtsFieldSharedPtr &ptsField);
LIB_UTILITIES_EXPORT void Write(const string &outFile,
const PtsFieldSharedPtr &ptsField);
class PtsIO : public FieldIOXml
{
public:
......@@ -83,7 +77,8 @@ public:
FieldMetaDataMap &fieldmetadatamap = NullFieldMetaDataMap);
LIB_UTILITIES_EXPORT void Write(const string &outFile,
const PtsFieldSharedPtr &ptsField);
const PtsFieldSharedPtr &ptsField,
const bool backup = false);
LIB_UTILITIES_EXPORT void ImportFieldData(TiXmlDocument docInput,
PtsFieldSharedPtr &ptsField);
......
......@@ -109,6 +109,7 @@ namespace Nektar
string sessionname = "SessionName";
sessionname += boost::lexical_cast<std::string>(i);
m_fieldMetaDataMap[sessionname] = filenames[i];
m_fieldMetaDataMap["ChkFileNum"] = boost::lexical_cast<std::string>(0);
}
}
......@@ -661,7 +662,7 @@ namespace Nektar
m_session->LoadParameter("NumQuadPointsError",
m_NumQuadPointsError, 0);
m_nchk = 1;
m_nchk = 0;
// Zero all physical fields initially
ZeroPhysFields();
......@@ -1237,11 +1238,11 @@ namespace Nektar
if (dumpInitialConditions && m_checksteps)
{
Checkpoint_Output(0);
Checkpoint_Output(m_nchk);
m_nchk++;
}
}
void EquationSystem::v_EvaluateExactSolution(
unsigned int field,
Array<OneD, NekDouble> &outfield,
......@@ -1986,7 +1987,6 @@ namespace Nektar
{
std::string outname = m_sessionName + "_" +
boost::lexical_cast<std::string>(n);
WriteFld(outname + ".chk");
}
......@@ -2000,9 +2000,8 @@ namespace Nektar
std::vector<Array<OneD, NekDouble> > &fieldcoeffs,
std::vector<std::string> &variables)
{
char chkout[16] = "";
sprintf(chkout, "%d", n);
std::string outname = m_sessionName + "_" + chkout + ".chk";
std::string outname = m_sessionName + "_" +
boost::lexical_cast<std::string>(n);
WriteFld(outname, field, fieldcoeffs, variables);
}
......@@ -2086,6 +2085,12 @@ namespace Nektar
{
m_fieldMetaDataMap["Time"] = boost::lexical_cast<std::string>(m_time);
}
// Update step in field info if required
if(m_fieldMetaDataMap.find("ChkFileNum") != m_fieldMetaDataMap.end())
{
m_fieldMetaDataMap["ChkFileNum"] = boost::lexical_cast<std::string>(m_nchk);
}
// If necessary, add mapping information to metadata
// and output mapping coordinates
......@@ -2096,7 +2101,7 @@ namespace Nektar
LibUtilities::FieldMetaDataMap fieldMetaDataMap(m_fieldMetaDataMap);
mapping->Output( fieldMetaDataMap, outname);
m_fld->Write(outname, FieldDef, FieldData, fieldMetaDataMap);
m_fld->Write(outname, FieldDef, FieldData, fieldMetaDataMap, true);
}
......
......@@ -376,7 +376,8 @@ namespace Nektar
transformed[i] = true;
}
}
Checkpoint_Output(m_nchk++);
Checkpoint_Output(m_nchk);
m_nchk++;
for(i = 0; i < nfields; i++)
{
if (transformed[i])
......@@ -391,7 +392,8 @@ namespace Nektar
}
else
{
Checkpoint_Output(m_nchk++);
Checkpoint_Output(m_nchk);
m_nchk++;
}
doCheckTime = false;
}
......@@ -456,7 +458,7 @@ namespace Nektar
*/
void UnsteadySystem::v_DoInitialise()
{
CheckForRestartTime(m_time);
CheckForRestartTime(m_time, m_nchk);
SetBoundaryConditions(m_time);
SetInitialConditions(m_time);
}
......@@ -695,7 +697,7 @@ namespace Nektar
}
}
void UnsteadySystem::CheckForRestartTime(NekDouble &time)
void UnsteadySystem::CheckForRestartTime(NekDouble &time, int &nchk)
{
if (m_session->DefinesFunction("InitialConditions"))
{
......@@ -738,6 +740,13 @@ namespace Nektar
time = boost::lexical_cast<NekDouble>(
iter->second);
}
iter = m_fieldMetaDataMap.find("ChkFileNum");
if (iter != m_fieldMetaDataMap.end())
{
nchk = boost::lexical_cast<NekDouble>(
iter->second);
}
}
break;
......
......@@ -142,7 +142,7 @@ namespace Nektar
return true;
}
SOLVER_UTILS_EXPORT void CheckForRestartTime(NekDouble &time);
SOLVER_UTILS_EXPORT void CheckForRestartTime(NekDouble &time, int &nchk);
/// \brief Evaluate the SVV diffusion coefficient
/// according to Moura's paper where it should
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment