Nektar++
Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
Nektar::LibUtilities::FieldIO Class Referenceabstract

Class for operating on Nektar++ input/output files. More...

#include <FieldIO.h>

Inheritance diagram for Nektar::LibUtilities::FieldIO:
[legend]

Public Member Functions

 FieldIO (LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
 Constructor for FieldIO base class. More...
 
virtual ~FieldIO ()
 
void Write (const std::string &outFile, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, const FieldMetaDataMap &fieldinfomap=NullFieldMetaDataMap, const bool backup=false)
 Write out the field information to the file outFile. More...
 
void Import (const std::string &infilename, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata=NullVectorNekDoubleVector, FieldMetaDataMap &fieldinfomap=NullFieldMetaDataMap, const Array< OneD, int > &ElementIDs=NullInt1DArray)
 Read field information from the file infilename. More...
 
DataSourceSharedPtr ImportFieldMetaData (const std::string &filename, FieldMetaDataMap &fieldmetadatamap)
 Import the metadata from a field file. More...
 
virtual const std::string & GetClassName () const =0
 

Static Public Member Functions

static const std::string GetFileType (const std::string &filename, CommSharedPtr comm)
 Determine file type of given input file. More...
 
static std::shared_ptr< FieldIOCreateDefault (const LibUtilities::SessionReaderSharedPtr session)
 Returns an object for the default FieldIO method. More...
 
static std::shared_ptr< FieldIOCreateForFile (const LibUtilities::SessionReaderSharedPtr session, const std::string &filename)
 Construct a FieldIO object for a given input filename. More...
 
static void AddInfoTag (TagWriterSharedPtr root, const FieldMetaDataMap &fieldmetadatamap)
 Add provenance information to the field metadata map. More...
 

Protected Member Functions

int CheckFieldDefinition (const FieldDefinitionsSharedPtr &fielddefs)
 Check field definitions for correctness and return storage size. More...
 
virtual std::string GetFileEnding () const
 Helper function that determines default file extension. More...
 
std::string SetUpOutput (const std::string outname, bool perRank, bool backup=false)
 Set up the filesystem ready for output. More...
 
virtual void v_Write (const std::string &outFile, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, const FieldMetaDataMap &fieldinfomap, const bool backup=false)=0
 Write out the field information to the file outFile. More...
 
virtual void v_Import (const std::string &infilename, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata=NullVectorNekDoubleVector, FieldMetaDataMap &fieldinfomap=NullFieldMetaDataMap, const Array< OneD, int > &ElementIDs=NullInt1DArray)=0
 Read field information from the file infilename. More...
 
virtual DataSourceSharedPtr v_ImportFieldMetaData (const std::string &filename, FieldMetaDataMap &fieldmetadatamap)=0
 Import the metadata from a field file. More...
 

Protected Attributes

LibUtilities::CommSharedPtr m_comm
 Communicator to use when writing parallel format. More...
 
bool m_sharedFilesystem
 Boolean dictating whether we are on a shared filesystem. More...
 

Detailed Description

Class for operating on Nektar++ input/output files.

Nektar++ input/output of field data can be described as follows:

This base class represents the minimum functionality that subclasses need to implement in order to implement the above functionality. Each subclass is free to determine its own file structure and parallel behaviour.

Definition at line 222 of file FieldIO.h.

Constructor & Destructor Documentation

◆ FieldIO()

Nektar::LibUtilities::FieldIO::FieldIO ( LibUtilities::CommSharedPtr  pComm,
bool  sharedFilesystem 
)

Constructor for FieldIO base class.

Definition at line 308 of file FieldIO.cpp.

309  : m_comm(pComm), m_sharedFilesystem(sharedFilesystem)
310 {
311 }
bool m_sharedFilesystem
Boolean dictating whether we are on a shared filesystem.
Definition: FieldIO.h:268
LibUtilities::CommSharedPtr m_comm
Communicator to use when writing parallel format.
Definition: FieldIO.h:266

◆ ~FieldIO()

virtual Nektar::LibUtilities::FieldIO::~FieldIO ( )
inlinevirtual

Member Function Documentation

◆ AddInfoTag()

void Nektar::LibUtilities::FieldIO::AddInfoTag ( TagWriterSharedPtr  root,
const FieldMetaDataMap fieldmetadatamap 
)
static

Add provenance information to the field metadata map.

This routine adds some basic provenance information to the field metadata to enable better tracking of version information:

  • Nektar++ version
  • Date and time of simulation
  • Hostname of the machine the simulation was performed on
  • git SHA1 and branch name, if Nektar++ was compiled from git and not e.g. a tarball.
Parameters
rootRoot tag, which is encapsulated using the TagWriter structure to enable multi-file format support.
fieldmetadatamapAny existing field metadata.

Definition at line 329 of file FieldIO.cpp.

References Nektar::NekConstants::kGitBranch, Nektar::NekConstants::kGitSha1, NEKTAR_VERSION, and Nektar::LibUtilities::NullFieldMetaDataMap.

Referenced by Nektar::LibUtilities::FieldIOHdf5::v_Write(), Nektar::LibUtilities::FieldIOXml::v_Write(), and Nektar::LibUtilities::FieldIOXml::WriteMultiFldFileIDs().

331 {
332  FieldMetaDataMap ProvenanceMap;
333 
334  // Nektar++ release version from VERSION file
335  ProvenanceMap["NektarVersion"] = std::string(NEKTAR_VERSION);
336 
337  // Date/time stamp
338  auto now = std::chrono::system_clock::now();
339  auto now_t = std::chrono::system_clock::to_time_t(now);
340  auto now_tm = *std::localtime(&now_t);
341  char buffer[128];
342  strftime(buffer, sizeof(buffer), "%d-%b-%Y %H:%M:%S", &now_tm);
343  ProvenanceMap["Timestamp"] = buffer;
344 
345  // Hostname
346  boost::system::error_code ec;
347  ProvenanceMap["Hostname"] = ip::host_name(ec);
348 
349  // Git information
350  // If built from a distributed package, do not include this
351  if (NekConstants::kGitSha1 != "GITDIR-NOTFOUND")
352  {
353  ProvenanceMap["GitSHA1"] = NekConstants::kGitSha1;
354  ProvenanceMap["GitBranch"] = NekConstants::kGitBranch;
355  }
356 
357  TagWriterSharedPtr infoTag = root->AddChild("Metadata");
358 
359  TagWriterSharedPtr provTag = infoTag->AddChild("Provenance");
360  for (auto &infoit : ProvenanceMap)
361  {
362  provTag->SetAttr(infoit.first, infoit.second);
363  }
364 
365  //---------------------------------------------
366  // write field info section
367  if (fieldmetadatamap != NullFieldMetaDataMap)
368  {
369  for (auto &infoit : fieldmetadatamap)
370  {
371  infoTag->SetAttr(infoit.first, infoit.second);
372  }
373  }
374 }
array buffer
Definition: GsLib.hpp:61
std::map< std::string, std::string > FieldMetaDataMap
Definition: FieldIO.h:52
std::shared_ptr< TagWriter > TagWriterSharedPtr
Definition: FieldIO.h:69
const std::string kGitSha1
const std::string kGitBranch
#define NEKTAR_VERSION
Definition: FieldIO.cpp:54
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:53

◆ CheckFieldDefinition()

int Nektar::LibUtilities::FieldIO::CheckFieldDefinition ( const FieldDefinitionsSharedPtr fielddefs)
protected

Check field definitions for correctness and return storage size.

Parameters
fielddefsField definitions to check.

Definition at line 553 of file FieldIO.cpp.

References ASSERTL0, Nektar::ErrorUtil::efatal, Nektar::LibUtilities::eHexahedron, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::ePyramid, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eSegment, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::LibUtilities::StdTriData::getNumberOfCoefficients(), Nektar::LibUtilities::StdTetData::getNumberOfCoefficients(), Nektar::LibUtilities::StdPyrData::getNumberOfCoefficients(), Nektar::LibUtilities::StdPrismData::getNumberOfCoefficients(), and NEKERROR.

Referenced by Nektar::LibUtilities::FieldIOXml::ImportFieldData(), Nektar::LibUtilities::FieldIOHdf5::ImportFieldData(), Nektar::LibUtilities::FieldIOHdf5::v_Write(), and Nektar::LibUtilities::FieldIOXml::v_Write().

554 {
555  int i;
556 
557  if (fielddefs->m_elementIDs.size() == 0) // empty partition
558  {
559  return 0;
560  }
561 
562  unsigned int numbasis = 0;
563 
564  // Determine nummodes vector lists are correct length
565  switch (fielddefs->m_shapeType)
566  {
567  case eSegment:
568  numbasis = 1;
569  if (fielddefs->m_numHomogeneousDir)
570  {
571  numbasis += fielddefs->m_numHomogeneousDir;
572  }
573 
574  break;
575  case eTriangle:
576  case eQuadrilateral:
577  if (fielddefs->m_numHomogeneousDir)
578  {
579  numbasis = 3;
580  }
581  else
582  {
583  numbasis = 2;
584  }
585  break;
586  case eTetrahedron:
587  case ePyramid:
588  case ePrism:
589  case eHexahedron:
590  numbasis = 3;
591  break;
592  default:
593  NEKERROR(ErrorUtil::efatal, "Unsupported shape type.");
594  break;
595  }
596 
597  size_t datasize = 0;
598 
599  ASSERTL0(fielddefs->m_basis.size() == numbasis,
600  "Length of basis vector is incorrect");
601 
602  if (fielddefs->m_uniOrder == true)
603  {
604  unsigned int cnt = 0;
605  // calculate datasize
606  switch (fielddefs->m_shapeType)
607  {
608  case eSegment:
609  {
610  int l = fielddefs->m_numModes[cnt++];
611  if (fielddefs->m_numHomogeneousDir == 1)
612  {
613  datasize += l * fielddefs->m_homogeneousZIDs.size();
614  cnt++;
615  }
616  else if (fielddefs->m_numHomogeneousDir == 2)
617  {
618  datasize += l * fielddefs->m_homogeneousYIDs.size();
619  cnt += 2;
620  }
621  else
622  {
623  datasize += l;
624  }
625  }
626  break;
627  case eTriangle:
628  {
629  int l = fielddefs->m_numModes[cnt++];
630  int m = fielddefs->m_numModes[cnt++];
631 
632  if (fielddefs->m_numHomogeneousDir == 1)
633  {
634  datasize += StdTriData::getNumberOfCoefficients(l, m) *
635  fielddefs->m_homogeneousZIDs.size();
636  }
637  else
638  {
639  datasize += StdTriData::getNumberOfCoefficients(l, m);
640  }
641  }
642  break;
643  case eQuadrilateral:
644  {
645  int l = fielddefs->m_numModes[cnt++];
646  int m = fielddefs->m_numModes[cnt++];
647  if (fielddefs->m_numHomogeneousDir == 1)
648  {
649  datasize += l * m * fielddefs->m_homogeneousZIDs.size();
650  }
651  else
652  {
653  datasize += l * m;
654  }
655  }
656  break;
657  case eTetrahedron:
658  {
659  int l = fielddefs->m_numModes[cnt++];
660  int m = fielddefs->m_numModes[cnt++];
661  int n = fielddefs->m_numModes[cnt++];
662  datasize += StdTetData::getNumberOfCoefficients(l, m, n);
663  }
664  break;
665  case ePyramid:
666  {
667  int l = fielddefs->m_numModes[cnt++];
668  int m = fielddefs->m_numModes[cnt++];
669  int n = fielddefs->m_numModes[cnt++];
670  datasize += StdPyrData::getNumberOfCoefficients(l, m, n);
671  }
672  break;
673  case ePrism:
674  {
675  int l = fielddefs->m_numModes[cnt++];
676  int m = fielddefs->m_numModes[cnt++];
677  int n = fielddefs->m_numModes[cnt++];
678  datasize += StdPrismData::getNumberOfCoefficients(l, m, n);
679  }
680  break;
681  case eHexahedron:
682  {
683  int l = fielddefs->m_numModes[cnt++];
684  int m = fielddefs->m_numModes[cnt++];
685  int n = fielddefs->m_numModes[cnt++];
686  datasize += l * m * n;
687  }
688  break;
689  default:
690  NEKERROR(ErrorUtil::efatal, "Unsupported shape type.");
691  break;
692  }
693 
694  datasize *= fielddefs->m_elementIDs.size();
695  }
696  else
697  {
698  unsigned int cnt = 0;
699  // calculate data length
700  for (i = 0; i < fielddefs->m_elementIDs.size(); ++i)
701  {
702  switch (fielddefs->m_shapeType)
703  {
704  case eSegment:
705  {
706  int l = fielddefs->m_numModes[cnt++];
707  if (fielddefs->m_numHomogeneousDir == 1)
708  {
709  datasize += l * fielddefs->m_homogeneousZIDs.size();
710  cnt++;
711  }
712  else if (fielddefs->m_numHomogeneousDir == 2)
713  {
714  datasize += l * fielddefs->m_homogeneousYIDs.size();
715  cnt += 2;
716  }
717  else
718  {
719  datasize += l;
720  }
721  }
722  break;
723  case eTriangle:
724  {
725  int l = fielddefs->m_numModes[cnt++];
726  int m = fielddefs->m_numModes[cnt++];
727  if (fielddefs->m_numHomogeneousDir == 1)
728  {
729  datasize += StdTriData::getNumberOfCoefficients(l, m) *
730  fielddefs->m_homogeneousZIDs.size();
731  cnt++;
732  }
733  else
734  {
735  datasize += StdTriData::getNumberOfCoefficients(l, m);
736  }
737  }
738  break;
739  case eQuadrilateral:
740  {
741  int l = fielddefs->m_numModes[cnt++];
742  int m = fielddefs->m_numModes[cnt++];
743  if (fielddefs->m_numHomogeneousDir == 1)
744  {
745  datasize += l * m * fielddefs->m_homogeneousZIDs.size();
746  cnt++;
747  }
748  else
749  {
750  datasize += l * m;
751  }
752  }
753  break;
754  case eTetrahedron:
755  {
756  int l = fielddefs->m_numModes[cnt++];
757  int m = fielddefs->m_numModes[cnt++];
758  int n = fielddefs->m_numModes[cnt++];
759  datasize += StdTetData::getNumberOfCoefficients(l, m, n);
760  }
761  break;
762  case ePyramid:
763  {
764  int l = fielddefs->m_numModes[cnt++];
765  int m = fielddefs->m_numModes[cnt++];
766  int n = fielddefs->m_numModes[cnt++];
767  datasize += StdPyrData::getNumberOfCoefficients(l, m, n);
768  }
769  break;
770  case ePrism:
771  {
772  int l = fielddefs->m_numModes[cnt++];
773  int m = fielddefs->m_numModes[cnt++];
774  int n = fielddefs->m_numModes[cnt++];
775  datasize += StdPrismData::getNumberOfCoefficients(l, m, n);
776  }
777  break;
778  case eHexahedron:
779  {
780  int l = fielddefs->m_numModes[cnt++];
781  int m = fielddefs->m_numModes[cnt++];
782  int n = fielddefs->m_numModes[cnt++];
783  datasize += l * m * n;
784  }
785  break;
786  default:
787  NEKERROR(ErrorUtil::efatal, "Unsupported shape type.");
788  break;
789  }
790  }
791  }
792 
793  return (int)datasize;
794 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:209
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:287
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:194
int getNumberOfCoefficients(int Na, int Nb)
Definition: ShapeType.hpp:113
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:240

◆ CreateDefault()

FieldIOSharedPtr Nektar::LibUtilities::FieldIO::CreateDefault ( const LibUtilities::SessionReaderSharedPtr  session)
static

Returns an object for the default FieldIO method.

This function returns a FieldIO class as determined by the hard-coded default (XML), which can be overridden by changing the session reader SOLVERINFO variable FieldIOFormat.

Parameters
sessionSession reader
Returns
FieldIO object

Definition at line 176 of file FieldIO.cpp.

References Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::CreateInstance(), and Nektar::LibUtilities::GetFieldIOFactory().

Referenced by Nektar::VortexWaveInteraction::FileRelaxation(), Nektar::FilterBenchmark::FilterBenchmark(), Nektar::SolverUtils::FilterCheckpoint::FilterCheckpoint(), Nektar::FilterCheckpointCellModel::FilterCheckpointCellModel(), Nektar::SolverUtils::FilterModalEnergy::FilterModalEnergy(), Nektar::SolverUtils::FilterThresholdMax::FilterThresholdMax(), Nektar::SolverUtils::FilterThresholdMin::FilterThresholdMin(), Nektar::GlobalMapping::Mapping::Mapping(), and Nektar::SolverUtils::EquationSystem::v_InitObject().

178 {
179  std::string iofmt("Xml");
180  if (session->DefinesSolverInfo("IOFormat"))
181  {
182  iofmt = session->GetSolverInfo("IOFormat");
183  }
184 
185  if (session->DefinesCmdLineArgument("io-format"))
186  {
187  iofmt = session->GetCmdLineArgument<std::string>("io-format");
188  }
189 
191  iofmt,
192  session->GetComm(),
193  session->GetSharedFilesystem());
194 }
FieldIOFactory & GetFieldIOFactory()
Returns the FieldIO factory.
Definition: FieldIO.cpp:71
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144

◆ CreateForFile()

FieldIOSharedPtr Nektar::LibUtilities::FieldIO::CreateForFile ( const LibUtilities::SessionReaderSharedPtr  session,
const std::string &  filename 
)
static

Construct a FieldIO object for a given input filename.

This is a convenience function that takes an input filename and constructs the appropriate FieldIO subclass, using FieldIO::GetFileType.

Parameters
sessionSession reader
filenameInput filename
Returns
FieldIO class reader for filename.

Definition at line 207 of file FieldIO.cpp.

References Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::CreateInstance(), Nektar::LibUtilities::GetFieldIOFactory(), and GetFileType().

Referenced by Nektar::SolverUtils::UnsteadySystem::CheckForRestartTime(), Nektar::SolverUtils::SessionFunction::EvaluateFld(), Nektar::GlobalMapping::Mapping::EvaluateFunction(), Nektar::SolverUtils::EquationSystem::ImportFld(), Nektar::LinearisedAdvection::ImportFldBase(), and Nektar::SolverUtils::FilterFieldConvert::v_Initialise().

210 {
211  const std::string iofmt =
212  FieldIO::GetFileType(filename, session->GetComm());
214  iofmt,
215  session->GetComm(),
216  session->GetSharedFilesystem());
217 }
FieldIOFactory & GetFieldIOFactory()
Returns the FieldIO factory.
Definition: FieldIO.cpp:71
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
static const std::string GetFileType(const std::string &filename, CommSharedPtr comm)
Determine file type of given input file.
Definition: FieldIO.cpp:96

◆ GetClassName()

virtual const std::string& Nektar::LibUtilities::FieldIO::GetClassName ( ) const
pure virtual

◆ GetFileEnding()

virtual std::string Nektar::LibUtilities::FieldIO::GetFileEnding ( ) const
inlineprotectedvirtual

Helper function that determines default file extension.

Reimplemented in Nektar::LibUtilities::PtsIO, and Nektar::LibUtilities::CsvIO.

Definition at line 276 of file FieldIO.h.

References LIB_UTILITIES_EXPORT, Nektar::NullInt1DArray, and Nektar::LibUtilities::NullVectorNekDoubleVector.

Referenced by Nektar::LibUtilities::FieldIOXml::SetUpFieldMetaData(), and SetUpOutput().

277  {
278  return "fld";
279  }

◆ GetFileType()

const std::string Nektar::LibUtilities::FieldIO::GetFileType ( const std::string &  filename,
CommSharedPtr  comm 
)
static

Determine file type of given input file.

This method attempts to identify the file type of a given input file filename. It returns a string corresponding to GetFieldIOFactory() or throws an assertion if it cannot be identified.

Parameters
filenameInput filename
commCommunicator for parallel runs
Returns
FieldIO format of filename.

Definition at line 96 of file FieldIO.cpp.

References ASSERTL0, Nektar::ErrorUtil::efatal, Nektar::LibUtilities::eHDF5, Nektar::LibUtilities::eXML, NEKERROR, and Nektar::LibUtilities::PortablePath().

Referenced by CreateForFile(), Nektar::MultiRegions::ExpList::ExtractFileBCs(), Nektar::FieldUtils::Field::FieldIOForFile(), Nektar::LibUtilities::Import(), and Nektar::SpatialDomains::MeshPartition::ReadExpansions().

98 {
99  FieldIOType ioType = eXML;
100  int size = comm->GetSize();
101  bool root = comm->TreatAsRankZero();
102 
103  if (size == 1 || root)
104  {
105  std::string datafilename;
106 
107  // If input is a directory, check for root processor file.
108  if (fs::is_directory(filename))
109  {
110  fs::path p0file("P0000000.fld");
111  fs::path fullpath = filename / p0file;
112  datafilename = PortablePath(fullpath);
113  }
114  else
115  {
116  datafilename = filename;
117  }
118 
119  // Read first 8 bytes. If they correspond with magic bytes below it's an
120  // HDF5 file. XML is potentially a nightmare with all the different
121  // encodings so we'll just assume it's OK if it's not HDF.
122  const unsigned char magic[8] = {
123  0x89, 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a};
124 
125  std::ifstream datafile(datafilename.c_str(), std::ios_base::binary);
126  ASSERTL0(datafile.good(), "Unable to open file: " + filename);
127 
128  ioType = eHDF5;
129  for (unsigned i = 0; i < 8 && datafile.good(); ++i)
130  {
131  int byte = datafile.get();
132  if (byte != magic[i])
133  {
134  ioType = eXML;
135  break;
136  }
137  }
138  }
139 
140  if (size > 1)
141  {
142  int code = (int)ioType;
143  comm->Bcast(code, 0);
144  ioType = (FieldIOType)code;
145  }
146 
147  std::string iofmt;
148  if (ioType == eXML)
149  {
150  iofmt = "Xml";
151  }
152  else if (ioType == eHDF5)
153  {
154  iofmt = "Hdf5";
155  }
156  else
157  {
158  // Error
159  NEKERROR(ErrorUtil::efatal, "Unknown file format");
160  }
161 
162  return iofmt;
163 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:209
FieldIOType
Enumerator for auto-detection of FieldIO types.
Definition: FieldIO.cpp:78
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:41

◆ Import()

void Nektar::LibUtilities::FieldIO::Import ( const std::string &  infilename,
std::vector< FieldDefinitionsSharedPtr > &  fielddefs,
std::vector< std::vector< NekDouble > > &  fielddata = NullVectorNekDoubleVector,
FieldMetaDataMap fieldinfo = NullFieldMetaDataMap,
const Array< OneD, int > &  ElementIDs = NullInt1DArray 
)
inline

Read field information from the file infilename.

Parameters
infilenameInput filename (or directory if parallel format)
fielddefsOn return contains field definitions as read from the input.
fielddataOn return, contains binary field data that stores the input corresponding to fielddefs.
fieldinfoOn returnm, contains the associated field metadata map.
ElementIDsElement IDs that lie on this processor, which can be optionally supplied to avoid reading the entire file on each processor.

Definition at line 339 of file FieldIO.h.

344 {
345  v_Import(infilename, fielddefs, fielddata, fieldinfo, ElementIDs);
346 }
virtual void v_Import(const std::string &infilename, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata=NullVectorNekDoubleVector, FieldMetaDataMap &fieldinfomap=NullFieldMetaDataMap, const Array< OneD, int > &ElementIDs=NullInt1DArray)=0
Read field information from the file infilename.

◆ ImportFieldMetaData()

DataSourceSharedPtr Nektar::LibUtilities::FieldIO::ImportFieldMetaData ( const std::string &  filename,
FieldMetaDataMap fieldmetadatamap 
)
inline

Import the metadata from a field file.

Parameters
filenameInput filename.
fieldmetadatamapOn return contains the field metadata map from filename.

Definition at line 355 of file FieldIO.h.

Referenced by Nektar::LibUtilities::PtsIO::Import(), and Nektar::LibUtilities::FieldIOXml::v_Import().

357 {
358  return v_ImportFieldMetaData(filename, fieldmetadatamap);
359 }
virtual DataSourceSharedPtr v_ImportFieldMetaData(const std::string &filename, FieldMetaDataMap &fieldmetadatamap)=0
Import the metadata from a field file.

◆ SetUpOutput()

std::string Nektar::LibUtilities::FieldIO::SetUpOutput ( const std::string  outname,
bool  perRank,
bool  backup = false 
)
protected

Set up the filesystem ready for output.

This function sets up the output given an output filename outname. This will therefore remove any file or directory with the desired output filename and return the absolute path to the output.

If perRank is set, a new directory will be created to contain one file per process rank.

Parameters
outnameDesired output filename.
perRankTrue if one file-per-rank output is required.
Returns
Absolute path to resulting file.

Definition at line 391 of file FieldIO.cpp.

References ASSERTL0, Nektar::ErrorUtil::efatal, CellMLToNektar.pycml::format, GetFileEnding(), m_comm, m_sharedFilesystem, NEKERROR, Nektar::LibUtilities::PortablePath(), Nektar::LibUtilities::ReduceMax, and Nektar::LibUtilities::ReduceMin.

Referenced by Nektar::LibUtilities::FieldIOHdf5::v_Write(), Nektar::LibUtilities::FieldIOXml::v_Write(), Nektar::LibUtilities::CsvIO::Write(), and Nektar::LibUtilities::PtsIO::Write().

392 {
393  ASSERTL0(!outname.empty(), "Empty path given to SetUpOutput()");
394 
395  int nprocs = m_comm->GetSize();
396  bool root = m_comm->TreatAsRankZero();
397 
398  // Path to output: will be directory if parallel, normal file if
399  // serial.
400  fs::path specPath(outname), fulloutname;
401 
402  // in case we are rank 0 or not on a shared filesystem, check if the specPath already exists
403  if (backup && (root || !m_sharedFilesystem) && fs::exists(specPath))
404  {
405  // rename. foo/bar_123.chk -> foo/bar_123.bak0.chk and in case
406  // foo/bar_123.bak0.chk already exists, foo/bar_123.chk -> foo/bar_123.bak1.chk
407  fs::path bakPath = specPath;
408  int cnt = 0;
409  while (fs::exists(bakPath))
410  {
411  bakPath = specPath.parent_path();
412  bakPath += specPath.stem();
413  bakPath += fs::path(".bak" + std::to_string(cnt++));
414  bakPath += specPath.extension();
415  }
416  std::cout << "renaming " << specPath << " -> " << bakPath << std::endl;
417  try
418  {
419  fs::rename(specPath, bakPath);
420  }
421  catch (fs::filesystem_error &e)
422  {
423  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
424  "Filesystem error: " + std::string(e.what()));
425  }
426  }
427 
428  // wait until rank 0 has moved the old specPath and the changes
429  // have propagated through the filesystem
430  if (backup)
431  {
432  m_comm->Block();
433  int exists = 1;
434  while (exists && perRank)
435  {
436  exists = fs::exists(specPath);
437  m_comm->AllReduce(exists, ReduceMax);
438  }
439  }
440 
441  if (nprocs == 1)
442  {
443  fulloutname = specPath;
444  }
445  else
446  {
447  // Guess at filename that might belong to this process.
448  boost::format pad("P%1$07d.%2$s");
449  pad % m_comm->GetRank() % GetFileEnding();
450 
451  // Generate full path name
452  fs::path poutfile(pad.str());
453  fulloutname = specPath / poutfile;
454  }
455 
456  // Remove any existing file which is in the way
457  if (m_comm->RemoveExistingFiles() && !backup)
458  {
459  if (m_sharedFilesystem)
460  {
461  // First, each process clears up its .fld file. This might or might
462  // not be there (we might have changed numbers of processors between
463  // runs, for example), but we can try anyway.
464  try
465  {
466  fs::remove_all(fulloutname);
467  }
468  catch (fs::filesystem_error &e)
469  {
470  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
471  "Filesystem error: " + std::string(e.what()));
472  }
473  }
474 
475  m_comm->Block();
476 
477  // Now get rank 0 processor to tidy everything else up.
478  if (root || !m_sharedFilesystem)
479  {
480  try
481  {
482  fs::remove_all(specPath);
483  }
484  catch (fs::filesystem_error &e)
485  {
486  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
487  "Filesystem error: " + std::string(e.what()));
488  }
489  }
490 
491  // wait until rank 0 has removed specPath and the changes
492  // have propagated through the filesystem
493  m_comm->Block();
494  int exists = 1;
495  while (exists && perRank)
496  {
497  exists = fs::exists(specPath);
498  m_comm->AllReduce(exists, ReduceMax);
499  }
500  }
501 
502  if (root)
503  {
504  std::cout << "Writing: " << specPath;
505  }
506 
507  // serial processing just add ending.
508  if (nprocs == 1)
509  {
510  return LibUtilities::PortablePath(specPath);
511  }
512 
513  // Create the destination directory
514  if (perRank)
515  {
516  try
517  {
518  if (root || !m_sharedFilesystem)
519  {
520  fs::create_directory(specPath);
521  }
522  }
523  catch (fs::filesystem_error &e)
524  {
526  "Filesystem error: " + std::string(e.what()));
527  }
528 
529  m_comm->Block();
530 
531  // Sit in a loop and make sure target directory has been created
532  int created = 0;
533  while (!created)
534  {
535  created = fs::is_directory(specPath);
536  m_comm->AllReduce(created, ReduceMin);
537  }
538  }
539  else
540  {
541  fulloutname = specPath;
542  }
543 
544  // Return the full path to the partition for this process
545  return LibUtilities::PortablePath(fulloutname);
546 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:209
bool m_sharedFilesystem
Boolean dictating whether we are on a shared filesystem.
Definition: FieldIO.h:268
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:41
LibUtilities::CommSharedPtr m_comm
Communicator to use when writing parallel format.
Definition: FieldIO.h:266
virtual std::string GetFileEnding() const
Helper function that determines default file extension.
Definition: FieldIO.h:276

◆ v_Import()

virtual void Nektar::LibUtilities::FieldIO::v_Import ( const std::string &  infilename,
std::vector< FieldDefinitionsSharedPtr > &  fielddefs,
std::vector< std::vector< NekDouble > > &  fielddata = NullVectorNekDoubleVector,
FieldMetaDataMap fieldinfomap = NullFieldMetaDataMap,
const Array< OneD, int > &  ElementIDs = NullInt1DArray 
)
protectedpure virtual

Read field information from the file infilename.

Parameters
infilenameInput filename (or directory if parallel format)
fielddefsOn return contains field definitions as read from the input.
fielddataOn return, contains binary field data that stores the input corresponding to fielddefs.
fieldinfoOn returnm, contains the associated field metadata map.
ElementIDsElement IDs that lie on this processor, which can be optionally supplied to avoid reading the entire file on each processor.

Implemented in Nektar::LibUtilities::FieldIOXml, and Nektar::LibUtilities::FieldIOHdf5.

◆ v_ImportFieldMetaData()

virtual DataSourceSharedPtr Nektar::LibUtilities::FieldIO::v_ImportFieldMetaData ( const std::string &  filename,
FieldMetaDataMap fieldmetadatamap 
)
protectedpure virtual

Import the metadata from a field file.

Parameters
filenameInput filename.
fieldmetadatamapOn return contains the field metadata map from filename.

Implemented in Nektar::LibUtilities::FieldIOXml, and Nektar::LibUtilities::FieldIOHdf5.

◆ v_Write()

virtual void Nektar::LibUtilities::FieldIO::v_Write ( const std::string &  outFile,
std::vector< FieldDefinitionsSharedPtr > &  fielddefs,
std::vector< std::vector< NekDouble > > &  fielddata,
const FieldMetaDataMap fieldinfomap,
const bool  backup = false 
)
protectedpure virtual

Write out the field information to the file outFile.

Parameters
outFileOutput filename
fielddefsField definitions that define the output
fielddataBinary field data that stores the output corresponding to fielddefs.
fieldinfomapAssociated field metadata map.

Implemented in Nektar::LibUtilities::FieldIOXml, and Nektar::LibUtilities::FieldIOHdf5.

◆ Write()

void Nektar::LibUtilities::FieldIO::Write ( const std::string &  outFile,
std::vector< FieldDefinitionsSharedPtr > &  fielddefs,
std::vector< std::vector< NekDouble > > &  fielddata,
const FieldMetaDataMap fieldinfomap = NullFieldMetaDataMap,
const bool  backup = false 
)
inline

Write out the field information to the file outFile.

Parameters
outFileOutput filename
fielddefsField definitions that define the output
fielddataBinary field data that stores the output corresponding to fielddefs.
fieldinfomapAssociated field metadata map.

Definition at line 317 of file FieldIO.h.

322 {
323  v_Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
324 }
virtual void v_Write(const std::string &outFile, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, const FieldMetaDataMap &fieldinfomap, const bool backup=false)=0
Write out the field information to the file outFile.

Member Data Documentation

◆ m_comm

LibUtilities::CommSharedPtr Nektar::LibUtilities::FieldIO::m_comm
protected

◆ m_sharedFilesystem

bool Nektar::LibUtilities::FieldIO::m_sharedFilesystem
protected

Boolean dictating whether we are on a shared filesystem.

Definition at line 268 of file FieldIO.h.

Referenced by SetUpOutput().