36 #include <boost/asio/ip/host_name.hpp>
37 #include <boost/date_time/posix_time/posix_time.hpp>
38 #include <boost/date_time/posix_time/posix_time_io.hpp>
39 #include <boost/make_shared.hpp>
40 #include <boost/format.hpp>
46 #include <loki/Singleton.h>
55 #ifndef NEKTAR_VERSION
56 #define NEKTAR_VERSION "Unknown"
59 namespace berrc = boost::system::errc;
60 namespace ptime = boost::posix_time;
61 namespace ip = boost::asio::ip;
65 namespace LibUtilities
69 "io-format",
"i",
"Default input/output format (e.g. Xml, Hdf5)");
77 SingletonHolder<
FieldIOFactory, Loki::CreateUsingNew, Loki::NoDestroy,
78 Loki::ClassLevelLockable> Type;
79 return Type::Instance();
105 int size = comm->GetSize();
106 int rank = comm->GetRank();
108 if (size == 1 || rank == 0)
110 std::string datafilename;
113 if (fs::is_directory(filename))
115 fs::path p0file(
"P0000000.fld");
116 fs::path fullpath = filename / p0file;
121 datafilename = filename;
127 const unsigned char magic[8] = {
128 0x89, 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a};
130 std::ifstream datafile(datafilename.c_str(), ios_base::binary);
131 ASSERTL0(datafile.good(),
"Unable to open file: " + filename);
134 for (
unsigned i = 0; i < 8 && datafile.good(); ++i)
136 unsigned char byte = datafile.get();
137 if (byte != magic[i])
147 int code = (int)ioType;
148 comm->Bcast(code, 0);
157 else if (ioType ==
eHDF5)
164 ASSERTL0(
false,
"Unknown file format");
184 std::string iofmt(
"Xml");
185 if (session->DefinesSolverInfo(
"IOFormat"))
187 iofmt = session->GetSolverInfo(
"IOFormat");
190 if (session->DefinesCmdLineArgument(
"io-format"))
192 iofmt = session->GetCmdLineArgument<std::string>(
"io-format");
198 session->GetSharedFilesystem());
214 const std::string &filename)
216 const std::string iofmt =
221 session->GetSharedFilesystem());
235 void Write(
const std::string &outFile,
236 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
237 std::vector<std::vector<NekDouble> > &fielddata,
241 #ifdef NEKTAR_USE_MPI
244 MPI_Initialized(&init);
253 MPI_Comm_size(MPI_COMM_WORLD, &size);
255 "This static function is not available in parallel. Please"
256 "instantiate a FieldIO object for parallel use.");
261 f->Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
280 const std::string &infilename,
281 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
282 std::vector<std::vector<NekDouble> > &fielddata,
286 #ifdef NEKTAR_USE_MPI
289 MPI_Initialized(&init);
298 MPI_Comm_size(MPI_COMM_WORLD, &size);
300 "This static function is not available in parallel. Please"
301 "instantiate a FieldIO object for parallel use.");
307 f->Import(infilename, fielddefs, fielddata, fieldinfomap, ElementIDs);
314 : m_comm(pComm), m_sharedFilesystem(sharedFilesystem)
343 ptime::time_facet *facet =
new ptime::time_facet(
"%d-%b-%Y %H:%M:%S");
344 std::stringstream wss;
345 wss.imbue(locale(wss.getloc(), facet));
346 wss << ptime::second_clock::local_time();
347 ProvenanceMap[
"Timestamp"] = wss.str();
350 boost::system::error_code ec;
351 ProvenanceMap[
"Hostname"] = ip::host_name(ec);
363 FieldMetaDataMap::const_iterator infoit;
366 for (infoit = ProvenanceMap.begin(); infoit != ProvenanceMap.end();
369 provTag->SetAttr(infoit->first, infoit->second);
376 for (infoit = fieldmetadatamap.begin();
377 infoit != fieldmetadatamap.end();
380 infoTag->SetAttr(infoit->first, infoit->second);
402 ASSERTL0(!outname.empty(),
"Empty path given to SetUpOutput()");
404 int nprocs =
m_comm->GetSize();
405 int rank =
m_comm->GetRank();
409 fs::path specPath(outname), fulloutname;
416 fs::path bakPath = specPath;
418 while (fs::exists(bakPath))
420 bakPath = specPath.parent_path();
421 bakPath += specPath.stem();
422 bakPath += fs::path(
".bak" + boost::lexical_cast<std::string>(cnt++));
423 bakPath += specPath.extension();
425 std::cout <<
"renaming " << specPath <<
" -> " << bakPath << std::endl;
428 fs::rename(specPath, bakPath);
430 catch (fs::filesystem_error &e)
432 ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
433 "Filesystem error: " + string(e.what()));
443 while (exists && perRank)
445 exists = fs::exists(specPath);
452 fulloutname = specPath;
461 fs::path poutfile(pad.str());
462 fulloutname = specPath / poutfile;
466 if (
m_comm->RemoveExistingFiles() && !backup)
475 fs::remove_all(fulloutname);
477 catch (fs::filesystem_error &e)
479 ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
480 "Filesystem error: " + string(e.what()));
491 fs::remove_all(specPath);
493 catch (fs::filesystem_error &e)
495 ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
496 "Filesystem error: " + string(e.what()));
504 while (exists && perRank)
506 exists = fs::exists(specPath);
513 cout <<
"Writing: " << specPath;
529 fs::create_directory(specPath);
532 catch (fs::filesystem_error &e)
534 ASSERTL0(
false,
"Filesystem error: " +
string(e.what()));
543 created = fs::is_directory(specPath);
549 fulloutname = specPath;
565 if (fielddefs->m_elementIDs.size() == 0)
570 unsigned int numbasis = 0;
573 switch (fielddefs->m_shapeType)
577 if (fielddefs->m_numHomogeneousDir)
579 numbasis += fielddefs->m_numHomogeneousDir;
585 if (fielddefs->m_numHomogeneousDir)
601 ASSERTL0(
false,
"Unsupported shape type.");
605 unsigned int datasize = 0;
607 ASSERTL0(fielddefs->m_basis.size() == numbasis,
608 "Length of basis vector is incorrect");
610 if (fielddefs->m_uniOrder ==
true)
612 unsigned int cnt = 0;
614 switch (fielddefs->m_shapeType)
618 int l = fielddefs->m_numModes[cnt++];
619 if (fielddefs->m_numHomogeneousDir == 1)
621 datasize += l * fielddefs->m_homogeneousZIDs.size();
624 else if (fielddefs->m_numHomogeneousDir == 2)
626 datasize += l * fielddefs->m_homogeneousYIDs.size();
637 int l = fielddefs->m_numModes[cnt++];
638 int m = fielddefs->m_numModes[cnt++];
640 if (fielddefs->m_numHomogeneousDir == 1)
643 fielddefs->m_homogeneousZIDs.size();
653 int l = fielddefs->m_numModes[cnt++];
654 int m = fielddefs->m_numModes[cnt++];
655 if (fielddefs->m_numHomogeneousDir == 1)
657 datasize += l * m * fielddefs->m_homogeneousZIDs.size();
667 int l = fielddefs->m_numModes[cnt++];
668 int m = fielddefs->m_numModes[cnt++];
669 int n = fielddefs->m_numModes[cnt++];
675 int l = fielddefs->m_numModes[cnt++];
676 int m = fielddefs->m_numModes[cnt++];
677 int n = fielddefs->m_numModes[cnt++];
683 int l = fielddefs->m_numModes[cnt++];
684 int m = fielddefs->m_numModes[cnt++];
685 int n = fielddefs->m_numModes[cnt++];
691 int l = fielddefs->m_numModes[cnt++];
692 int m = fielddefs->m_numModes[cnt++];
693 int n = fielddefs->m_numModes[cnt++];
694 datasize += l * m * n;
698 ASSERTL0(
false,
"Unsupported shape type.");
702 datasize *= fielddefs->m_elementIDs.size();
706 unsigned int cnt = 0;
708 for (i = 0; i < fielddefs->m_elementIDs.size(); ++i)
710 switch (fielddefs->m_shapeType)
714 int l = fielddefs->m_numModes[cnt++];
715 if (fielddefs->m_numHomogeneousDir == 1)
717 datasize += l * fielddefs->m_homogeneousZIDs.size();
720 else if (fielddefs->m_numHomogeneousDir == 2)
722 datasize += l * fielddefs->m_homogeneousYIDs.size();
733 int l = fielddefs->m_numModes[cnt++];
734 int m = fielddefs->m_numModes[cnt++];
735 if (fielddefs->m_numHomogeneousDir == 1)
738 fielddefs->m_homogeneousZIDs.size();
749 int l = fielddefs->m_numModes[cnt++];
750 int m = fielddefs->m_numModes[cnt++];
751 if (fielddefs->m_numHomogeneousDir == 1)
753 datasize += l * m * fielddefs->m_homogeneousZIDs.size();
764 int l = fielddefs->m_numModes[cnt++];
765 int m = fielddefs->m_numModes[cnt++];
766 int n = fielddefs->m_numModes[cnt++];
772 int l = fielddefs->m_numModes[cnt++];
773 int m = fielddefs->m_numModes[cnt++];
774 int n = fielddefs->m_numModes[cnt++];
780 int l = fielddefs->m_numModes[cnt++];
781 int m = fielddefs->m_numModes[cnt++];
782 int n = fielddefs->m_numModes[cnt++];
788 int l = fielddefs->m_numModes[cnt++];
789 int m = fielddefs->m_numModes[cnt++];
790 int n = fielddefs->m_numModes[cnt++];
791 datasize += l * m * n;
795 ASSERTL0(
false,
"Unsupported shape type.");
#define ASSERTL0(condition, msg)
int getNumberOfCoefficients(int Na, int Nb, int Nc)
LibUtilities::NekFactory< std::string, FieldIO, LibUtilities::CommSharedPtr, bool > FieldIOFactory
Datatype of the NekFactory used to instantiate classes.
tBaseSharedPtr CreateInstance(tKey idKey BOOST_PP_COMMA_IF(MAX_PARAM) BOOST_PP_ENUM_BINARY_PARAMS(MAX_PARAM, tParam, x))
Create an instance of the class referred to by idKey.
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...
boost::shared_ptr< FieldDefinitions > FieldDefinitionsSharedPtr
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)
FieldIOFactory & GetFieldIOFactory()
Returns the FieldIO factory.
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
std::map< std::string, std::string > FieldMetaDataMap
CommFactory & GetCommFactory()
int CheckFieldDefinition(const FieldDefinitionsSharedPtr &fielddefs)
Check field definitions for correctness and return storage size.
bool m_sharedFilesystem
Boolean dictating whether we are on a shared filesystem.
boost::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
const std::string kGitSha1
FieldIOType
Enumerator for auto-detection of FieldIO types.
static const std::string GetFileType(const std::string &filename, CommSharedPtr comm)
Determine file type of given input file.
#define LIB_UTILITIES_EXPORT
int getNumberOfCoefficients(int Na, int Nb)
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
boost::shared_ptr< FieldIO > FieldIOSharedPtr
const std::string kGitBranch
std::string SetUpOutput(const std::string outname, bool perRank, bool backup=false)
Set up the filesystem ready for output.
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 ...
LibUtilities::CommSharedPtr m_comm
Communicator to use when writing parallel format.
int getNumberOfCoefficients(int Na, int Nb, int Nc)
static boost::shared_ptr< FieldIO > CreateDefault(const LibUtilities::SessionReaderSharedPtr session)
Returns an object for the default FieldIO method.
static boost::shared_ptr< FieldIO > CreateForFile(const LibUtilities::SessionReaderSharedPtr session, const std::string &filename)
Construct a FieldIO object for a given input filename.
virtual std::string GetFileEnding() const
Helper function that determines default file extension.
boost::shared_ptr< TagWriter > TagWriterSharedPtr
static FieldMetaDataMap NullFieldMetaDataMap
void AddInfoTag(TagWriterSharedPtr root, const FieldMetaDataMap &fieldmetadatamap)
Add provenance information to the field metadata map.
Provides a generic Factory class.
FieldIO(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
Constructor for FieldIO base class.