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->GetSize();
102 bool root = comm->TreatAsRankZero();
104 if (size == 1 || root)
106 std::string datafilename;
109 if (fs::is_directory(filename))
111 fs::path fullpath = filename;
113 fs::path d = fullpath;
114 boost::regex expr(
"P\\d{7}.fld");
118 for (
auto &f : fs::directory_iterator(d))
120 if (boost::regex_match(f.path().filename().string(), what, expr))
128 ASSERTL0(found,std::string(
"Failed to open a PXXXXXXX.fld file "
129 "in directory: " + filename).c_str());
135 datafilename = filename;
141 const unsigned char magic[8] = {
142 0x89, 0x48, 0x44, 0x46, 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->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");
212 session->GetSharedFilesystem());
228 const std::string &filename)
230 const std::string iofmt =
235 session->GetSharedFilesystem());
249 void Write(
const std::string &outFile,
250 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
251 std::vector<std::vector<NekDouble> > &fielddata,
255 #ifdef NEKTAR_USE_MPI
258 MPI_Initialized(&init);
267 MPI_Comm_size(MPI_COMM_WORLD, &size);
269 "This static function is not available in parallel. Please"
270 "instantiate a FieldIO object for parallel use.");
275 f->Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
294 const std::string &infilename,
295 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
296 std::vector<std::vector<NekDouble> > &fielddata,
300 #ifdef NEKTAR_USE_MPI
303 MPI_Initialized(&init);
312 MPI_Comm_size(MPI_COMM_WORLD, &size);
314 "This static function is not available in parallel. Please"
315 "instantiate a FieldIO object for parallel use.");
321 f->Import(infilename, fielddefs, fielddata, fieldinfomap, ElementIDs);
328 : m_comm(pComm), m_sharedFilesystem(sharedFilesystem)
357 auto now = std::chrono::system_clock::now();
358 auto now_t = std::chrono::system_clock::to_time_t(now);
359 auto now_tm = *std::localtime(&now_t);
361 strftime(
buffer,
sizeof(
buffer),
"%d-%b-%Y %H:%M:%S", &now_tm);
362 ProvenanceMap[
"Timestamp"] =
buffer;
365 boost::system::error_code ec;
366 ProvenanceMap[
"Hostname"] = ip::host_name(ec);
379 for (
auto &infoit : ProvenanceMap)
381 provTag->SetAttr(infoit.first, infoit.second);
388 for (
auto &infoit : fieldmetadatamap)
390 infoTag->SetAttr(infoit.first, infoit.second);
412 ASSERTL0(!outname.empty(),
"Empty path given to SetUpOutput()");
415 std::size_t file_id = std::hash<std::string>{}(outname);
418 std::size_t file_id_max {file_id};
419 std::size_t file_id_min {file_id};
424 ASSERTL0(file_id_min == file_id_max,
425 "All processes do not have the same filename.");
427 int nprocs =
m_comm->GetSize();
428 bool root =
m_comm->TreatAsRankZero();
432 fs::path specPath(outname), fulloutname;
439 fs::path bakPath = specPath;
441 while (fs::exists(bakPath))
443 bakPath = specPath.parent_path();
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()));
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->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()));
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()));
527 while (exists && perRank)
529 exists = fs::exists(specPath);
536 std::cout <<
"Writing: " << specPath;
552 fs::create_directory(specPath);
555 catch (fs::filesystem_error &e)
558 "Filesystem error: " + std::string(e.what()));
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.
static void AddInfoTag(TagWriterSharedPtr root, const FieldMetaDataMap &fieldmetadatamap)
Add provenance information to the field metadata map.
virtual std::string GetFileEnding() const
Helper function that determines default file extension.
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)
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
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.
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
The above copyright notice and this permission notice shall be included.