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

328  : m_comm(pComm), m_sharedFilesystem(sharedFilesystem)
329 {
330 }
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

Definition at line 228 of file FieldIO.h.

229  {
230  }

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

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

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

197 {
198  std::string iofmt("Xml");
199  if (session->DefinesSolverInfo("IOFormat"))
200  {
201  iofmt = session->GetSolverInfo("IOFormat");
202  }
203 
204  if (session->DefinesCmdLineArgument("io-format"))
205  {
206  iofmt = session->GetCmdLineArgument<std::string>("io-format");
207  }
208 
210  iofmt,
211  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:145
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());
233  iofmt,
234  session->GetComm(),
235  session->GetSharedFilesystem());
236 }
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::UnsteadySystem::CheckForRestartTime(), Nektar::SolverUtils::SessionFunction::EvaluateFld(), Nektar::GlobalMapping::Mapping::EvaluateFunction(), ExpList_LoadField(), Nektar::SolverUtils::EquationSystem::ImportFld(), Nektar::LinearisedAdvection::ImportFldBase(), Nektar::SmoothedProfileMethod::ReadPhi(), and Nektar::SolverUtils::FilterFieldConvert::v_Initialise().

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

277  {
278  return "fld";
279  }

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

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

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

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

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.

References v_ImportFieldMetaData().

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

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

411 {
412  ASSERTL0(!outname.empty(), "Empty path given to SetUpOutput()");
413 
414  // Create a hash from the filename
415  std::size_t file_id = std::hash<std::string>{}(outname);
416 
417  // Find the minimum and maximum hash for each process
418  std::size_t file_id_max {file_id};
419  std::size_t file_id_min {file_id};
420  m_comm->AllReduce(file_id_max, ReduceMax);
421  m_comm->AllReduce(file_id_min, ReduceMin);
422 
423  // Check that each process has the same filename (hash)
424  ASSERTL0(file_id_min == file_id_max,
425  "All processes do not have the same filename.");
426 
427  int nprocs = m_comm->GetSize();
428  bool root = m_comm->TreatAsRankZero();
429 
430  // Path to output: will be directory if parallel, normal file if
431  // serial.
432  fs::path specPath(outname), fulloutname;
433 
434  // in case we are rank 0 or not on a shared filesystem, check if the specPath already exists
435  if (backup && (root || !m_sharedFilesystem) && fs::exists(specPath))
436  {
437  // rename. foo/bar_123.chk -> foo/bar_123.bak0.chk and in case
438  // foo/bar_123.bak0.chk already exists, foo/bar_123.chk -> foo/bar_123.bak1.chk
439  fs::path bakPath = specPath;
440  int cnt = 0;
441  while (fs::exists(bakPath))
442  {
443  bakPath = specPath.parent_path();
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->Block();
465  int exists = 1;
466  while (exists && perRank)
467  {
468  exists = fs::exists(specPath);
469  m_comm->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->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->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->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->Block();
526  int exists = 1;
527  while (exists && perRank)
528  {
529  exists = fs::exists(specPath);
530  m_comm->AllReduce(exists, ReduceMax);
531  }
532  }
533 
534  if (root)
535  {
536  std::cout << "Writing: " << specPath;
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->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->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 }
virtual std::string GetFileEnding() const
Helper function that determines default file extension.
Definition: FieldIO.h:276

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

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

Referenced by SetUpOutput().