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...
 
const std::string & GetClassName () const
 
std::string GetFileEnding () const
 Helper function that determines default file extension. More...
 

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...
 
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...
 
virtual std::string v_GetFileEnding () const
 
virtual const std::string & v_GetClassName () const =0
 
bool ParallelInTime ()
 Check if solver use Parallel-in-Time. 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 228 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 323 of file FieldIO.cpp.

324  : m_comm(pComm), m_sharedFilesystem(sharedFilesystem)
325 {
326 }
bool m_sharedFilesystem
Boolean dictating whether we are on a shared filesystem.
Definition: FieldIO.h:284
LibUtilities::CommSharedPtr m_comm
Communicator to use when writing parallel format.
Definition: FieldIO.h:278

◆ ~FieldIO()

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

Definition at line 234 of file FieldIO.h.

235  {
236  }

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 344 of file FieldIO.cpp.

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

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().

◆ 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 585 of file FieldIO.cpp.

586 {
587  int i;
588 
589  if (fielddefs->m_elementIDs.size() == 0) // empty partition
590  {
591  return 0;
592  }
593 
594  unsigned int numbasis = 0;
595 
596  // Determine nummodes vector lists are correct length
597  switch (fielddefs->m_shapeType)
598  {
599  case eSegment:
600  numbasis = 1;
601  if (fielddefs->m_numHomogeneousDir)
602  {
603  numbasis += fielddefs->m_numHomogeneousDir;
604  }
605 
606  break;
607  case eTriangle:
608  case eQuadrilateral:
609  if (fielddefs->m_numHomogeneousDir)
610  {
611  numbasis = 3;
612  }
613  else
614  {
615  numbasis = 2;
616  }
617  break;
618  case eTetrahedron:
619  case ePyramid:
620  case ePrism:
621  case eHexahedron:
622  numbasis = 3;
623  break;
624  default:
625  NEKERROR(ErrorUtil::efatal, "Unsupported shape type.");
626  break;
627  }
628 
629  size_t datasize = 0;
630 
631  ASSERTL0(fielddefs->m_basis.size() == numbasis,
632  "Length of basis vector is incorrect");
633 
634  if (fielddefs->m_uniOrder == true)
635  {
636  unsigned int cnt = 0;
637  // calculate datasize
638  switch (fielddefs->m_shapeType)
639  {
640  case eSegment:
641  {
642  int l = fielddefs->m_numModes[cnt++];
643  if (fielddefs->m_numHomogeneousDir == 1)
644  {
645  datasize += l * fielddefs->m_homogeneousZIDs.size();
646  cnt++;
647  }
648  else if (fielddefs->m_numHomogeneousDir == 2)
649  {
650  datasize += l * fielddefs->m_homogeneousYIDs.size();
651  cnt += 2;
652  }
653  else
654  {
655  datasize += l;
656  }
657  }
658  break;
659  case eTriangle:
660  {
661  int l = fielddefs->m_numModes[cnt++];
662  int m = fielddefs->m_numModes[cnt++];
663 
664  if (fielddefs->m_numHomogeneousDir == 1)
665  {
666  datasize += StdTriData::getNumberOfCoefficients(l, m) *
667  fielddefs->m_homogeneousZIDs.size();
668  }
669  else
670  {
671  datasize += StdTriData::getNumberOfCoefficients(l, m);
672  }
673  }
674  break;
675  case eQuadrilateral:
676  {
677  int l = fielddefs->m_numModes[cnt++];
678  int m = fielddefs->m_numModes[cnt++];
679  if (fielddefs->m_numHomogeneousDir == 1)
680  {
681  datasize += l * m * fielddefs->m_homogeneousZIDs.size();
682  }
683  else
684  {
685  datasize += l * m;
686  }
687  }
688  break;
689  case eTetrahedron:
690  {
691  int l = fielddefs->m_numModes[cnt++];
692  int m = fielddefs->m_numModes[cnt++];
693  int n = fielddefs->m_numModes[cnt++];
694  datasize += StdTetData::getNumberOfCoefficients(l, m, n);
695  }
696  break;
697  case ePyramid:
698  {
699  int l = fielddefs->m_numModes[cnt++];
700  int m = fielddefs->m_numModes[cnt++];
701  int n = fielddefs->m_numModes[cnt++];
702  datasize += StdPyrData::getNumberOfCoefficients(l, m, n);
703  }
704  break;
705  case ePrism:
706  {
707  int l = fielddefs->m_numModes[cnt++];
708  int m = fielddefs->m_numModes[cnt++];
709  int n = fielddefs->m_numModes[cnt++];
710  datasize += StdPrismData::getNumberOfCoefficients(l, m, n);
711  }
712  break;
713  case eHexahedron:
714  {
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;
719  }
720  break;
721  default:
722  NEKERROR(ErrorUtil::efatal, "Unsupported shape type.");
723  break;
724  }
725 
726  datasize *= fielddefs->m_elementIDs.size();
727  }
728  else
729  {
730  unsigned int cnt = 0;
731  // calculate data length
732  for (i = 0; i < fielddefs->m_elementIDs.size(); ++i)
733  {
734  switch (fielddefs->m_shapeType)
735  {
736  case eSegment:
737  {
738  int l = fielddefs->m_numModes[cnt++];
739  if (fielddefs->m_numHomogeneousDir == 1)
740  {
741  datasize += l * fielddefs->m_homogeneousZIDs.size();
742  cnt++;
743  }
744  else if (fielddefs->m_numHomogeneousDir == 2)
745  {
746  datasize += l * fielddefs->m_homogeneousYIDs.size();
747  cnt += 2;
748  }
749  else
750  {
751  datasize += l;
752  }
753  }
754  break;
755  case eTriangle:
756  {
757  int l = fielddefs->m_numModes[cnt++];
758  int m = fielddefs->m_numModes[cnt++];
759  if (fielddefs->m_numHomogeneousDir == 1)
760  {
761  datasize += StdTriData::getNumberOfCoefficients(l, m) *
762  fielddefs->m_homogeneousZIDs.size();
763  cnt++;
764  }
765  else
766  {
767  datasize += StdTriData::getNumberOfCoefficients(l, m);
768  }
769  }
770  break;
771  case eQuadrilateral:
772  {
773  int l = fielddefs->m_numModes[cnt++];
774  int m = fielddefs->m_numModes[cnt++];
775  if (fielddefs->m_numHomogeneousDir == 1)
776  {
777  datasize += l * m * fielddefs->m_homogeneousZIDs.size();
778  cnt++;
779  }
780  else
781  {
782  datasize += l * m;
783  }
784  }
785  break;
786  case eTetrahedron:
787  {
788  int l = fielddefs->m_numModes[cnt++];
789  int m = fielddefs->m_numModes[cnt++];
790  int n = fielddefs->m_numModes[cnt++];
791  datasize += StdTetData::getNumberOfCoefficients(l, m, n);
792  }
793  break;
794  case ePyramid:
795  {
796  int l = fielddefs->m_numModes[cnt++];
797  int m = fielddefs->m_numModes[cnt++];
798  int n = fielddefs->m_numModes[cnt++];
799  datasize += StdPyrData::getNumberOfCoefficients(l, m, n);
800  }
801  break;
802  case ePrism:
803  {
804  int l = fielddefs->m_numModes[cnt++];
805  int m = fielddefs->m_numModes[cnt++];
806  int n = fielddefs->m_numModes[cnt++];
807  datasize += StdPrismData::getNumberOfCoefficients(l, m, n);
808  }
809  break;
810  case eHexahedron:
811  {
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;
816  }
817  break;
818  default:
819  NEKERROR(ErrorUtil::efatal, "Unsupported shape type.");
820  break;
821  }
822  }
823  }
824 
825  return (int)datasize;
826 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:284
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:237
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:192
int getNumberOfCoefficients(int Na, int Nb)
Definition: ShapeType.hpp:114

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().

◆ 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 197 of file FieldIO.cpp.

199 {
200  std::string iofmt("Xml");
201  if (session->DefinesSolverInfo("IOFormat"))
202  {
203  iofmt = session->GetSolverInfo("IOFormat");
204  }
205 
206  if (session->DefinesCmdLineArgument("io-format"))
207  {
208  iofmt = session->GetCmdLineArgument<std::string>("io-format");
209  }
210 
211  return GetFieldIOFactory().CreateInstance(iofmt, session->GetComm(),
212  session->GetSharedFilesystem());
213 }
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
FieldIOFactory & GetFieldIOFactory()
Returns the FieldIO factory.
Definition: FieldIO.cpp:72

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().

◆ 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 226 of file FieldIO.cpp.

229 {
230  const std::string iofmt =
231  FieldIO::GetFileType(filename, session->GetComm());
232  return GetFieldIOFactory().CreateInstance(iofmt, session->GetComm(),
233  session->GetSharedFilesystem());
234 }
static const std::string GetFileType(const std::string &filename, CommSharedPtr comm)
Determine file type of given input file.
Definition: FieldIO.cpp:97

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

Referenced by Nektar::SolverUtils::ForcingMovingReferenceFrame::CheckForRestartTheta(), Nektar::SolverUtils::UnsteadySystem::CheckForRestartTime(), Nektar::SolverUtils::SessionFunction::EvaluateFld(), Nektar::GlobalMapping::Mapping::EvaluateFunction(), ExpList_LoadField(), Nektar::SolverUtils::EquationSystem::ImportFld(), Nektar::LinearisedAdvection::ImportFldBase(), Nektar::SmoothedProfileMethod::ReadPhi(), Nektar::SolverUtils::FilterBodyFittedVelocity::v_Initialise(), and Nektar::SolverUtils::FilterFieldConvert::v_Initialise().

◆ GetClassName()

const std::string& Nektar::LibUtilities::FieldIO::GetClassName ( ) const
inline

Definition at line 259 of file FieldIO.h.

260  {
261  return v_GetClassName();
262  }
virtual const std::string & v_GetClassName() const =0

References v_GetClassName().

◆ GetFileEnding()

std::string Nektar::LibUtilities::FieldIO::GetFileEnding ( ) const
inline

Helper function that determines default file extension.

Definition at line 275 of file FieldIO.h.

276  {
277  return v_GetFileEnding();
278  };
virtual std::string v_GetFileEnding() const
Definition: FieldIO.h:313

References v_GetFileEnding().

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

◆ 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 97 of file FieldIO.cpp.

99 {
100  FieldIOType ioType = eXML;
101  int size = comm->GetSpaceComm()->GetSize();
102  bool root = comm->GetSpaceComm()->TreatAsRankZero();
103 
104  if (size == 1 || root)
105  {
106  std::string datafilename;
107 
108  // If input is a directory, check for root processor file.
109  if (fs::is_directory(filename))
110  {
111  fs::path fullpath = filename;
112  fs::path d = fullpath;
113  boost::regex expr("P\\d{7}.fld");
114  boost::smatch what;
115 
116  bool found = false;
117  for (auto &f : fs::directory_iterator(d))
118  {
119  if (boost::regex_match(f.path().filename().string(), what,
120  expr))
121  {
122  found = true;
123  fullpath = f.path();
124  break;
125  }
126  }
127 
128  ASSERTL0(found, std::string("Failed to open a PXXXXXXX.fld file "
129  "in directory: " +
130  filename)
131  .c_str());
132 
133  datafilename = PortablePath(fullpath);
134  }
135  else
136  {
137  datafilename = filename;
138  }
139 
140  // Read first 8 bytes. If they correspond with magic bytes below it's an
141  // HDF5 file. XML is potentially a nightmare with all the different
142  // encodings so we'll just assume it's OK if it's not HDF.
143  const unsigned char magic[8] = {0x89, 0x48, 0x44, 0x46,
144  0x0d, 0x0a, 0x1a, 0x0a};
145 
146  std::ifstream datafile(datafilename.c_str(), std::ios_base::binary);
147  ASSERTL0(datafile.good(), "Unable to open file: " + filename);
148 
149  ioType = eHDF5;
150  for (unsigned i = 0; i < 8 && datafile.good(); ++i)
151  {
152  int byte = datafile.get();
153  if (byte != magic[i])
154  {
155  ioType = eXML;
156  break;
157  }
158  }
159  }
160 
161  if (size > 1)
162  {
163  int code = (int)ioType;
164  comm->GetSpaceComm()->Bcast(code, 0);
165  ioType = (FieldIOType)code;
166  }
167 
168  std::string iofmt;
169  if (ioType == eXML)
170  {
171  iofmt = "Xml";
172  }
173  else if (ioType == eHDF5)
174  {
175  iofmt = "Hdf5";
176  }
177  else
178  {
179  // Error
180  NEKERROR(ErrorUtil::efatal, "Unknown file format");
181  }
182 
183  return iofmt;
184 }
FieldIOType
Enumerator for auto-detection of FieldIO types.
Definition: FieldIO.cpp:80
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:45

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

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

◆ 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 360 of file FieldIO.h.

365 {
366  v_Import(infilename, fielddefs, fielddata, fieldinfo, ElementIDs);
367 }
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.

References v_Import().

◆ 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 376 of file FieldIO.h.

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

References v_ImportFieldMetaData().

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

◆ ParallelInTime()

bool Nektar::LibUtilities::FieldIO::ParallelInTime ( )
inlineprotected

Check if solver use Parallel-in-Time.

Definition at line 321 of file FieldIO.h.

322  {
323  return m_comm->GetSize() != m_comm->GetSpaceComm()->GetSize();
324  }

References m_comm.

◆ 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 406 of file FieldIO.cpp.

408 {
409  ASSERTL0(!outname.empty(), "Empty path given to SetUpOutput()");
410 
411  // Create a hash from the filename
412  std::size_t file_id = std::hash<std::string>{}(outname);
413 
414  // Find the minimum and maximum hash for each process
415  std::size_t file_id_max{file_id};
416  std::size_t file_id_min{file_id};
417  m_comm->GetSpaceComm()->AllReduce(file_id_max, ReduceMax);
418  m_comm->GetSpaceComm()->AllReduce(file_id_min, ReduceMin);
419 
420  // Check that each process has the same filename (hash)
421  ASSERTL0(file_id_min == file_id_max,
422  "All processes do not have the same filename.");
423 
424  int nprocs = m_comm->GetSpaceComm()->GetSize();
425  bool root = m_comm->GetSpaceComm()->TreatAsRankZero();
426 
427  // Path to output: will be directory if parallel, normal file if
428  // serial.
429  fs::path specPath(outname), fulloutname;
430 
431  // in case we are rank 0 or not on a shared filesystem, check if the
432  // specPath already exists
433  if (backup && (root || !m_sharedFilesystem) && fs::exists(specPath))
434  {
435  // rename. foo/bar_123.chk -> foo/bar_123.bak0.chk and in case
436  // foo/bar_123.bak0.chk already exists, foo/bar_123.chk ->
437  // foo/bar_123.bak1.chk
438  fs::path bakPath = specPath;
439  int cnt = 0;
440  while (fs::exists(bakPath))
441  {
442  bakPath = specPath.parent_path();
443  bakPath += fs::path(bakPath.extension() == ".pit" ? "/" : "");
444  bakPath += specPath.stem();
445  bakPath += fs::path(".bak" + std::to_string(cnt++));
446  bakPath += specPath.extension();
447  }
448  std::cout << "renaming " << specPath << " -> " << bakPath << std::endl;
449  try
450  {
451  fs::rename(specPath, bakPath);
452  }
453  catch (fs::filesystem_error &e)
454  {
455  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
456  "Filesystem error: " + std::string(e.what()));
457  }
458  }
459 
460  // wait until rank 0 has moved the old specPath and the changes
461  // have propagated through the filesystem
462  if (backup)
463  {
464  m_comm->GetSpaceComm()->Block();
465  int exists = 1;
466  while (exists && perRank)
467  {
468  exists = fs::exists(specPath);
469  m_comm->GetSpaceComm()->AllReduce(exists, ReduceMax);
470  }
471  }
472 
473  if (nprocs == 1)
474  {
475  fulloutname = specPath;
476  }
477  else
478  {
479  // Guess at filename that might belong to this process.
480  boost::format pad("P%1$07d.%2$s");
481  pad % m_comm->GetSpaceComm()->GetRank() % GetFileEnding();
482 
483  // Generate full path name
484  fs::path poutfile(pad.str());
485  fulloutname = specPath / poutfile;
486  }
487 
488  // Remove any existing file which is in the way
489  if (m_comm->GetSpaceComm()->RemoveExistingFiles() && !backup)
490  {
491  if (m_sharedFilesystem)
492  {
493  // First, each process clears up its .fld file. This might or might
494  // not be there (we might have changed numbers of processors between
495  // runs, for example), but we can try anyway.
496  try
497  {
498  fs::remove_all(fulloutname);
499  }
500  catch (fs::filesystem_error &e)
501  {
502  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
503  "Filesystem error: " + std::string(e.what()));
504  }
505  }
506 
507  m_comm->GetSpaceComm()->Block();
508 
509  // Now get rank 0 processor to tidy everything else up.
510  if (root || !m_sharedFilesystem)
511  {
512  try
513  {
514  fs::remove_all(specPath);
515  }
516  catch (fs::filesystem_error &e)
517  {
518  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
519  "Filesystem error: " + std::string(e.what()));
520  }
521  }
522 
523  // wait until rank 0 has removed specPath and the changes
524  // have propagated through the filesystem
525  m_comm->GetSpaceComm()->Block();
526  int exists = 1;
527  while (exists && perRank)
528  {
529  exists = fs::exists(specPath);
530  m_comm->GetSpaceComm()->AllReduce(exists, ReduceMax);
531  }
532  }
533 
534  if (root)
535  {
536  std::cout << "Writing: " << specPath << std::endl;
537  }
538 
539  // serial processing just add ending.
540  if (nprocs == 1)
541  {
542  return LibUtilities::PortablePath(specPath);
543  }
544 
545  // Create the destination directory
546  if (perRank)
547  {
548  try
549  {
550  if (root || !m_sharedFilesystem)
551  {
552  fs::create_directory(specPath);
553  }
554  }
555  catch (fs::filesystem_error &e)
556  {
558  "Filesystem error: " + std::string(e.what()));
559  }
560 
561  m_comm->GetSpaceComm()->Block();
562 
563  // Sit in a loop and make sure target directory has been created
564  int created = 0;
565  while (!created)
566  {
567  created = fs::is_directory(specPath);
568  m_comm->GetSpaceComm()->AllReduce(created, ReduceMin);
569  }
570  }
571  else
572  {
573  fulloutname = specPath;
574  }
575 
576  // Return the full path to the partition for this process
577  return LibUtilities::PortablePath(fulloutname);
578 }
std::string GetFileEnding() const
Helper function that determines default file extension.
Definition: FieldIO.h:275

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().

◆ v_GetClassName()

virtual const std::string& Nektar::LibUtilities::FieldIO::v_GetClassName ( ) const
protectedpure virtual

◆ v_GetFileEnding()

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

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

Definition at line 313 of file FieldIO.h.

314  {
315  return "fld";
316  }

Referenced by GetFileEnding().

◆ 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.

Referenced by Import().

◆ 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.

Referenced by ImportFieldMetaData().

◆ 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.

Referenced by Write().

◆ 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 338 of file FieldIO.h.

343 {
344  v_Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
345 }
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.

References v_Write().

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 284 of file FieldIO.h.

Referenced by SetUpOutput().