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,
129 ASSERTL0(found, std::string(
"Failed to open a PXXXXXXX.fld file "
138 datafilename = filename;
144 const unsigned char magic[8] = {0x89, 0x48, 0x44, 0x46,
145 0x0d, 0x0a, 0x1a, 0x0a};
147 std::ifstream datafile(datafilename.c_str(), std::ios_base::binary);
148 ASSERTL0(datafile.good(),
"Unable to open file: " + filename);
151 for (
unsigned i = 0; i < 8 && datafile.good(); ++i)
153 int byte = datafile.get();
154 if (
byte != magic[i])
164 int code = (int)ioType;
165 comm->Bcast(code, 0);
174 else if (ioType ==
eHDF5)
201 std::string iofmt(
"Xml");
202 if (session->DefinesSolverInfo(
"IOFormat"))
204 iofmt = session->GetSolverInfo(
"IOFormat");
207 if (session->DefinesCmdLineArgument(
"io-format"))
209 iofmt = session->GetCmdLineArgument<std::string>(
"io-format");
213 session->GetSharedFilesystem());
229 const std::string &filename)
231 const std::string iofmt =
234 session->GetSharedFilesystem());
248 void Write(
const std::string &outFile,
249 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
250 std::vector<std::vector<NekDouble>> &fielddata,
253 #ifdef NEKTAR_USE_MPI
256 MPI_Initialized(&init);
265 MPI_Comm_size(MPI_COMM_WORLD, &size);
267 "This static function is not available in parallel. Please"
268 "instantiate a FieldIO object for parallel use.");
273 f->Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
292 const std::string &infilename,
293 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
294 std::vector<std::vector<NekDouble>> &fielddata,
297 #ifdef NEKTAR_USE_MPI
300 MPI_Initialized(&init);
309 MPI_Comm_size(MPI_COMM_WORLD, &size);
311 "This static function is not available in parallel. Please"
312 "instantiate a FieldIO object for parallel use.");
318 f->Import(infilename, fielddefs, fielddata, fieldinfomap, ElementIDs);
325 : m_comm(pComm), m_sharedFilesystem(sharedFilesystem)
354 auto now = std::chrono::system_clock::now();
355 auto now_t = std::chrono::system_clock::to_time_t(now);
356 auto now_tm = *std::localtime(&now_t);
358 strftime(
buffer,
sizeof(
buffer),
"%d-%b-%Y %H:%M:%S", &now_tm);
359 ProvenanceMap[
"Timestamp"] =
buffer;
362 boost::system::error_code ec;
363 ProvenanceMap[
"Hostname"] = ip::host_name(ec);
376 for (
auto &infoit : ProvenanceMap)
378 provTag->SetAttr(infoit.first, infoit.second);
385 for (
auto &infoit : fieldmetadatamap)
387 infoTag->SetAttr(infoit.first, infoit.second);
410 ASSERTL0(!outname.empty(),
"Empty path given to SetUpOutput()");
413 std::size_t file_id = std::hash<std::string>{}(outname);
416 std::size_t file_id_max{file_id};
417 std::size_t file_id_min{file_id};
422 ASSERTL0(file_id_min == file_id_max,
423 "All processes do not have the same filename.");
425 int nprocs =
m_comm->GetSize();
426 bool root =
m_comm->TreatAsRankZero();
430 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)
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.