39#include <boost/format.hpp>
59 :
FieldIO(pComm, sharedFilesystem)
84 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
85 std::vector<std::vector<NekDouble>> &fielddata,
89 double tm0 = 0.0, tm1 = 0.0;
90 if (
m_comm->TreatAsRankZero())
96 ASSERTL1(fielddefs.size() == fielddata.size(),
97 "Length of fielddefs and fielddata incompatible");
98 for (
int f = 0; f < fielddefs.size(); ++f)
101 "Fielddata vector must contain at least one value.");
103 ASSERTL1(fielddata[f].size() == fielddefs[f]->m_fields.size() *
105 "Invalid size of fielddata vector.");
111 std::string filename =
SetUpOutput(outFile,
true, backup);
116 TiXmlDeclaration *decl =
new TiXmlDeclaration(
"1.0",
"utf-8",
"");
117 doc.LinkEndChild(decl);
119 TiXmlElement *root =
new TiXmlElement(
"NEKTAR");
120 doc.LinkEndChild(root);
124 for (
int f = 0; f < fielddefs.size(); ++f)
128 TiXmlElement *elemTag =
new TiXmlElement(
"ELEMENTS");
129 root->LinkEndChild(elemTag);
132 std::string fieldsString;
134 std::stringstream fieldsStringStream;
136 for (
size_t i = 0; i < fielddefs[f]->m_fields.size(); i++)
140 fieldsStringStream <<
",";
142 fieldsStringStream << fielddefs[f]->m_fields[i];
145 fieldsString = fieldsStringStream.str();
147 elemTag->SetAttribute(
"FIELDS", fieldsString);
150 std::string shapeString;
152 std::stringstream shapeStringStream;
153 shapeStringStream <<
ShapeTypeMap[fielddefs[f]->m_shapeType];
154 if (fielddefs[f]->m_numHomogeneousDir == 1)
156 shapeStringStream <<
"-HomogenousExp1D";
158 else if (fielddefs[f]->m_numHomogeneousDir == 2)
160 shapeStringStream <<
"-HomogenousExp2D";
163 if (fielddefs[f]->m_homoStrips)
165 shapeStringStream <<
"-Strips";
168 shapeString = shapeStringStream.str();
170 elemTag->SetAttribute(
"SHAPE", shapeString);
173 std::string basisString;
175 std::stringstream basisStringStream;
177 for (
size_t i = 0; i < fielddefs[f]->m_basis.size(); i++)
181 basisStringStream <<
",";
183 basisStringStream <<
BasisTypeMap[fielddefs[f]->m_basis[i]];
186 basisString = basisStringStream.str();
188 elemTag->SetAttribute(
"BASIS", basisString);
191 if (fielddefs[f]->m_numHomogeneousDir)
193 std::string homoLenString;
195 std::stringstream homoLenStringStream;
197 for (
int i = 0; i < fielddefs[f]->m_numHomogeneousDir; ++i)
201 homoLenStringStream <<
",";
204 << fielddefs[f]->m_homogeneousLengths[i];
207 homoLenString = homoLenStringStream.str();
209 elemTag->SetAttribute(
"HOMOGENEOUSLENGTHS", homoLenString);
213 if (fielddefs[f]->m_numHomogeneousDir)
215 if (fielddefs[f]->m_homogeneousYIDs.size() > 0)
217 std::string homoYIDsString;
219 std::stringstream homoYIDsStringStream;
221 for (
int i = 0; i < fielddefs[f]->m_homogeneousYIDs.size();
226 homoYIDsStringStream <<
",";
229 << fielddefs[f]->m_homogeneousYIDs[i];
232 homoYIDsString = homoYIDsStringStream.str();
234 elemTag->SetAttribute(
"HOMOGENEOUSYIDS", homoYIDsString);
237 if (fielddefs[f]->m_homogeneousZIDs.size() > 0)
239 std::string homoZIDsString;
241 std::stringstream homoZIDsStringStream;
243 for (
int i = 0; i < fielddefs[f]->m_homogeneousZIDs.size();
248 homoZIDsStringStream <<
",";
251 << fielddefs[f]->m_homogeneousZIDs[i];
254 homoZIDsString = homoZIDsStringStream.str();
256 elemTag->SetAttribute(
"HOMOGENEOUSZIDS", homoZIDsString);
259 if (fielddefs[f]->m_homogeneousSIDs.size() > 0)
261 std::string homoSIDsString;
263 std::stringstream homoSIDsStringStream;
265 for (
int i = 0; i < fielddefs[f]->m_homogeneousSIDs.size();
270 homoSIDsStringStream <<
",";
273 << fielddefs[f]->m_homogeneousSIDs[i];
276 homoSIDsString = homoSIDsStringStream.str();
278 elemTag->SetAttribute(
"HOMOGENEOUSSIDS", homoSIDsString);
283 std::string numModesString;
285 std::stringstream numModesStringStream;
287 if (fielddefs[f]->m_uniOrder)
289 numModesStringStream <<
"UNIORDER:";
292 for (
size_t i = 0; i < fielddefs[f]->m_basis.size(); i++)
296 numModesStringStream <<
",";
298 numModesStringStream << fielddefs[f]->m_numModes[i];
304 numModesStringStream <<
"MIXORDER:";
306 for (
size_t i = 0; i < fielddefs[f]->m_numModes.size(); i++)
310 numModesStringStream <<
",";
312 numModesStringStream << fielddefs[f]->m_numModes[i];
317 numModesString = numModesStringStream.str();
319 elemTag->SetAttribute(
"NUMMODESPERDIR", numModesString);
324 std::string idString;
326 std::stringstream idStringStream;
330 elemTag->SetAttribute(
"ID", idString);
331 elemTag->SetAttribute(
"COMPRESSED",
337 elemTag->SetAttribute(
"BITSIZE",
341 std::string base64string;
344 "Failed to compress field data.");
346 elemTag->LinkEndChild(
new TiXmlText(base64string));
348 doc.SaveFile(filename);
350 m_comm->GetSpaceComm()->Block();
353 if (
m_comm->TreatAsRankZero())
356 std::cout <<
" (" << tm1 - tm0 <<
"s, XML)" << std::endl;
373 const std::string &outFile,
const std::vector<std::string> fileNames,
374 std::vector<std::vector<unsigned int>> &elementList,
378 TiXmlDeclaration *decl =
new TiXmlDeclaration(
"1.0",
"utf-8",
"");
379 doc.LinkEndChild(decl);
381 ASSERTL0(fileNames.size() == elementList.size(),
382 "Outfile names and list of elements ids does not match");
384 TiXmlElement *root =
new TiXmlElement(
"NEKTAR");
385 doc.LinkEndChild(root);
389 for (
int t = 0; t < fileNames.size(); ++t)
391 if (elementList[t].size())
393 TiXmlElement *elemIDs =
new TiXmlElement(
"Partition");
394 root->LinkEndChild(elemIDs);
396 elemIDs->SetAttribute(
"FileName", fileNames[t]);
400 elemIDs->LinkEndChild(
new TiXmlText(IDstr));
404 doc.SaveFile(outFile);
420 const std::string &inFile, std::vector<std::string> &fileNames,
421 std::vector<std::vector<unsigned int>> &elementList,
424 TiXmlDocument doc(inFile);
425 bool loadOkay = doc.LoadFile();
427 std::stringstream errstr;
428 errstr <<
"Unable to load file: " << inFile << std::endl;
429 errstr <<
"Reason: " << doc.ErrorDesc() << std::endl;
430 errstr <<
"Position: Line " << doc.ErrorRow() <<
", Column "
431 << doc.ErrorCol() << std::endl;
435 TiXmlHandle docHandle(&doc);
439 TiXmlElement *master = doc.FirstChildElement(
"NEKTAR");
440 ASSERTL0(master,
"Unable to find NEKTAR tag in file.");
443 std::string strPartition =
"Partition";
446 TiXmlElement *fldfileIDs = master->FirstChildElement(strPartition.c_str());
450 strPartition =
"MultipleFldFiles";
451 fldfileIDs = master->FirstChildElement(
"MultipleFldFiles");
453 ASSERTL0(fldfileIDs,
"Unable to find 'Partition' or 'MultipleFldFiles' tag "
454 "within nektar tag.");
459 const char *attr = fldfileIDs->Attribute(
"FileName");
460 ASSERTL0(attr,
"'FileName' not provided as an attribute of '" +
461 strPartition +
"' tag.");
462 fileNames.push_back(std::string(attr));
464 const char *elementIDs = fldfileIDs->GetText();
465 ASSERTL0(elementIDs,
"Element IDs not specified.");
467 std::string elementIDsStr(elementIDs);
469 std::vector<unsigned int> idvec;
472 elementList.push_back(idvec);
474 fldfileIDs = fldfileIDs->NextSiblingElement(strPartition.c_str());
491 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
492 std::vector<std::vector<NekDouble>> &fielddata,
496 std::string infile = infilename;
498 fs::path pinfilename(infilename);
502 if (fs::is_directory(pinfilename))
504 fs::path infofile(
"Info.xml");
505 fs::path fullpath = pinfilename / infofile;
508 std::vector<std::string> filenames;
509 std::vector<std::vector<unsigned int>> elementIDs_OnPartitions;
519 for (
int i = 0; i < filenames.size(); ++i)
521 fs::path pfilename(filenames[i]);
522 fullpath = pinfilename / pfilename;
535 std::map<int, std::vector<int>> FileIDs;
536 std::set<int> LoadFile;
538 for (i = 0; i < elementIDs_OnPartitions.size(); ++i)
540 for (j = 0; j < elementIDs_OnPartitions[i].size(); ++j)
542 FileIDs[elementIDs_OnPartitions[i][j]].push_back(i);
546 for (i = 0; i < ElementIDs.size(); ++i)
548 auto it = FileIDs.find(ElementIDs[i]);
549 if (it != FileIDs.end())
551 for (j = 0; j < it->second.size(); ++j)
553 LoadFile.insert(it->second[j]);
558 for (
auto &iter : LoadFile)
560 fs::path pfilename(filenames[iter]);
561 fullpath = pinfilename / pfilename;
596 TiXmlElement *metadata =
nullptr;
597 TiXmlElement *master =
nullptr;
600 master = xml->Get().FirstChildElement(
"NEKTAR");
601 ASSERTL0(master,
"Unable to find NEKTAR tag in file.");
602 std::string strLoop =
"NEKTAR";
604 metadata = master->FirstChildElement(
"Metadata");
607 TiXmlElement *param = metadata->FirstChildElement();
611 std::string paramString = param->Value();
612 if (paramString !=
"Provenance")
615 if (param->NoChildren())
617 fieldmetadatamap[paramString] =
"";
621 TiXmlNode *paramBody = param->FirstChild();
622 std::string paramBodyStr = paramBody->ToText()->Value();
623 fieldmetadatamap[paramString] = paramBodyStr;
626 param = param->NextSiblingElement();
653 const std::string &outname,
654 const std::vector<FieldDefinitionsSharedPtr> &fielddefs,
657 ASSERTL0(!outname.empty(),
"Empty path given to SetUpFieldMetaData()");
659 unsigned int nprocs =
m_comm->GetSpaceComm()->GetSize();
660 unsigned int rank =
m_comm->GetSpaceComm()->GetRank();
662 fs::path specPath(outname);
667 std::vector<size_t> elmtnums(nprocs, 0);
668 std::vector<unsigned int> idlist;
669 for (
size_t i = 0; i < fielddefs.size(); ++i)
671 elmtnums[rank] += fielddefs[i]->m_elementIDs.size();
672 idlist.insert(idlist.end(), fielddefs[i]->m_elementIDs.begin(),
673 fielddefs[i]->m_elementIDs.end());
681 std::vector<std::vector<unsigned int>> ElementIDs(nprocs);
684 ElementIDs[0] = idlist;
685 for (
size_t i = 1; i < nprocs; ++i)
689 std::vector<unsigned int> tmp(elmtnums[i]);
690 m_comm->GetSpaceComm()->Recv(i, tmp);
696 std::vector<std::string> filenames;
697 for (
unsigned int i = 0; i < nprocs; ++i)
701 filenames.push_back(pad.str());
705 std::string infofile =
713 if (elmtnums[rank] > 0)
715 m_comm->GetSpaceComm()->Send(0, idlist);
730 std::vector<FieldDefinitionsSharedPtr> &fielddefs,
bool expChild)
733 std::static_pointer_cast<XmlDataSource>(dataSource);
734 TiXmlElement *master =
737 master = xml->Get().FirstChildElement(
"NEKTAR");
738 ASSERTL0(master,
"Unable to find NEKTAR tag in file.");
739 std::string strLoop =
"NEKTAR";
740 TiXmlElement *loopXml = master;
742 TiXmlElement *expansionTypes;
745 expansionTypes = master->FirstChildElement(
"EXPANSIONS");
746 ASSERTL0(expansionTypes,
"Unable to find EXPANSIONS tag in file.");
747 loopXml = expansionTypes;
748 strLoop =
"EXPANSIONS";
754 TiXmlElement *element = loopXml->FirstChildElement(
"ELEMENTS");
759 std::string idString;
760 std::string shapeString;
761 std::string basisString;
762 std::string homoLengthsString;
763 std::string homoSIDsString;
764 std::string homoZIDsString;
765 std::string homoYIDsString;
766 std::string numModesString;
767 std::string numPointsString;
768 std::string fieldsString;
769 std::string pointsString;
770 bool pointDef =
false;
771 bool numPointDef =
false;
772 TiXmlAttribute *attr = element->FirstAttribute();
775 std::string attrName(attr->Name());
776 if (attrName ==
"FIELDS")
778 fieldsString.insert(0, attr->Value());
780 else if (attrName ==
"SHAPE")
782 shapeString.insert(0, attr->Value());
784 else if (attrName ==
"BASIS")
786 basisString.insert(0, attr->Value());
788 else if (attrName ==
"HOMOGENEOUSLENGTHS")
790 homoLengthsString.insert(0, attr->Value());
792 else if (attrName ==
"HOMOGENEOUSSIDS")
794 homoSIDsString.insert(0, attr->Value());
796 else if (attrName ==
"HOMOGENEOUSZIDS")
798 homoZIDsString.insert(0, attr->Value());
800 else if (attrName ==
"HOMOGENEOUSYIDS")
802 homoYIDsString.insert(0, attr->Value());
804 else if (attrName ==
"NUMMODESPERDIR")
806 numModesString.insert(0, attr->Value());
808 else if (attrName ==
"ID")
810 idString.insert(0, attr->Value());
812 else if (attrName ==
"POINTSTYPE")
814 pointsString.insert(0, attr->Value());
817 else if (attrName ==
"NUMPOINTSPERDIR")
819 numPointsString.insert(0, attr->Value());
822 else if (attrName ==
"COMPRESSED")
826 "Compressed formats do not "
827 "match. Expected: " +
829 " but got " + std::string(attr->Value()));
831 else if (attrName ==
"BITSIZE")
839 std::string errstr(
"Unknown attribute: ");
850 if (shapeString.find(
"Strips") != std::string::npos)
860 if ((
loc = shapeString.find_first_of(
"-")) != std::string::npos)
862 if (shapeString.find(
"Exp1D") != std::string::npos)
871 shapeString.erase(
loc, shapeString.length());
875 std::vector<unsigned int> elementIds;
879 ASSERTL0(valid,
"Unable to correctly parse the element ids.");
896 std::string(
"Unable to correctly parse the shape type: ")
901 std::vector<std::string> basisStrings;
902 std::vector<BasisType> basis;
904 ASSERTL0(valid,
"Unable to correctly parse the basis types.");
905 for (std::vector<std::string>::size_type i = 0;
906 i < basisStrings.size(); i++)
920 std::string(
"Unable to correctly parse the basis type: ")
921 .append(basisStrings[i])
926 std::vector<NekDouble> homoLengths;
931 ASSERTL0(valid,
"Unable to correctly parse the number of "
932 "homogeneous lengths.");
936 std::vector<unsigned int> homoSIDs;
941 "Unable to correctly parse homogeneous strips IDs.");
945 std::vector<unsigned int> homoZIDs;
946 std::vector<unsigned int> homoYIDs;
952 "Unable to correctly parse homogeneous planes IDs.");
958 ASSERTL0(valid,
"Unable to correctly parse homogeneous lines "
959 "IDs in z-direction.");
961 ASSERTL0(valid,
"Unable to correctly parse homogeneous lines "
962 "IDs in y-direction.");
966 std::vector<PointsType> points;
970 std::vector<std::string> pointsStrings;
972 ASSERTL0(valid,
"Unable to correctly parse the points types.");
973 for (std::vector<std::string>::size_type i = 0;
974 i < pointsStrings.size(); i++)
989 "Unable to correctly parse the points type: ")
990 .append(pointsStrings[i])
996 std::vector<unsigned int> numModes;
997 bool UniOrder =
false;
999 if (strstr(numModesString.c_str(),
"UNIORDER:"))
1006 ASSERTL0(valid,
"Unable to correctly parse the number of modes.");
1009 std::vector<unsigned int> numPoints;
1014 "Unable to correctly parse the number of points.");
1018 std::vector<std::string> Fields;
1020 ASSERTL0(valid,
"Unable to correctly parse the number of fields.");
1024 shape, elementIds, basis, UniOrder, numModes, Fields,
1025 numHomoDir, homoLengths, strips, homoSIDs, homoZIDs,
1026 homoYIDs, points, pointDef, numPoints, numPointDef);
1028 fielddefs.push_back(fielddef);
1030 element = element->NextSiblingElement(
"ELEMENTS");
1032 loopXml = loopXml->NextSiblingElement(strLoop);
1045 const std::vector<FieldDefinitionsSharedPtr> &fielddefs,
1046 std::vector<std::vector<NekDouble>> &fielddata)
1050 std::static_pointer_cast<XmlDataSource>(dataSource);
1052 TiXmlElement *master =
1055 master = xml->Get().FirstChildElement(
"NEKTAR");
1056 ASSERTL0(master,
"Unable to find NEKTAR tag in file.");
1061 TiXmlElement *element = master->FirstChildElement(
"ELEMENTS");
1062 ASSERTL0(element,
"Unable to find ELEMENTS tag within nektar tag.");
1066 TiXmlNode *elementChild = element->FirstChild();
1068 "Unable to extract the data from the element tag.");
1069 std::string elementStr;
1070 while (elementChild)
1072 if (elementChild->Type() == TiXmlNode::TINYXML_TEXT)
1074 elementStr += elementChild->ToText()->ValueStr();
1076 elementChild = elementChild->NextSibling();
1079 std::vector<NekDouble> elementFieldData;
1082 const char *CompressStr = element->Attribute(
"COMPRESSED");
1087 "Compressed formats do not match. "
1090 std::string(CompressStr));
1094 elementStr, elementFieldData),
1095 "Failed to decompress field data.");
1096 fielddata.push_back(elementFieldData);
1100 fielddata[cntdumps].size() ==
1101 datasize * fielddefs[cntdumps]->m_fields.size(),
1102 "Input data is not the same length as header infoarmation");
1106 element = element->NextSiblingElement(
"ELEMENTS");
1108 master = master->NextSiblingElement(
"NEKTAR");
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define WARNINGL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Class for operating on Nektar++ input/output files.
int CheckFieldDefinition(const FieldDefinitionsSharedPtr &fielddefs)
Check field definitions for correctness and return storage size.
DataSourceSharedPtr ImportFieldMetaData(const std::string &filename, FieldMetaDataMap &fieldmetadatamap)
Import the metadata from a field file.
std::string SetUpOutput(const std::string outname, bool perRank, bool backup=false)
Set up the filesystem ready for output.
LibUtilities::CommSharedPtr m_comm
Communicator to use when writing parallel format.
std::string GetFileEnding() const
Helper function that determines default file extension.
static void AddInfoTag(TagWriterSharedPtr root, const FieldMetaDataMap &fieldmetadatamap)
Add provenance information to the field metadata map.
void ImportMultiFldFileIDs(const std::string &inFile, std::vector< std::string > &fileNames, std::vector< std::vector< unsigned int > > &elementList, FieldMetaDataMap &fieldmetadatamap)
Read file containing element ID to partition mapping.
void ImportFieldData(DataSourceSharedPtr dataSource, const std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata)
Import field data from a target file.
const std::string & v_GetClassName() const override
Returns the class name.
void ImportFieldDefs(DataSourceSharedPtr dataSource, std::vector< FieldDefinitionsSharedPtr > &fielddefs, bool expChild)
Import field definitions from the target file.
void WriteMultiFldFileIDs(const std::string &outfile, const std::vector< std::string > fileNames, std::vector< std::vector< unsigned int > > &elementList, const FieldMetaDataMap &fieldinfomap=NullFieldMetaDataMap)
Write out a file containing element ID to partition mapping.
static FieldIOSharedPtr create(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
Creates an instance of this class.
DataSourceSharedPtr v_ImportFieldMetaData(const std::string &filename, FieldMetaDataMap &fieldmetadatamap) override
Import field metadata from filename and return the data source which wraps filename.
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) override
Import an XML format file.
void v_Write(const std::string &outFile, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, const FieldMetaDataMap &fieldinfomap=NullFieldMetaDataMap, const bool backup=false) override
Write an XML file to outFile given the field definitions fielddefs, field data fielddata and metadata...
FieldIOXml(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
Default constructor.
void SetUpFieldMetaData(const std::string &outname, const std::vector< FieldDefinitionsSharedPtr > &fielddefs, const FieldMetaDataMap &fieldmetadatamap)
Set up field meta data map.
static std::string className
Name of class.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
static DataSourceSharedPtr create(const std::string &fn)
Create a new XML data source based on the filename.
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static std::string GenerateSeqString(const std::vector< T > &v)
Generate a compressed comma-separated string representation of a vector of unsigned integers.
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector.
std::string GetBitSizeStr(void)
int ZlibDecodeFromBase64Str(std::string &in64, std::vector< T > &out)
std::string GetCompressString(void)
int ZlibEncodeToBase64Str(std::vector< T > &in, std::string &out64)
const char *const ShapeTypeMap[SIZE_ShapeType]
const char *const BasisTypeMap[]
std::shared_ptr< DataSource > DataSourceSharedPtr
std::map< std::string, std::string > FieldMetaDataMap
const std::string kPointsTypeStr[]
static std::string PortablePath(const fs::path &path)
create portable path on different platforms for std::filesystem path.
std::shared_ptr< XmlDataSource > XmlDataSourceSharedPtr
static std::vector< std::vector< NekDouble > > NullVectorNekDoubleVector
std::shared_ptr< FieldDefinitions > FieldDefinitionsSharedPtr
FieldIOFactory & GetFieldIOFactory()
Returns the FieldIO factory.
std::shared_ptr< XmlTagWriter > XmlTagWriterSharedPtr
@ SIZE_PointsType
Length of enum list.
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
@ SIZE_BasisType
Length of enum list.
static Array< OneD, int > NullInt1DArray