35#include <boost/asio/ip/host_name.hpp>
36#include <boost/format.hpp>
49#include <system_error>
56#define NEKTAR_VERSION "Unknown"
59namespace ip = boost::asio::ip;
65 "io-format",
"i",
"Default input/output format (e.g. Xml, Hdf5)");
99 int size = comm->GetSpaceComm()->GetSize();
100 bool root = comm->GetSpaceComm()->TreatAsRankZero();
102 if (size == 1 || root)
104 std::string datafilename;
107 if (fs::is_directory(filename))
109 fs::path fullpath = filename;
110 fs::path
d = fullpath;
111 std::regex expr(
"P\\d{7}.fld");
115 for (
auto &f : fs::directory_iterator(
d))
117 std::string filename = f.path().filename().string();
118 if (std::regex_match(filename, what, expr))
126 ASSERTL0(found, std::string(
"Failed to open a PXXXXXXX.fld file "
135 datafilename = filename;
141 const unsigned char magic[8] = {0x89, 0x48, 0x44, 0x46,
142 0x0d, 0x0a, 0x1a, 0x0a};
144 std::ifstream datafile(datafilename.c_str(), std::ios_base::binary);
145 ASSERTL0(datafile.good(),
"Unable to open file: " + filename);
148 for (
unsigned i = 0; i < 8 && datafile.good(); ++i)
150 int byte = datafile.get();
151 if (
byte != magic[i])
161 int code = (int)ioType;
162 comm->GetSpaceComm()->Bcast(code, 0);
171 else if (ioType ==
eHDF5)
198 std::string iofmt(
"Xml");
199 if (session->DefinesSolverInfo(
"IOFormat"))
201 iofmt = session->GetSolverInfo(
"IOFormat");
204 if (session->DefinesCmdLineArgument(
"io-format"))
206 iofmt = session->GetCmdLineArgument<std::string>(
"io-format");
210 session->GetSharedFilesystem());
226 const std::string &filename)
228 const std::string iofmt =
231 session->GetSharedFilesystem());
245void Write(
const std::string &outFile,
246 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
247 std::vector<std::vector<NekDouble>> &fielddata,
253 MPI_Initialized(&init);
262 MPI_Comm_size(MPI_COMM_WORLD, &size);
264 "This static function is not available in parallel. Please"
265 "instantiate a FieldIO object for parallel use.");
270 f->Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
289 const std::string &infilename,
290 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
291 std::vector<std::vector<NekDouble>> &fielddata,
297 MPI_Initialized(&init);
306 MPI_Comm_size(MPI_COMM_WORLD, &size);
308 "This static function is not available in parallel. Please"
309 "instantiate a FieldIO object for parallel use.");
315 f->Import(infilename, fielddefs, fielddata, fieldinfomap, ElementIDs);
322 : m_comm(pComm), m_sharedFilesystem(sharedFilesystem)
351 auto now = std::chrono::system_clock::now();
352 auto now_t = std::chrono::system_clock::to_time_t(now);
353 auto now_tm = *std::localtime(&now_t);
355 strftime(
buffer,
sizeof(
buffer),
"%d-%b-%Y %H:%M:%S", &now_tm);
356 ProvenanceMap[
"Timestamp"] =
buffer;
359 boost::system::error_code ec;
360 ProvenanceMap[
"Hostname"] = ip::host_name(ec);
373 for (
auto &infoit : ProvenanceMap)
375 provTag->SetAttr(infoit.first, infoit.second);
382 for (
auto &infoit : fieldmetadatamap)
384 infoTag->SetAttr(infoit.first, infoit.second);
407 ASSERTL0(!outname.empty(),
"Empty path given to SetUpOutput()");
410 std::size_t file_id = std::hash<std::string>{}(outname);
413 std::size_t file_id_max{file_id};
414 std::size_t file_id_min{file_id};
419 ASSERTL0(file_id_min == file_id_max,
420 "All processes do not have the same filename.");
422 int nprocs =
m_comm->GetSpaceComm()->GetSize();
423 bool root =
m_comm->GetSpaceComm()->TreatAsRankZero();
427 fs::path specPath(outname), fulloutname;
436 fs::path bakPath = specPath;
438 while (fs::exists(bakPath))
440 bakPath = specPath.parent_path();
441 bakPath += fs::path(bakPath.extension() ==
".pit" ?
"/" :
"");
442 bakPath += specPath.stem();
443 bakPath += fs::path(
".bak" + std::to_string(cnt++));
444 bakPath += specPath.extension();
446 std::cout <<
"renaming " << specPath <<
" -> " << bakPath << std::endl;
449 fs::rename(specPath, bakPath);
451 catch (fs::filesystem_error &e)
453 ASSERTL0(e.code() == std::errc::no_such_file_or_directory,
454 "Filesystem error: " + std::string(e.what()));
462 m_comm->GetSpaceComm()->Block();
464 while (exists && perRank)
466 exists = fs::exists(specPath);
473 fulloutname = specPath;
482 fs::path poutfile(pad.str());
483 fulloutname = specPath / poutfile;
487 if (
m_comm->GetSpaceComm()->RemoveExistingFiles() && !backup)
496 fs::remove_all(fulloutname);
498 catch (fs::filesystem_error &e)
500 ASSERTL0(e.code() == std::errc::no_such_file_or_directory,
501 "Filesystem error: " + std::string(e.what()));
505 m_comm->GetSpaceComm()->Block();
512 fs::remove_all(specPath);
514 catch (fs::filesystem_error &e)
516 ASSERTL0(e.code() == std::errc::no_such_file_or_directory,
517 "Filesystem error: " + std::string(e.what()));
523 m_comm->GetSpaceComm()->Block();
525 while (exists && perRank)
527 exists = fs::exists(specPath);
534 std::cout <<
"Writing: \"" + specPath.string() +
535 (
m_comm->IsParallelInTime() ?
"\"\n" :
"\"");
551 fs::create_directory(specPath);
554 catch (fs::filesystem_error &e)
557 "Filesystem error: " + std::string(e.what()));
560 m_comm->GetSpaceComm()->Block();
566 created = fs::is_directory(specPath);
572 fulloutname = specPath;
592 switch (fielddefs->m_shapeType)
596 int l = fielddefs->m_numModes[cnt++];
597 if (fielddefs->m_numHomogeneousDir == 1)
599 NCoeffs = l * fielddefs->m_homogeneousZIDs.size();
602 else if (fielddefs->m_numHomogeneousDir == 2)
604 NCoeffs = l * fielddefs->m_homogeneousYIDs.size();
615 int l = fielddefs->m_numModes[cnt++];
616 int m = fielddefs->m_numModes[cnt++];
617 if (fielddefs->m_numHomogeneousDir == 1)
620 fielddefs->m_homogeneousZIDs.size();
631 int l = fielddefs->m_numModes[cnt++];
632 int m = fielddefs->m_numModes[cnt++];
633 if (fielddefs->m_numHomogeneousDir == 1)
636 fielddefs->m_homogeneousZIDs.size();
647 int l = fielddefs->m_numModes[cnt++];
648 int m = fielddefs->m_numModes[cnt++];
649 int n = fielddefs->m_numModes[cnt++];
655 int l = fielddefs->m_numModes[cnt++];
656 int m = fielddefs->m_numModes[cnt++];
657 int n = fielddefs->m_numModes[cnt++];
663 int l = fielddefs->m_numModes[cnt++];
664 int m = fielddefs->m_numModes[cnt++];
665 int n = fielddefs->m_numModes[cnt++];
671 int l = fielddefs->m_numModes[cnt++];
672 int m = fielddefs->m_numModes[cnt++];
673 int n = fielddefs->m_numModes[cnt++];
693 if (fielddefs->m_elementIDs.size() == 0)
698 unsigned int numbasis = 0;
701 switch (fielddefs->m_shapeType)
705 if (fielddefs->m_numHomogeneousDir)
707 numbasis += fielddefs->m_numHomogeneousDir;
713 if (fielddefs->m_numHomogeneousDir)
733 ASSERTL0(fielddefs->m_basis.size() == numbasis,
734 "Length of basis vector is incorrect");
736 if (fielddefs->m_uniOrder ==
true)
739 unsigned int cnt = 0;
743 return datasize * fielddefs->m_elementIDs.size();
748 unsigned int cnt = 0;
752 for (
int i = 0; i < fielddefs->m_elementIDs.size(); ++i)
771 std::vector<unsigned int> coeffsPerElmt;
774 if (fielddefs->m_elementIDs.size() == 0)
776 return coeffsPerElmt;
780 coeffsPerElmt.resize(fielddefs->m_elementIDs.size());
782 if (fielddefs->m_uniOrder ==
true)
785 unsigned int cnt = 0;
789 for (
int i = 0; i < fielddefs->m_elementIDs.size(); ++i)
791 coeffsPerElmt[i] = datasize;
797 unsigned int cnt = 0;
799 for (
int i = 0; i < fielddefs->m_elementIDs.size(); ++i)
805 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)