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

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

◆ ~FieldIO()

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

Definition at line 225 of file FieldIO.h.

226  {
227  }

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

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

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

200 {
201  std::string iofmt("Xml");
202  if (session->DefinesSolverInfo("IOFormat"))
203  {
204  iofmt = session->GetSolverInfo("IOFormat");
205  }
206 
207  if (session->DefinesCmdLineArgument("io-format"))
208  {
209  iofmt = session->GetCmdLineArgument<std::string>("io-format");
210  }
211 
212  return GetFieldIOFactory().CreateInstance(iofmt, session->GetComm(),
213  session->GetSharedFilesystem());
214 }
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 227 of file FieldIO.cpp.

230 {
231  const std::string iofmt =
232  FieldIO::GetFileType(filename, session->GetComm());
233  return GetFieldIOFactory().CreateInstance(iofmt, session->GetComm(),
234  session->GetSharedFilesystem());
235 }
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(), 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 271 of file FieldIO.h.

272  {
273  return "fld";
274  }

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,
121  expr))
122  {
123  found = true;
124  fullpath = f.path();
125  break;
126  }
127  }
128 
129  ASSERTL0(found, std::string("Failed to open a PXXXXXXX.fld file "
130  "in directory: " +
131  filename)
132  .c_str());
133 
134  datafilename = PortablePath(fullpath);
135  }
136  else
137  {
138  datafilename = filename;
139  }
140 
141  // Read first 8 bytes. If they correspond with magic bytes below it's an
142  // HDF5 file. XML is potentially a nightmare with all the different
143  // encodings so we'll just assume it's OK if it's not HDF.
144  const unsigned char magic[8] = {0x89, 0x48, 0x44, 0x46,
145  0x0d, 0x0a, 0x1a, 0x0a};
146 
147  std::ifstream datafile(datafilename.c_str(), std::ios_base::binary);
148  ASSERTL0(datafile.good(), "Unable to open file: " + filename);
149 
150  ioType = eHDF5;
151  for (unsigned i = 0; i < 8 && datafile.good(); ++i)
152  {
153  int byte = datafile.get();
154  if (byte != magic[i])
155  {
156  ioType = eXML;
157  break;
158  }
159  }
160  }
161 
162  if (size > 1)
163  {
164  int code = (int)ioType;
165  comm->Bcast(code, 0);
166  ioType = (FieldIOType)code;
167  }
168 
169  std::string iofmt;
170  if (ioType == eXML)
171  {
172  iofmt = "Xml";
173  }
174  else if (ioType == eHDF5)
175  {
176  iofmt = "Hdf5";
177  }
178  else
179  {
180  // Error
181  NEKERROR(ErrorUtil::efatal, "Unknown file format");
182  }
183 
184  return iofmt;
185 }
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: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 334 of file FieldIO.h.

339 {
340  v_Import(infilename, fielddefs, fielddata, fieldinfo, ElementIDs);
341 }
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 350 of file FieldIO.h.

352 {
353  return v_ImportFieldMetaData(filename, fieldmetadatamap);
354 }
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 407 of file FieldIO.cpp.

409 {
410  ASSERTL0(!outname.empty(), "Empty path given to SetUpOutput()");
411 
412  // Create a hash from the filename
413  std::size_t file_id = std::hash<std::string>{}(outname);
414 
415  // Find the minimum and maximum hash for each process
416  std::size_t file_id_max{file_id};
417  std::size_t file_id_min{file_id};
418  m_comm->AllReduce(file_id_max, ReduceMax);
419  m_comm->AllReduce(file_id_min, ReduceMin);
420 
421  // Check that each process has the same filename (hash)
422  ASSERTL0(file_id_min == file_id_max,
423  "All processes do not have the same filename.");
424 
425  int nprocs = m_comm->GetSize();
426  bool root = m_comm->TreatAsRankZero();
427 
428  // Path to output: will be directory if parallel, normal file if
429  // serial.
430  fs::path specPath(outname), fulloutname;
431 
432  // in case we are rank 0 or not on a shared filesystem, check if the
433  // specPath already exists
434  if (backup && (root || !m_sharedFilesystem) && fs::exists(specPath))
435  {
436  // rename. foo/bar_123.chk -> foo/bar_123.bak0.chk and in case
437  // foo/bar_123.bak0.chk already exists, foo/bar_123.chk ->
438  // 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:271

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

317 {
318  v_Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
319 }
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 263 of file FieldIO.h.

Referenced by SetUpOutput().