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.