35 #include <boost/asio/ip/host_name.hpp>
36 #include <boost/format.hpp>
37 #include <boost/regex.hpp>
54 #ifndef NEKTAR_VERSION
55 #define NEKTAR_VERSION "Unknown"
58 namespace berrc = boost::system::errc;
59 namespace ip = boost::asio::ip;
63 namespace LibUtilities
67 "io-format",
"i",
"Default input/output format (e.g. Xml, Hdf5)");
101 int size = comm->GetSpaceComm()->GetSize();
102 bool root = comm->GetSpaceComm()->TreatAsRankZero();
104 if (size == 1 || root)
106 std::string datafilename;
109 if (fs::is_directory(filename))
111 fs::path fullpath = filename;
112 fs::path d = fullpath;
113 boost::regex expr(
"P\\d{7}.fld");
117 for (
auto &f : fs::directory_iterator(d))
119 if (boost::regex_match(f.path().filename().string(), what,
128 ASSERTL0(found, std::string(
"Failed to open a PXXXXXXX.fld file "
137 datafilename = filename;
143 const unsigned char magic[8] = {0x89, 0x48, 0x44, 0x46,
144 0x0d, 0x0a, 0x1a, 0x0a};
146 std::ifstream datafile(datafilename.c_str(), std::ios_base::binary);
147 ASSERTL0(datafile.good(),
"Unable to open file: " + filename);
150 for (
unsigned i = 0; i < 8 && datafile.good(); ++i)
152 int byte = datafile.get();
153 if (
byte != magic[i])
163 int code = (int)ioType;
164 comm->GetSpaceComm()->Bcast(code, 0);
173 else if (ioType ==
eHDF5)
200 std::string iofmt(
"Xml");
201 if (session->DefinesSolverInfo(
"IOFormat"))
203 iofmt = session->GetSolverInfo(
"IOFormat");
206 if (session->DefinesCmdLineArgument(
"io-format"))
208 iofmt = session->GetCmdLineArgument<std::string>(
"io-format");
212 session->GetSharedFilesystem());
228 const std::string &filename)
230 const std::string iofmt =
233 session->GetSharedFilesystem());
247 void Write(
const std::string &outFile,
248 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
249 std::vector<std::vector<NekDouble>> &fielddata,
252 #ifdef NEKTAR_USE_MPI
255 MPI_Initialized(&init);
264 MPI_Comm_size(MPI_COMM_WORLD, &size);
266 "This static function is not available in parallel. Please"
267 "instantiate a FieldIO object for parallel use.");
272 f->Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
291 const std::string &infilename,
292 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
293 std::vector<std::vector<NekDouble>> &fielddata,
296 #ifdef NEKTAR_USE_MPI
299 MPI_Initialized(&init);
308 MPI_Comm_size(MPI_COMM_WORLD, &size);
310 "This static function is not available in parallel. Please"
311 "instantiate a FieldIO object for parallel use.");
317 f->Import(infilename, fielddefs, fielddata, fieldinfomap, ElementIDs);
324 : m_comm(pComm), m_sharedFilesystem(sharedFilesystem)
353 auto now = std::chrono::system_clock::now();
354 auto now_t = std::chrono::system_clock::to_time_t(now);
355 auto now_tm = *std::localtime(&now_t);
357 strftime(
buffer,
sizeof(
buffer),
"%d-%b-%Y %H:%M:%S", &now_tm);
358 ProvenanceMap[
"Timestamp"] =
buffer;
361 boost::system::error_code ec;
362 ProvenanceMap[
"Hostname"] = ip::host_name(ec);
375 for (
auto &infoit : ProvenanceMap)
377 provTag->SetAttr(infoit.first, infoit.second);
384 for (
auto &infoit : fieldmetadatamap)
386 infoTag->SetAttr(infoit.first, infoit.second);
409 ASSERTL0(!outname.empty(),
"Empty path given to SetUpOutput()");
412 std::size_t file_id = std::hash<std::string>{}(outname);
415 std::size_t file_id_max{file_id};
416 std::size_t file_id_min{file_id};
421 ASSERTL0(file_id_min == file_id_max,
422 "All processes do not have the same filename.");
424 int nprocs =
m_comm->GetSpaceComm()->GetSize();
425 bool root =
m_comm->GetSpaceComm()->TreatAsRankZero();
429 fs::path specPath(outname), fulloutname;
438 fs::path bakPath = specPath;
440 while (fs::exists(bakPath))
442 bakPath = specPath.parent_path();
443 bakPath += fs::path(bakPath.extension() ==
".pit" ?
"/" :
"");
444 bakPath += specPath.stem();
445 bakPath += fs::path(
".bak" + std::to_string(cnt++));
446 bakPath += specPath.extension();
448 std::cout <<
"renaming " << specPath <<
" -> " << bakPath << std::endl;
451 fs::rename(specPath, bakPath);
453 catch (fs::filesystem_error &e)
455 ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
456 "Filesystem error: " + std::string(e.what()));
464 m_comm->GetSpaceComm()->Block();
466 while (exists && perRank)
468 exists = fs::exists(specPath);
475 fulloutname = specPath;
484 fs::path poutfile(pad.str());
485 fulloutname = specPath / poutfile;
489 if (
m_comm->GetSpaceComm()->RemoveExistingFiles() && !backup)
498 fs::remove_all(fulloutname);
500 catch (fs::filesystem_error &e)
502 ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
503 "Filesystem error: " + std::string(e.what()));
507 m_comm->GetSpaceComm()->Block();
514 fs::remove_all(specPath);
516 catch (fs::filesystem_error &e)
518 ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
519 "Filesystem error: " + std::string(e.what()));
525 m_comm->GetSpaceComm()->Block();
527 while (exists && perRank)
529 exists = fs::exists(specPath);
536 std::cout <<
"Writing: " << specPath << std::endl;
552 fs::create_directory(specPath);
555 catch (fs::filesystem_error &e)
558 "Filesystem error: " + std::string(e.what()));
561 m_comm->GetSpaceComm()->Block();
567 created = fs::is_directory(specPath);
573 fulloutname = specPath;
589 if (fielddefs->m_elementIDs.size() == 0)
594 unsigned int numbasis = 0;
597 switch (fielddefs->m_shapeType)
601 if (fielddefs->m_numHomogeneousDir)
603 numbasis += fielddefs->m_numHomogeneousDir;
609 if (fielddefs->m_numHomogeneousDir)
631 ASSERTL0(fielddefs->m_basis.size() == numbasis,
632 "Length of basis vector is incorrect");
634 if (fielddefs->m_uniOrder ==
true)
636 unsigned int cnt = 0;
638 switch (fielddefs->m_shapeType)
642 int l = fielddefs->m_numModes[cnt++];
643 if (fielddefs->m_numHomogeneousDir == 1)
645 datasize += l * fielddefs->m_homogeneousZIDs.size();
648 else if (fielddefs->m_numHomogeneousDir == 2)
650 datasize += l * fielddefs->m_homogeneousYIDs.size();
661 int l = fielddefs->m_numModes[cnt++];
662 int m = fielddefs->m_numModes[cnt++];
664 if (fielddefs->m_numHomogeneousDir == 1)
667 fielddefs->m_homogeneousZIDs.size();
677 int l = fielddefs->m_numModes[cnt++];
678 int m = fielddefs->m_numModes[cnt++];
679 if (fielddefs->m_numHomogeneousDir == 1)
681 datasize += l * m * fielddefs->m_homogeneousZIDs.size();
691 int l = fielddefs->m_numModes[cnt++];
692 int m = fielddefs->m_numModes[cnt++];
693 int n = fielddefs->m_numModes[cnt++];
699 int l = fielddefs->m_numModes[cnt++];
700 int m = fielddefs->m_numModes[cnt++];
701 int n = fielddefs->m_numModes[cnt++];
707 int l = fielddefs->m_numModes[cnt++];
708 int m = fielddefs->m_numModes[cnt++];
709 int n = fielddefs->m_numModes[cnt++];
715 int l = fielddefs->m_numModes[cnt++];
716 int m = fielddefs->m_numModes[cnt++];
717 int n = fielddefs->m_numModes[cnt++];
718 datasize += l * m * n;
726 datasize *= fielddefs->m_elementIDs.size();
730 unsigned int cnt = 0;
732 for (i = 0; i < fielddefs->m_elementIDs.size(); ++i)
734 switch (fielddefs->m_shapeType)
738 int l = fielddefs->m_numModes[cnt++];
739 if (fielddefs->m_numHomogeneousDir == 1)
741 datasize += l * fielddefs->m_homogeneousZIDs.size();
744 else if (fielddefs->m_numHomogeneousDir == 2)
746 datasize += l * fielddefs->m_homogeneousYIDs.size();
757 int l = fielddefs->m_numModes[cnt++];
758 int m = fielddefs->m_numModes[cnt++];
759 if (fielddefs->m_numHomogeneousDir == 1)
762 fielddefs->m_homogeneousZIDs.size();
773 int l = fielddefs->m_numModes[cnt++];
774 int m = fielddefs->m_numModes[cnt++];
775 if (fielddefs->m_numHomogeneousDir == 1)
777 datasize += l * m * fielddefs->m_homogeneousZIDs.size();
788 int l = fielddefs->m_numModes[cnt++];
789 int m = fielddefs->m_numModes[cnt++];
790 int n = fielddefs->m_numModes[cnt++];
796 int l = fielddefs->m_numModes[cnt++];
797 int m = fielddefs->m_numModes[cnt++];
798 int n = fielddefs->m_numModes[cnt++];
804 int l = fielddefs->m_numModes[cnt++];
805 int m = fielddefs->m_numModes[cnt++];
806 int n = fielddefs->m_numModes[cnt++];
812 int l = fielddefs->m_numModes[cnt++];
813 int m = fielddefs->m_numModes[cnt++];
814 int n = fielddefs->m_numModes[cnt++];
815 datasize += l * m * n;
825 return (
int)datasize;
#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.
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)
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 ...
FieldIOType
Enumerator for auto-detection of FieldIO types.
std::shared_ptr< TagWriter > TagWriterSharedPtr
std::shared_ptr< FieldIO > FieldIOSharedPtr
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::map< std::string, std::string > FieldMetaDataMap
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
std::shared_ptr< SessionReader > SessionReaderSharedPtr
static FieldMetaDataMap NullFieldMetaDataMap
std::shared_ptr< FieldDefinitions > FieldDefinitionsSharedPtr
FieldIOFactory & GetFieldIOFactory()
Returns the FieldIO factory.
CommFactory & GetCommFactory()
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
const std::string kGitBranch
const std::string kGitSha1
The above copyright notice and this permission notice shall be included.