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::vector< unsigned int > GetNumberOfCoeffsPerElement (const FieldDefinitionsSharedPtr &fielddefs)
 Compute number of data points needed to store expansion inside each element. 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
 

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

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

◆ ~FieldIO()

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

Definition at line 232 of file FieldIO.h.

233 {
234 }

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

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

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(), Nektar::SpatialDomains::MeshGraphIOXml::v_WriteGeometry(), 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 690 of file FieldIO.cpp.

691{
692 // Return 0 if this is an empty parition
693 if (fielddefs->m_elementIDs.size() == 0)
694 {
695 return 0;
696 }
697
698 unsigned int numbasis = 0;
699
700 // Determine nummodes vector lists are correct length
701 switch (fielddefs->m_shapeType)
702 {
703 case eSegment:
704 numbasis = 1;
705 if (fielddefs->m_numHomogeneousDir)
706 {
707 numbasis += fielddefs->m_numHomogeneousDir;
708 }
709
710 break;
711 case eTriangle:
712 case eQuadrilateral:
713 if (fielddefs->m_numHomogeneousDir)
714 {
715 numbasis = 3;
716 }
717 else
718 {
719 numbasis = 2;
720 }
721 break;
722 case eTetrahedron:
723 case ePyramid:
724 case ePrism:
725 case eHexahedron:
726 numbasis = 3;
727 break;
728 default:
729 NEKERROR(ErrorUtil::efatal, "Unsupported shape type.");
730 break;
731 }
732
733 ASSERTL0(fielddefs->m_basis.size() == numbasis,
734 "Length of basis vector is incorrect");
735
736 if (fielddefs->m_uniOrder == true)
737 {
738 // Counter is updated by "GetNumberOfDataPoints()"
739 unsigned int cnt = 0;
740
741 const int datasize = GetNumberOfDataPoints(fielddefs, cnt);
742
743 return datasize * fielddefs->m_elementIDs.size();
744 }
745 else
746 {
747 // Counter is updated by "GetNumberOfDataPoints()"
748 unsigned int cnt = 0;
749
750 int datasize = 0;
751
752 for (int i = 0; i < fielddefs->m_elementIDs.size(); ++i)
753 {
754 datasize += GetNumberOfDataPoints(fielddefs, cnt);
755 }
756
757 return datasize;
758 }
759}
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:202
int GetNumberOfDataPoints(const FieldDefinitionsSharedPtr &fielddefs, unsigned int &cnt)
Compute the number of values needed to store elemental expansion.
Definition: FieldIO.cpp:587

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::GetNumberOfDataPoints(), and NEKERROR.

Referenced by Nektar::LibUtilities::FieldIOXml::ImportFieldData(), Nektar::LibUtilities::FieldIOHdf5::v_Import(), 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
209 return GetFieldIOFactory().CreateInstance(iofmt, session->GetComm(),
210 session->GetSharedFilesystem());
211}
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
FieldIOFactory & GetFieldIOFactory()
Returns the FieldIO factory.
Definition: FieldIO.cpp:70

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

Referenced by Diffusion::Diffusion(), Nektar::VortexWaveInteraction::FileRelaxation(), Nektar::FilterBenchmark::FilterBenchmark(), Nektar::SolverUtils::FilterCheckpoint::FilterCheckpoint(), Nektar::FilterCheckpointCellModel::FilterCheckpointCellModel(), Nektar::FilterHilbertFFTPhase::FilterHilbertFFTPhase(), Nektar::SolverUtils::FilterModalEnergy::FilterModalEnergy(), Nektar::FilterOffsetPhase::FilterOffsetPhase(), 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 224 of file FieldIO.cpp.

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

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

Referenced by Nektar::SolverUtils::UnsteadySystem::CheckForRestartTime(), Nektar::SolverUtils::SessionFunction::EvaluateFld(), Nektar::GlobalMapping::Mapping::EvaluateFunction(), Nektar::SolverUtils::EquationSystem::ImportFld(), Nektar::LinearisedAdvection::ImportFldBase(), Nektar::SolverUtils::FileFieldInterpolator::ImportFldBase(), Nektar::CellModel::LoadCellModel(), Nektar::SpatialDomains::MeshGraph::ReadExpansionInfo(), Nektar::SmoothedProfileMethod::ReadPhi(), Nektar::SolverUtils::ForcingMovingReferenceFrame::SetInitialConditions(), Nektar::SolverUtils::FilterBodyFittedVelocity::v_Initialise(), and Nektar::SolverUtils::FilterFieldConvert::v_Initialise().

◆ GetClassName()

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

Definition at line 257 of file FieldIO.h.

258 {
259 return v_GetClassName();
260 }
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 273 of file FieldIO.h.

274 {
275 return v_GetFileEnding();
276 };
virtual std::string v_GetFileEnding() const
Definition: FieldIO.h:314

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

97{
98 FieldIOType ioType = eXML;
99 int size = comm->GetSpaceComm()->GetSize();
100 bool root = comm->GetSpaceComm()->TreatAsRankZero();
101
102 if (size == 1 || root)
103 {
104 std::string datafilename;
105
106 // If input is a directory, check for root processor file.
107 if (fs::is_directory(filename))
108 {
109 fs::path fullpath = filename;
110 fs::path d = fullpath;
111 std::regex expr("P\\d{7}.fld");
112 std::smatch what;
113
114 bool found = false;
115 for (auto &f : fs::directory_iterator(d))
116 {
117 std::string filename = f.path().filename().string();
118 if (std::regex_match(filename, what, expr))
119 {
120 found = true;
121 fullpath = f.path();
122 break;
123 }
124 }
125
126 ASSERTL0(found, std::string("Failed to open a PXXXXXXX.fld file "
127 "in directory: " +
128 filename)
129 .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] = {0x89, 0x48, 0x44, 0x46,
142 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->GetSpaceComm()->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:78
static std::string PortablePath(const fs::path &path)
create portable path on different platforms for std::filesystem path.
Definition: Filesystem.hpp:56
std::vector< double > d(NPUPPER *NPUPPER)

References ASSERTL0, Nektar::UnitTests::d(), 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().

◆ GetNumberOfCoeffsPerElement()

std::vector< unsigned int > Nektar::LibUtilities::FieldIO::GetNumberOfCoeffsPerElement ( const FieldDefinitionsSharedPtr fielddefs)
protected

Compute number of data points needed to store expansion inside each element.

Parameters
fielddefsField definitions.

Definition at line 767 of file FieldIO.cpp.

769{
770 // Allocate vector with results
771 std::vector<unsigned int> coeffsPerElmt;
772
773 // Return empty vector if partition is empty
774 if (fielddefs->m_elementIDs.size() == 0)
775 {
776 return coeffsPerElmt;
777 }
778
779 // Add elements to vector
780 coeffsPerElmt.resize(fielddefs->m_elementIDs.size());
781
782 if (fielddefs->m_uniOrder == true)
783 {
784 // Counter is updated by "GetNumberOfDataPoints"
785 unsigned int cnt = 0;
786
787 const int datasize = GetNumberOfDataPoints(fielddefs, cnt);
788
789 for (int i = 0; i < fielddefs->m_elementIDs.size(); ++i)
790 {
791 coeffsPerElmt[i] = datasize;
792 }
793 }
794 else
795 {
796 // Counter is updated by "GetNumberOfDataPoints"
797 unsigned int cnt = 0;
798
799 for (int i = 0; i < fielddefs->m_elementIDs.size(); ++i)
800 {
801 coeffsPerElmt[i] = GetNumberOfDataPoints(fielddefs, cnt);
802 }
803 }
804
805 return coeffsPerElmt;
806}

References Nektar::LibUtilities::GetNumberOfDataPoints().

Referenced by Nektar::LibUtilities::FieldIOHdf5::v_Import().

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

360{
361 v_Import(infilename, fielddefs, fielddata, fieldinfo, ElementIDs);
362}
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 371 of file FieldIO.h.

373{
374 return v_ImportFieldMetaData(filename, fieldmetadatamap);
375}
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 404 of file FieldIO.cpp.

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

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::CsvIO, and Nektar::LibUtilities::PtsIO.

Definition at line 314 of file FieldIO.h.

315 {
316 return "fld";
317 }

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::FieldIOHdf5, and Nektar::LibUtilities::FieldIOXml.

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::FieldIOHdf5, and Nektar::LibUtilities::FieldIOXml.

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::FieldIOHdf5, and Nektar::LibUtilities::FieldIOXml.

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

338{
339 v_Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
340}
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 282 of file FieldIO.h.

Referenced by SetUpOutput().