35#include <boost/asio/ip/host_name.hpp>
36#include <boost/format.hpp>
55#define NEKTAR_VERSION "Unknown"
58namespace ip = boost::asio::ip;
64 "io-format",
"i",
"Default input/output format (e.g. Xml, Hdf5)");
98 int size = comm->GetSpaceComm()->GetSize();
99 bool root = comm->GetSpaceComm()->TreatAsRankZero();
101 if (size == 1 || root)
103 std::string datafilename;
106 if (fs::is_directory(filename))
108 fs::path fullpath = filename;
109 fs::path
d = fullpath;
110 std::regex expr(
"P\\d{7}.fld");
114 for (
auto &f : fs::directory_iterator(
d))
116 std::string filename = f.path().filename().string();
117 if (std::regex_match(filename, what, expr))
125 ASSERTL0(found, std::string(
"Failed to open a PXXXXXXX.fld file "
134 datafilename = filename;
140 const unsigned char magic[8] = {0x89, 0x48, 0x44, 0x46,
141 0x0d, 0x0a, 0x1a, 0x0a};
143 std::ifstream datafile(datafilename.c_str(), std::ios_base::binary);
144 ASSERTL0(datafile.good(),
"Unable to open file: " + filename);
147 for (
unsigned i = 0; i < 8 && datafile.good(); ++i)
149 int byte = datafile.get();
150 if (
byte != magic[i])
160 int code = (int)ioType;
161 comm->GetSpaceComm()->Bcast(code, 0);
170 else if (ioType ==
eHDF5)
197 std::string iofmt(
"Xml");
198 if (session->DefinesSolverInfo(
"IOFormat"))
200 iofmt = session->GetSolverInfo(
"IOFormat");
203 if (session->DefinesCmdLineArgument(
"io-format"))
205 iofmt = session->GetCmdLineArgument<std::string>(
"io-format");
209 session->GetSharedFilesystem());
225 const std::string &filename)
227 const std::string iofmt =
230 session->GetSharedFilesystem());
244void Write(
const std::string &outFile,
245 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
246 std::vector<std::vector<NekDouble>> &fielddata,
252 MPI_Initialized(&init);
261 MPI_Comm_size(MPI_COMM_WORLD, &size);
263 "This static function is not available in parallel. Please"
264 "instantiate a FieldIO object for parallel use.");
269 f->Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
288 const std::string &infilename,
289 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
290 std::vector<std::vector<NekDouble>> &fielddata,
296 MPI_Initialized(&init);
305 MPI_Comm_size(MPI_COMM_WORLD, &size);
307 "This static function is not available in parallel. Please"
308 "instantiate a FieldIO object for parallel use.");
314 f->Import(infilename, fielddefs, fielddata, fieldinfomap, ElementIDs);
321 : m_comm(pComm), m_sharedFilesystem(sharedFilesystem)
350 auto now = std::chrono::system_clock::now();
351 auto now_t = std::chrono::system_clock::to_time_t(now);
352 auto now_tm = *std::localtime(&now_t);
354 strftime(
buffer,
sizeof(
buffer),
"%d-%b-%Y %H:%M:%S", &now_tm);
355 ProvenanceMap[
"Timestamp"] =
buffer;
358 boost::system::error_code ec;
359 ProvenanceMap[
"Hostname"] = ip::host_name(ec);
372 for (
auto &infoit : ProvenanceMap)
374 provTag->SetAttr(infoit.first, infoit.second);
381 for (
auto &infoit : fieldmetadatamap)
383 infoTag->SetAttr(infoit.first, infoit.second);
406 ASSERTL0(!outname.empty(),
"Empty path given to SetUpOutput()");
409 std::size_t file_id = std::hash<std::string>{}(outname);
412 std::size_t file_id_max{file_id};
413 std::size_t file_id_min{file_id};
418 ASSERTL0(file_id_min == file_id_max,
419 "All processes do not have the same filename.");
421 int nprocs =
m_comm->GetSpaceComm()->GetSize();
422 bool root =
m_comm->GetSpaceComm()->TreatAsRankZero();
426 fs::path specPath(outname), fulloutname;
435 fs::path bakPath = specPath;
437 while (fs::exists(bakPath))
439 bakPath = specPath.parent_path();
440 bakPath += fs::path(bakPath.extension() ==
".pit" ?
"/" :
"");
441 bakPath += specPath.stem();
442 bakPath += fs::path(
".bak" + std::to_string(cnt++));
443 bakPath += specPath.extension();
445 std::cout <<
"renaming " << specPath <<
" -> " << bakPath << std::endl;
448 fs::rename(specPath, bakPath);
450 catch (fs::filesystem_error &e)
452 ASSERTL0(e.code() == fserrc::no_such_file_or_directory,
453 "Filesystem error: " + std::string(e.what()));
461 m_comm->GetSpaceComm()->Block();
463 while (exists && perRank)
465 exists = fs::exists(specPath);
472 fulloutname = specPath;
481 fs::path poutfile(pad.str());
482 fulloutname = specPath / poutfile;
486 if (
m_comm->GetSpaceComm()->RemoveExistingFiles() && !backup)
495 fs::remove_all(fulloutname);
497 catch (fs::filesystem_error &e)
499 ASSERTL0(e.code() == fserrc::no_such_file_or_directory,
500 "Filesystem error: " + std::string(e.what()));
504 m_comm->GetSpaceComm()->Block();
511 fs::remove_all(specPath);
513 catch (fs::filesystem_error &e)
515 ASSERTL0(e.code() == fserrc::no_such_file_or_directory,
516 "Filesystem error: " + std::string(e.what()));
522 m_comm->GetSpaceComm()->Block();
524 while (exists && perRank)
526 exists = fs::exists(specPath);
533 std::cout <<
"Writing: \"" + specPath.string() +
534 (
m_comm->IsParallelInTime() ?
"\"\n" :
"\"");
550 fs::create_directory(specPath);
553 catch (fs::filesystem_error &e)
556 "Filesystem error: " + std::string(e.what()));
559 m_comm->GetSpaceComm()->Block();
565 created = fs::is_directory(specPath);
571 fulloutname = specPath;
591 switch (fielddefs->m_shapeType)
595 int l = fielddefs->m_numModes[cnt++];
596 if (fielddefs->m_numHomogeneousDir == 1)
598 NCoeffs = l * fielddefs->m_homogeneousZIDs.size();
601 else if (fielddefs->m_numHomogeneousDir == 2)
603 NCoeffs = l * fielddefs->m_homogeneousYIDs.size();
614 int l = fielddefs->m_numModes[cnt++];
615 int m = fielddefs->m_numModes[cnt++];
616 if (fielddefs->m_numHomogeneousDir == 1)
619 fielddefs->m_homogeneousZIDs.size();
630 int l = fielddefs->m_numModes[cnt++];
631 int m = fielddefs->m_numModes[cnt++];
632 if (fielddefs->m_numHomogeneousDir == 1)
635 fielddefs->m_homogeneousZIDs.size();
646 int l = fielddefs->m_numModes[cnt++];
647 int m = fielddefs->m_numModes[cnt++];
648 int n = fielddefs->m_numModes[cnt++];
654 int l = fielddefs->m_numModes[cnt++];
655 int m = fielddefs->m_numModes[cnt++];
656 int n = fielddefs->m_numModes[cnt++];
662 int l = fielddefs->m_numModes[cnt++];
663 int m = fielddefs->m_numModes[cnt++];
664 int n = fielddefs->m_numModes[cnt++];
670 int l = fielddefs->m_numModes[cnt++];
671 int m = fielddefs->m_numModes[cnt++];
672 int n = fielddefs->m_numModes[cnt++];
692 if (fielddefs->m_elementIDs.size() == 0)
697 unsigned int numbasis = 0;
700 switch (fielddefs->m_shapeType)
704 if (fielddefs->m_numHomogeneousDir)
706 numbasis += fielddefs->m_numHomogeneousDir;
712 if (fielddefs->m_numHomogeneousDir)
732 ASSERTL0(fielddefs->m_basis.size() == numbasis,
733 "Length of basis vector is incorrect");
735 if (fielddefs->m_uniOrder ==
true)
738 unsigned int cnt = 0;
742 return datasize * fielddefs->m_elementIDs.size();
747 unsigned int cnt = 0;
751 for (
int i = 0; i < fielddefs->m_elementIDs.size(); ++i)
770 std::vector<unsigned int> coeffsPerElmt;
773 if (fielddefs->m_elementIDs.size() == 0)
775 return coeffsPerElmt;
779 coeffsPerElmt.resize(fielddefs->m_elementIDs.size());
781 if (fielddefs->m_uniOrder ==
true)
784 unsigned int cnt = 0;
788 for (
int i = 0; i < fielddefs->m_elementIDs.size(); ++i)
790 coeffsPerElmt[i] = datasize;
796 unsigned int cnt = 0;
798 for (
int i = 0; i < fielddefs->m_elementIDs.size(); ++i)
804 return coeffsPerElmt;
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define LIB_UTILITIES_EXPORT
int CheckFieldDefinition(const FieldDefinitionsSharedPtr &fielddefs)
Check field definitions for correctness and return storage size.
static const std::string GetFileType(const std::string &filename, CommSharedPtr comm)
Determine file type of given input file.
std::vector< unsigned int > GetNumberOfCoeffsPerElement(const FieldDefinitionsSharedPtr &fielddefs)
Compute number of data points needed to store expansion inside each element.
bool m_sharedFilesystem
Boolean dictating whether we are on a shared filesystem.
static std::shared_ptr< FieldIO > CreateForFile(const LibUtilities::SessionReaderSharedPtr session, const std::string &filename)
Construct a FieldIO object for a given input filename.
static std::shared_ptr< FieldIO > CreateDefault(const LibUtilities::SessionReaderSharedPtr session)
Returns an object for the default FieldIO method.
std::string SetUpOutput(const std::string outname, bool perRank, bool backup=false)
Set up the filesystem ready for output.
LibUtilities::CommSharedPtr m_comm
Communicator to use when writing parallel format.
FieldIO(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
Constructor for FieldIO base class.
std::string GetFileEnding() const
Helper function that determines default file extension.
static void AddInfoTag(TagWriterSharedPtr root, const FieldMetaDataMap &fieldmetadatamap)
Add provenance information to the field metadata map.
Provides a generic Factory class.
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
static std::string RegisterCmdLineArgument(const std::string &pName, const std::string &pShortName, const std::string &pDescription)
Registers a command-line argument with the session reader.
int getNumberOfCoefficients(int Na, int Nb, int Nc)
int getNumberOfCoefficients(int Na, int Nb, int Nc)
int getNumberOfCoefficients(int Na, int Nb, int Nc)
int getNumberOfCoefficients(int Na, int Nb)
int getNumberOfCoefficients(int Na, int Nb, int Nc)
int getNumberOfCoefficients(int Na, int Nb)
int GetNumberOfDataPoints(const FieldDefinitionsSharedPtr &fielddefs, unsigned int &cnt)
Compute the number of values needed to store elemental expansion.
FieldIOType
Enumerator for auto-detection of FieldIO types.
void Import(const std::string &infilename, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, FieldMetaDataMap &fieldinfomap, const Array< OneD, int > &ElementIDs)
This function allows for data to be imported from an FLD file when a session and/or communicator is n...
std::shared_ptr< TagWriter > TagWriterSharedPtr
std::shared_ptr< FieldIO > FieldIOSharedPtr
std::map< std::string, std::string > FieldMetaDataMap
static std::string PortablePath(const fs::path &path)
create portable path on different platforms for std::filesystem path.
std::shared_ptr< SessionReader > SessionReaderSharedPtr
static FieldMetaDataMap NullFieldMetaDataMap
std::shared_ptr< FieldDefinitions > FieldDefinitionsSharedPtr
FieldIOFactory & GetFieldIOFactory()
Returns the FieldIO factory.
void Write(const std::string &outFile, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, const FieldMetaDataMap &fieldinfomap, const bool backup)
This function allows for data to be written to an FLD file when a session and/or communicator is not ...
CommFactory & GetCommFactory()
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
const std::string kGitBranch
const std::string kGitSha1
std::vector< double > d(NPUPPER *NPUPPER)