Nektar++
Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Member Functions | List of all members
Nektar::LibUtilities::FieldIOXml Class Reference

#include <FieldIOXml.h>

Inheritance diagram for Nektar::LibUtilities::FieldIOXml:
[legend]

Public Member Functions

 FieldIOXml (LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
 Default constructor. More...
 
virtual ~FieldIOXml ()
 
void ImportFieldDefs (DataSourceSharedPtr dataSource, std::vector< FieldDefinitionsSharedPtr > &fielddefs, bool expChild)
 Import field definitions from the target file. More...
 
void ImportFieldData (DataSourceSharedPtr dataSource, const std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble >> &fielddata)
 Import field data from a target file. More...
 
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. More...
 
void SetUpFieldMetaData (const std::string &outname, const std::vector< FieldDefinitionsSharedPtr > &fielddefs, const FieldMetaDataMap &fieldmetadatamap)
 Set up field meta data map. More...
 
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. More...
 
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)
 Import an XML format file. More...
 
virtual const std::string & GetClassName () const
 Returns the class name. More...
 
- Public Member Functions inherited from Nektar::LibUtilities::FieldIO
 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...
 

Static Public Member Functions

static FieldIOSharedPtr create (LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
 Creates an instance of this class. More...
 
- Static Public Member Functions inherited from Nektar::LibUtilities::FieldIO
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...
 

Static Public Attributes

static std::string className
 Name of class. More...
 

Private Member Functions

virtual 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)
 Write an XML file to outFile given the field definitions fielddefs, field data fielddata and metadata fieldmetadatamap. More...
 
virtual DataSourceSharedPtr v_ImportFieldMetaData (const std::string &filename, FieldMetaDataMap &fieldmetadatamap)
 Import field metadata from filename and return the data source which wraps filename. More...
 

Additional Inherited Members

- Protected Member Functions inherited from Nektar::LibUtilities::FieldIO
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...
 
- Protected Attributes inherited from Nektar::LibUtilities::FieldIO
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

Definition at line 205 of file FieldIOXml.h.

Constructor & Destructor Documentation

◆ FieldIOXml()

Nektar::LibUtilities::FieldIOXml::FieldIOXml ( LibUtilities::CommSharedPtr  pComm,
bool  sharedFilesystem 
)

Default constructor.

Parameters
pCommCommunicator.
sharedFilesystemTrue if the underlying filesystem is shared by the compute nodes.

Definition at line 62 of file FieldIOXml.cpp.

63  : FieldIO(pComm, sharedFilesystem)
64 {
65 }
FieldIO(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
Constructor for FieldIO base class.
Definition: FieldIO.cpp:324

◆ ~FieldIOXml()

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

Definition at line 222 of file FieldIOXml.h.

223  {
224  }

Member Function Documentation

◆ create()

static FieldIOSharedPtr Nektar::LibUtilities::FieldIOXml::create ( LibUtilities::CommSharedPtr  pComm,
bool  sharedFilesystem 
)
inlinestatic

Creates an instance of this class.

Definition at line 209 of file FieldIOXml.h.

211  {
213  sharedFilesystem);
214  }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr().

◆ GetClassName()

virtual const std::string& Nektar::LibUtilities::FieldIOXml::GetClassName ( ) const
inlinevirtual

Returns the class name.

Implements Nektar::LibUtilities::FieldIO.

Definition at line 259 of file FieldIOXml.h.

260  {
261  return className;
262  }
static std::string className
Name of class.
Definition: FieldIOXml.h:217

References className.

◆ ImportFieldData()

void Nektar::LibUtilities::FieldIOXml::ImportFieldData ( DataSourceSharedPtr  dataSource,
const std::vector< FieldDefinitionsSharedPtr > &  fielddefs,
std::vector< std::vector< NekDouble >> &  fielddata 
)

Import field data from a target file.

Parameters
dataSourceTarget XML file
fielddefsField definitions for file
fielddataOn return, contains field data for each field.

Definition at line 1080 of file FieldIOXml.cpp.

1084 {
1085  int cntdumps = 0;
1087  std::static_pointer_cast<XmlDataSource>(dataSource);
1088 
1089  TiXmlElement *master =
1090  NULL; // Master tag within which all data is contained.
1091 
1092  master = xml->Get().FirstChildElement("NEKTAR");
1093  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
1094 
1095  // Loop through all nektar tags, finding all of the element tags.
1096  while (master)
1097  {
1098  TiXmlElement *element = master->FirstChildElement("ELEMENTS");
1099  ASSERTL0(element, "Unable to find ELEMENTS tag within nektar tag.");
1100  while (element)
1101  {
1102  // Extract the body, which the "data".
1103  TiXmlNode *elementChild = element->FirstChild();
1104  ASSERTL0(elementChild,
1105  "Unable to extract the data from the element tag.");
1106  std::string elementStr;
1107  while (elementChild)
1108  {
1109  if (elementChild->Type() == TiXmlNode::TINYXML_TEXT)
1110  {
1111  elementStr += elementChild->ToText()->ValueStr();
1112  }
1113  elementChild = elementChild->NextSibling();
1114  }
1115 
1116  std::vector<NekDouble> elementFieldData;
1117 
1118  // Convert from base64 to binary.
1119  const char *CompressStr = element->Attribute("COMPRESSED");
1120  if (CompressStr)
1121  {
1122  WARNINGL0(boost::iequals(CompressStr,
1124  "Compressed formats do not match. "
1125  "Expected: " +
1126  CompressData::GetCompressString() + " but got " +
1127  std::string(CompressStr));
1128  }
1129 
1131  elementStr, elementFieldData),
1132  "Failed to decompress field data.");
1133  fielddata.push_back(elementFieldData);
1134 
1135  int datasize = CheckFieldDefinition(fielddefs[cntdumps]);
1136  ASSERTL0(
1137  fielddata[cntdumps].size() ==
1138  datasize * fielddefs[cntdumps]->m_fields.size(),
1139  "Input data is not the same length as header infoarmation");
1140 
1141  cntdumps++;
1142 
1143  element = element->NextSiblingElement("ELEMENTS");
1144  }
1145  master = master->NextSiblingElement("NEKTAR");
1146  }
1147 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define WARNINGL0(condition, msg)
Definition: ErrorUtil.hpp:222
int CheckFieldDefinition(const FieldDefinitionsSharedPtr &fielddefs)
Check field definitions for correctness and return storage size.
Definition: FieldIO.cpp:585
int ZlibDecodeFromBase64Str(std::string &in64, std::vector< T > &out)
Definition: CompressData.h:220
std::shared_ptr< XmlDataSource > XmlDataSourceSharedPtr
Definition: FieldIOXml.h:111

References ASSERTL0, Nektar::LibUtilities::FieldIO::CheckFieldDefinition(), Nektar::LibUtilities::CompressData::GetCompressString(), WARNINGL0, and Nektar::LibUtilities::CompressData::ZlibDecodeFromBase64Str().

Referenced by v_Import().

◆ ImportFieldDefs()

void Nektar::LibUtilities::FieldIOXml::ImportFieldDefs ( DataSourceSharedPtr  dataSource,
std::vector< FieldDefinitionsSharedPtr > &  fielddefs,
bool  expChild 
)

Import field definitions from the target file.

Parameters
dataSourceTarget XML file
fielddefsOutput vector that will contain read field definitions.
expChildDetermines if the field definitions are defined by <EXPANSIONS> or in <NEKTAR>.

Definition at line 765 of file FieldIOXml.cpp.

768 {
770  std::static_pointer_cast<XmlDataSource>(dataSource);
771  TiXmlElement *master =
772  NULL; // Master tag within which all data is contained.
773 
774  master = xml->Get().FirstChildElement("NEKTAR");
775  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
776  std::string strLoop = "NEKTAR";
777  TiXmlElement *loopXml = master;
778 
779  TiXmlElement *expansionTypes;
780  if (expChild)
781  {
782  expansionTypes = master->FirstChildElement("EXPANSIONS");
783  ASSERTL0(expansionTypes, "Unable to find EXPANSIONS tag in file.");
784  loopXml = expansionTypes;
785  strLoop = "EXPANSIONS";
786  }
787 
788  // Loop through all nektar tags, finding all of the element tags.
789  while (loopXml)
790  {
791  TiXmlElement *element = loopXml->FirstChildElement("ELEMENTS");
792 
793  while (element)
794  {
795  // Extract the attributes.
796  std::string idString;
797  std::string shapeString;
798  std::string basisString;
799  std::string homoLengthsString;
800  std::string homoSIDsString;
801  std::string homoZIDsString;
802  std::string homoYIDsString;
803  std::string numModesString;
804  std::string numPointsString;
805  std::string fieldsString;
806  std::string pointsString;
807  bool pointDef = false;
808  bool numPointDef = false;
809  TiXmlAttribute *attr = element->FirstAttribute();
810  while (attr)
811  {
812  std::string attrName(attr->Name());
813  if (attrName == "FIELDS")
814  {
815  fieldsString.insert(0, attr->Value());
816  }
817  else if (attrName == "SHAPE")
818  {
819  shapeString.insert(0, attr->Value());
820  }
821  else if (attrName == "BASIS")
822  {
823  basisString.insert(0, attr->Value());
824  }
825  else if (attrName == "HOMOGENEOUSLENGTHS")
826  {
827  homoLengthsString.insert(0, attr->Value());
828  }
829  else if (attrName == "HOMOGENEOUSSIDS")
830  {
831  homoSIDsString.insert(0, attr->Value());
832  }
833  else if (attrName == "HOMOGENEOUSZIDS")
834  {
835  homoZIDsString.insert(0, attr->Value());
836  }
837  else if (attrName == "HOMOGENEOUSYIDS")
838  {
839  homoYIDsString.insert(0, attr->Value());
840  }
841  else if (attrName == "NUMMODESPERDIR")
842  {
843  numModesString.insert(0, attr->Value());
844  }
845  else if (attrName == "ID")
846  {
847  idString.insert(0, attr->Value());
848  }
849  else if (attrName == "POINTSTYPE")
850  {
851  pointsString.insert(0, attr->Value());
852  pointDef = true;
853  }
854  else if (attrName == "NUMPOINTSPERDIR")
855  {
856  numPointsString.insert(0, attr->Value());
857  numPointDef = true;
858  }
859  else if (attrName == "COMPRESSED")
860  {
861  WARNINGL0(boost::iequals(attr->Value(),
863  "Compressed formats do not "
864  "match. Expected: " +
866  " but got " + std::string(attr->Value()));
867  }
868  else if (attrName == "BITSIZE")
869  {
870  // This information is for future compatibility
871  // issues, for example in case we end up using a 128
872  // bit machine. Currently just do nothing.
873  }
874  else
875  {
876  std::string errstr("Unknown attribute: ");
877  errstr += attrName;
878  NEKERROR(ErrorUtil::ewarning, errstr.c_str());
879  }
880 
881  // Get the next attribute.
882  attr = attr->Next();
883  }
884 
885  // Check to see if using strips formulation
886  bool strips = false;
887  if (shapeString.find("Strips") != std::string::npos)
888  {
889  strips = true;
890  }
891 
892  // Check to see if homogeneous expansion and if so
893  // strip down the shapeString definition
894  int numHomoDir = 0;
895  size_t loc;
896  //---> This finds the first location of 'n'!
897  if ((loc = shapeString.find_first_of("-")) != std::string::npos)
898  {
899  if (shapeString.find("Exp1D") != std::string::npos)
900  {
901  numHomoDir = 1;
902  }
903  else // HomogeneousExp1D
904  {
905  numHomoDir = 2;
906  }
907 
908  shapeString.erase(loc, shapeString.length());
909  }
910 
911  // Reconstruct the fielddefs.
912  std::vector<unsigned int> elementIds;
913  {
914  bool valid =
915  ParseUtils::GenerateSeqVector(idString, elementIds);
916  ASSERTL0(valid, "Unable to correctly parse the element ids.");
917  }
918 
919  // Get the geometrical shape
920  ShapeType shape = (ShapeType)0;
921  bool valid = false;
922  for (unsigned int j = 0; j < SIZE_ShapeType; j++)
923  {
924  if (ShapeTypeMap[j] == shapeString)
925  {
926  shape = (ShapeType)j;
927  valid = true;
928  break;
929  }
930  }
931 
932  ASSERTL0(valid,
933  std::string("Unable to correctly parse the shape type: ")
934  .append(shapeString)
935  .c_str());
936 
937  // Get the basis
938  std::vector<std::string> basisStrings;
939  std::vector<BasisType> basis;
940  valid = ParseUtils::GenerateVector(basisString, basisStrings);
941  ASSERTL0(valid, "Unable to correctly parse the basis types.");
942  for (std::vector<std::string>::size_type i = 0;
943  i < basisStrings.size(); i++)
944  {
945  valid = false;
946  for (unsigned int j = 0; j < SIZE_BasisType; j++)
947  {
948  if (BasisTypeMap[j] == basisStrings[i])
949  {
950  basis.push_back((BasisType)j);
951  valid = true;
952  break;
953  }
954  }
955  ASSERTL0(
956  valid,
957  std::string("Unable to correctly parse the basis type: ")
958  .append(basisStrings[i])
959  .c_str());
960  }
961 
962  // Get homoLengths
963  std::vector<NekDouble> homoLengths;
964  if (numHomoDir)
965  {
966  valid =
967  ParseUtils::GenerateVector(homoLengthsString, homoLengths);
968  ASSERTL0(valid, "Unable to correctly parse the number of "
969  "homogeneous lengths.");
970  }
971 
972  // Get Homogeneous strips IDs
973  std::vector<unsigned int> homoSIDs;
974  if (strips)
975  {
976  valid = ParseUtils::GenerateVector(homoSIDsString, homoSIDs);
977  ASSERTL0(valid,
978  "Unable to correctly parse homogeneous strips IDs.");
979  }
980 
981  // Get Homogeneous points IDs
982  std::vector<unsigned int> homoZIDs;
983  std::vector<unsigned int> homoYIDs;
984 
985  if (numHomoDir == 1)
986  {
987  valid = ParseUtils::GenerateSeqVector(homoZIDsString, homoZIDs);
988  ASSERTL0(valid,
989  "Unable to correctly parse homogeneous planes IDs.");
990  }
991 
992  if (numHomoDir == 2)
993  {
994  valid = ParseUtils::GenerateSeqVector(homoZIDsString, homoZIDs);
995  ASSERTL0(valid, "Unable to correctly parse homogeneous lines "
996  "IDs in z-direction.");
997  valid = ParseUtils::GenerateSeqVector(homoYIDsString, homoYIDs);
998  ASSERTL0(valid, "Unable to correctly parse homogeneous lines "
999  "IDs in y-direction.");
1000  }
1001 
1002  // Get points type
1003  std::vector<PointsType> points;
1004 
1005  if (pointDef)
1006  {
1007  std::vector<std::string> pointsStrings;
1008  valid = ParseUtils::GenerateVector(pointsString, pointsStrings);
1009  ASSERTL0(valid, "Unable to correctly parse the points types.");
1010  for (std::vector<std::string>::size_type i = 0;
1011  i < pointsStrings.size(); i++)
1012  {
1013  valid = false;
1014  for (unsigned int j = 0; j < SIZE_PointsType; j++)
1015  {
1016  if (kPointsTypeStr[j] == pointsStrings[i])
1017  {
1018  points.push_back((PointsType)j);
1019  valid = true;
1020  break;
1021  }
1022  }
1023 
1024  ASSERTL0(valid,
1025  std::string(
1026  "Unable to correctly parse the points type: ")
1027  .append(pointsStrings[i])
1028  .c_str());
1029  }
1030  }
1031 
1032  // Get numModes
1033  std::vector<unsigned int> numModes;
1034  bool UniOrder = false;
1035 
1036  if (strstr(numModesString.c_str(), "UNIORDER:"))
1037  {
1038  UniOrder = true;
1039  }
1040 
1041  valid =
1042  ParseUtils::GenerateVector(numModesString.substr(9), numModes);
1043  ASSERTL0(valid, "Unable to correctly parse the number of modes.");
1044 
1045  // Get numPoints
1046  std::vector<unsigned int> numPoints;
1047  if (numPointDef)
1048  {
1049  valid = ParseUtils::GenerateVector(numPointsString, numPoints);
1050  ASSERTL0(valid,
1051  "Unable to correctly parse the number of points.");
1052  }
1053 
1054  // Get fields names
1055  std::vector<std::string> Fields;
1056  valid = ParseUtils::GenerateVector(fieldsString, Fields);
1057  ASSERTL0(valid, "Unable to correctly parse the number of fields.");
1058 
1059  FieldDefinitionsSharedPtr fielddef =
1061  shape, elementIds, basis, UniOrder, numModes, Fields,
1062  numHomoDir, homoLengths, strips, homoSIDs, homoZIDs,
1063  homoYIDs, points, pointDef, numPoints, numPointDef);
1064 
1065  fielddefs.push_back(fielddef);
1066 
1067  element = element->NextSiblingElement("ELEMENTS");
1068  }
1069  loopXml = loopXml->NextSiblingElement(strLoop);
1070  }
1071 }
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
static bool GenerateVector(const std::string &str, std::vector< T > &out)
Takes a comma-separated string and converts it to entries in a vector.
Definition: ParseUtils.cpp:129
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.
Definition: ParseUtils.cpp:103
const char *const ShapeTypeMap[SIZE_ShapeType]
Definition: ShapeType.hpp:77
const char *const BasisTypeMap[]
Definition: Foundations.hpp:46
const std::string kPointsTypeStr[]
Definition: Foundations.hpp:54
std::shared_ptr< FieldDefinitions > FieldDefinitionsSharedPtr
Definition: FieldIO.h:177
@ SIZE_PointsType
Length of enum list.
Definition: PointsType.h:97
@ SIZE_BasisType
Length of enum list.
Definition: BasisType.h:72

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, Nektar::LibUtilities::BasisTypeMap, Nektar::ErrorUtil::ewarning, Nektar::ParseUtils::GenerateSeqVector(), Nektar::ParseUtils::GenerateVector(), Nektar::LibUtilities::CompressData::GetCompressString(), Nektar::LibUtilities::kPointsTypeStr, CG_Iterations::loc, NEKERROR, Nektar::LibUtilities::ShapeTypeMap, Nektar::LibUtilities::SIZE_BasisType, Nektar::LibUtilities::SIZE_PointsType, Nektar::LibUtilities::SIZE_ShapeType, and WARNINGL0.

Referenced by v_Import().

◆ ImportMultiFldFileIDs()

void Nektar::LibUtilities::FieldIOXml::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.

This function reads an XML file (usually called Info.xml) that contains the element IDs that are contained within each partition, as well as the field metadata map.

Parameters
inFileInput multi-field file name.
fileNamesList of partition filenames.
elementListVector of element IDs that lie on each process.
fieldmetadatamapField metadata map that is read from inFile.

Definition at line 423 of file FieldIOXml.cpp.

427 {
428  boost::ignore_unused(fieldmetadatamap);
429 
430  TiXmlDocument doc(inFile);
431  bool loadOkay = doc.LoadFile();
432 
433  std::stringstream errstr;
434  errstr << "Unable to load file: " << inFile << std::endl;
435  errstr << "Reason: " << doc.ErrorDesc() << std::endl;
436  errstr << "Position: Line " << doc.ErrorRow() << ", Column "
437  << doc.ErrorCol() << std::endl;
438  ASSERTL0(loadOkay, errstr.str());
439 
440  // Handle on XML document
441  TiXmlHandle docHandle(&doc);
442 
443  // Retrieve main NEKTAR tag - XML specification states one
444  // top-level element tag per file.
445  TiXmlElement *master = doc.FirstChildElement("NEKTAR");
446  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
447 
448  // Partition element tag name
449  std::string strPartition = "Partition";
450 
451  // First attempt to get the first Partition element
452  TiXmlElement *fldfileIDs = master->FirstChildElement(strPartition.c_str());
453  if (!fldfileIDs)
454  {
455  // If this files try previous name
456  strPartition = "MultipleFldFiles";
457  fldfileIDs = master->FirstChildElement("MultipleFldFiles");
458  }
459  ASSERTL0(fldfileIDs, "Unable to find 'Partition' or 'MultipleFldFiles' tag "
460  "within nektar tag.");
461 
462  while (fldfileIDs)
463  {
464  // Read file name of partition file
465  const char *attr = fldfileIDs->Attribute("FileName");
466  ASSERTL0(attr, "'FileName' not provided as an attribute of '" +
467  strPartition + "' tag.");
468  fileNames.push_back(std::string(attr));
469 
470  const char *elementIDs = fldfileIDs->GetText();
471  ASSERTL0(elementIDs, "Element IDs not specified.");
472 
473  std::string elementIDsStr(elementIDs);
474 
475  std::vector<unsigned int> idvec;
476  ParseUtils::GenerateSeqVector(elementIDsStr, idvec);
477 
478  elementList.push_back(idvec);
479 
480  fldfileIDs = fldfileIDs->NextSiblingElement(strPartition.c_str());
481  }
482 }

References ASSERTL0, and Nektar::ParseUtils::GenerateSeqVector().

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

◆ SetUpFieldMetaData()

void Nektar::LibUtilities::FieldIOXml::SetUpFieldMetaData ( const std::string &  outname,
const std::vector< FieldDefinitionsSharedPtr > &  fielddefs,
const FieldMetaDataMap fieldmetadatamap 
)

Set up field meta data map.

This routine sets up the necessary information for the field metadata map before calling FieldIOXml::WriteMultiFldFileIDs, which involves each process sending its element ID list to the root processor. The root processor writes the Info.xml file.

Parameters
outnameOutput directory.
fielddefsField definitions, needed to grab element IDs.
fieldmetadatamapField metadata map that is also written to the Info.xml file.

Definition at line 689 of file FieldIOXml.cpp.

693 {
694  ASSERTL0(!outname.empty(), "Empty path given to SetUpFieldMetaData()");
695 
696  unsigned int nprocs = m_comm->GetSize();
697  unsigned int rank = m_comm->GetRank();
698 
699  fs::path specPath(outname);
700 
701  // Compute number of elements on this process and share with other
702  // processes. Also construct list of elements on this process from
703  // available vector of field definitions.
704  std::vector<size_t> elmtnums(nprocs, 0);
705  std::vector<unsigned int> idlist;
706  for (size_t i = 0; i < fielddefs.size(); ++i)
707  {
708  elmtnums[rank] += fielddefs[i]->m_elementIDs.size();
709  idlist.insert(idlist.end(), fielddefs[i]->m_elementIDs.begin(),
710  fielddefs[i]->m_elementIDs.end());
711  }
712  m_comm->AllReduce(elmtnums, LibUtilities::ReduceMax);
713 
714  // Collate per-process element lists on root process to generate
715  // the info file.
716  if (rank == 0)
717  {
718  std::vector<std::vector<unsigned int>> ElementIDs(nprocs);
719 
720  // Populate the list of element ID lists from all processes
721  ElementIDs[0] = idlist;
722  for (size_t i = 1; i < nprocs; ++i)
723  {
724  if (elmtnums[i] > 0)
725  {
726  std::vector<unsigned int> tmp(elmtnums[i]);
727  m_comm->Recv(i, tmp);
728  ElementIDs[i] = tmp;
729  }
730  }
731 
732  // Set up output names
733  std::vector<std::string> filenames;
734  for (unsigned int i = 0; i < nprocs; ++i)
735  {
736  boost::format pad("P%1$07d.%2$s");
737  pad % i % GetFileEnding();
738  filenames.push_back(pad.str());
739  }
740 
741  // Write the Info.xml file
742  std::string infofile =
743  LibUtilities::PortablePath(specPath / fs::path("Info.xml"));
744 
745  WriteMultiFldFileIDs(infofile, filenames, ElementIDs, fieldmetadatamap);
746  }
747  else
748  {
749  // Send this process's ID list to the root process
750  if (elmtnums[rank] > 0)
751  {
752  m_comm->Send(0, idlist);
753  }
754  }
755 }
LibUtilities::CommSharedPtr m_comm
Communicator to use when writing parallel format.
Definition: FieldIO.h:261
virtual std::string GetFileEnding() const
Helper function that determines default file extension.
Definition: FieldIO.h:271
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.
Definition: FieldIOXml.cpp:376
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:41

References ASSERTL0, CellMLToNektar.pycml::format, Nektar::LibUtilities::FieldIO::GetFileEnding(), Nektar::LibUtilities::FieldIO::m_comm, Nektar::LibUtilities::PortablePath(), Nektar::LibUtilities::ReduceMax, and WriteMultiFldFileIDs().

Referenced by v_Write().

◆ v_Import()

void Nektar::LibUtilities::FieldIOXml::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 
)
virtual

Import an XML format file.

Parameters
finfilenameInput filename
fielddefsField definitions of resulting field
fielddataField data of resulting field
fieldinfomapField metadata of resulting field
ElementIDsIf specified, contains the list of element IDs on this rank. The resulting field definitions will only contain data for the element IDs specified in this array.

Implements Nektar::LibUtilities::FieldIO.

Definition at line 496 of file FieldIOXml.cpp.

501 {
502  std::string infile = infilename;
503 
504  fs::path pinfilename(infilename);
505 
506  // Check to see whether infile is a directory and therefore read in parallel
507  // or serial.
508  if (fs::is_directory(pinfilename))
509  {
510  fs::path infofile("Info.xml");
511  fs::path fullpath = pinfilename / infofile;
512  infile = PortablePath(fullpath);
513 
514  std::vector<std::string> filenames;
515  std::vector<std::vector<unsigned int>> elementIDs_OnPartitions;
516 
517  ImportMultiFldFileIDs(infile, filenames, elementIDs_OnPartitions,
518  fieldinfomap);
519 
520  // Load metadata
521  ImportFieldMetaData(infile, fieldinfomap);
522 
523  if (ElementIDs == NullInt1DArray) // load all elements
524  {
525  for (int i = 0; i < filenames.size(); ++i)
526  {
527  fs::path pfilename(filenames[i]);
528  fullpath = pinfilename / pfilename;
529  std::string fname = PortablePath(fullpath);
530  DataSourceSharedPtr dataSource = XmlDataSource::create(fname);
531  ImportFieldDefs(dataSource, fielddefs, false);
532  if (fielddata != NullVectorNekDoubleVector)
533  {
534  ImportFieldData(dataSource, fielddefs, fielddata);
535  }
536  }
537  }
538  else // only load relevant elements from partitions
539  {
540  int i, j;
541  std::map<int, std::vector<int>> FileIDs;
542  std::set<int> LoadFile;
543 
544  for (i = 0; i < elementIDs_OnPartitions.size(); ++i)
545  {
546  for (j = 0; j < elementIDs_OnPartitions[i].size(); ++j)
547  {
548  FileIDs[elementIDs_OnPartitions[i][j]].push_back(i);
549  }
550  }
551 
552  for (i = 0; i < ElementIDs.size(); ++i)
553  {
554  auto it = FileIDs.find(ElementIDs[i]);
555  if (it != FileIDs.end())
556  {
557  for (j = 0; j < it->second.size(); ++j)
558  {
559  LoadFile.insert(it->second[j]);
560  }
561  }
562  }
563 
564  for (auto &iter : LoadFile)
565  {
566  fs::path pfilename(filenames[iter]);
567  fullpath = pinfilename / pfilename;
568  std::string fname = PortablePath(fullpath);
569  DataSourceSharedPtr dataSource = XmlDataSource::create(fname);
570  ImportFieldDefs(dataSource, fielddefs, false);
571  if (fielddata != NullVectorNekDoubleVector)
572  {
573  ImportFieldData(dataSource, fielddefs, fielddata);
574  }
575  }
576  }
577  }
578  else
579  {
580  // serial format case
581  DataSourceSharedPtr doc = ImportFieldMetaData(infilename, fieldinfomap);
582  ImportFieldDefs(doc, fielddefs, false);
583  if (fielddata != NullVectorNekDoubleVector)
584  {
585  ImportFieldData(doc, fielddefs, fielddata);
586  }
587  }
588 }
DataSourceSharedPtr ImportFieldMetaData(const std::string &filename, FieldMetaDataMap &fieldmetadatamap)
Import the metadata from a field file.
Definition: FieldIO.h:350
void ImportFieldDefs(DataSourceSharedPtr dataSource, std::vector< FieldDefinitionsSharedPtr > &fielddefs, bool expChild)
Import field definitions from the target file.
Definition: FieldIOXml.cpp:765
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.
Definition: FieldIOXml.cpp:423
void ImportFieldData(DataSourceSharedPtr dataSource, const std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble >> &fielddata)
Import field data from a target file.
static DataSourceSharedPtr create(const std::string &fn)
Create a new XML data source based on the filename.
Definition: FieldIOXml.h:94
std::shared_ptr< DataSource > DataSourceSharedPtr
Definition: FieldIO.h:81
static std::vector< std::vector< NekDouble > > NullVectorNekDoubleVector
static Array< OneD, int > NullInt1DArray

References Nektar::LibUtilities::XmlDataSource::create(), ImportFieldData(), ImportFieldDefs(), Nektar::LibUtilities::FieldIO::ImportFieldMetaData(), ImportMultiFldFileIDs(), Nektar::NullInt1DArray, Nektar::LibUtilities::NullVectorNekDoubleVector, and Nektar::LibUtilities::PortablePath().

◆ v_ImportFieldMetaData()

DataSourceSharedPtr Nektar::LibUtilities::FieldIOXml::v_ImportFieldMetaData ( const std::string &  filename,
FieldMetaDataMap fieldmetadatamap 
)
privatevirtual

Import field metadata from filename and return the data source which wraps filename.

Parameters
filenameInput filename.
fieldmetadatamapResulting field metadata from dataSource.

Implements Nektar::LibUtilities::FieldIO.

Definition at line 597 of file FieldIOXml.cpp.

599 {
601  XmlDataSourceSharedPtr xml = std::static_pointer_cast<XmlDataSource>(doc);
602  TiXmlElement *metadata = 0;
603  TiXmlElement *master = 0; // Master tag within which all data is
604  // contained.
605 
606  master = xml->Get().FirstChildElement("NEKTAR");
607  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
608  std::string strLoop = "NEKTAR";
609 
610  // Retain original metadata structure for backwards compatibility
611  // TODO: Remove old metadata format
612  metadata = master->FirstChildElement("FIELDMETADATA");
613  if (metadata)
614  {
615  TiXmlElement *param = metadata->FirstChildElement("P");
616 
617  while (param)
618  {
619  TiXmlAttribute *paramAttr = param->FirstAttribute();
620  std::string attrName(paramAttr->Name());
621  std::string paramString;
622 
623  if (attrName == "PARAM")
624  {
625  paramString.insert(0, paramAttr->Value());
626  }
627  else
628  {
630  "PARAM not provided as an attribute in "
631  "FIELDMETADATA section");
632  }
633 
634  // Now read body of param
635  std::string paramBodyStr;
636 
637  TiXmlNode *paramBody = param->FirstChild();
638 
639  paramBodyStr += paramBody->ToText()->Value();
640 
641  fieldmetadatamap[paramString] = paramBodyStr;
642  param = param->NextSiblingElement("P");
643  }
644  }
645 
646  // New metadata format
647  metadata = master->FirstChildElement("Metadata");
648  if (metadata)
649  {
650  TiXmlElement *param = metadata->FirstChildElement();
651 
652  while (param)
653  {
654  std::string paramString = param->Value();
655  if (paramString != "Provenance")
656  {
657  // Now read body of param
658  if (param->NoChildren())
659  {
660  fieldmetadatamap[paramString] = "";
661  }
662  else
663  {
664  TiXmlNode *paramBody = param->FirstChild();
665  std::string paramBodyStr = paramBody->ToText()->Value();
666  fieldmetadatamap[paramString] = paramBodyStr;
667  }
668  }
669  param = param->NextSiblingElement();
670  }
671  }
672 
673  return doc;
674 }

References ASSERTL0, Nektar::LibUtilities::XmlDataSource::create(), Nektar::ErrorUtil::efatal, and NEKERROR.

◆ v_Write()

void Nektar::LibUtilities::FieldIOXml::v_Write ( const std::string &  outFile,
std::vector< FieldDefinitionsSharedPtr > &  fielddefs,
std::vector< std::vector< NekDouble >> &  fielddata,
const FieldMetaDataMap fieldmetadatamap = NullFieldMetaDataMap,
const bool  backup = false 
)
privatevirtual

Write an XML file to outFile given the field definitions fielddefs, field data fielddata and metadata fieldmetadatamap.

The writing strategy is as follows:

  • Use FieldIO::SetUpOutput to construct the directory to contain each partition.
  • The root processor writes an Info.xml file containing the field metadata and an index that describes which elements lie in which XML file.
  • Each processor then writes an XML file containing the field definitions for that processor and output data in base64-encoded zlib-compressed format.
Parameters
outFileOutput filename.
fielddefsInput field definitions.
fielddataInput field data.
fieldmetadatamapField metadata.

Implements Nektar::LibUtilities::FieldIO.

Definition at line 87 of file FieldIOXml.cpp.

92 {
93  double tm0 = 0.0, tm1 = 0.0;
94  if (m_comm->TreatAsRankZero())
95  {
96  tm0 = m_comm->Wtime();
97  }
98 
99  // Check everything seems sensible
100  ASSERTL1(fielddefs.size() == fielddata.size(),
101  "Length of fielddefs and fielddata incompatible");
102  for (int f = 0; f < fielddefs.size(); ++f)
103  {
104  ASSERTL1(fielddata[f].size() > 0,
105  "Fielddata vector must contain at least one value.");
106 
107  ASSERTL1(fielddata[f].size() == fielddefs[f]->m_fields.size() *
108  CheckFieldDefinition(fielddefs[f]),
109  "Invalid size of fielddata vector.");
110  }
111 
112  // Prepare to write out data. In parallel, we must create directory and
113  // determine the full pathname to the file to write out. Any existing
114  // file/directory which is in the way is removed.
115  std::string filename = SetUpOutput(outFile, true, backup);
116  SetUpFieldMetaData(outFile, fielddefs, fieldmetadatamap);
117 
118  // Create the file (partition)
119  TiXmlDocument doc;
120  TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
121  doc.LinkEndChild(decl);
122 
123  TiXmlElement *root = new TiXmlElement("NEKTAR");
124  doc.LinkEndChild(root);
125 
126  AddInfoTag(XmlTagWriterSharedPtr(new XmlTagWriter(root)), fieldmetadatamap);
127 
128  for (int f = 0; f < fielddefs.size(); ++f)
129  {
130  //---------------------------------------------
131  // Write ELEMENTS
132  TiXmlElement *elemTag = new TiXmlElement("ELEMENTS");
133  root->LinkEndChild(elemTag);
134 
135  // Write FIELDS
136  std::string fieldsString;
137  {
138  std::stringstream fieldsStringStream;
139  bool first = true;
140  for (std::vector<int>::size_type i = 0;
141  i < fielddefs[f]->m_fields.size(); i++)
142  {
143  if (!first)
144  {
145  fieldsStringStream << ",";
146  }
147  fieldsStringStream << fielddefs[f]->m_fields[i];
148  first = false;
149  }
150  fieldsString = fieldsStringStream.str();
151  }
152  elemTag->SetAttribute("FIELDS", fieldsString);
153 
154  // Write SHAPE
155  std::string shapeString;
156  {
157  std::stringstream shapeStringStream;
158  shapeStringStream << ShapeTypeMap[fielddefs[f]->m_shapeType];
159  if (fielddefs[f]->m_numHomogeneousDir == 1)
160  {
161  shapeStringStream << "-HomogenousExp1D";
162  }
163  else if (fielddefs[f]->m_numHomogeneousDir == 2)
164  {
165  shapeStringStream << "-HomogenousExp2D";
166  }
167 
168  if (fielddefs[f]->m_homoStrips)
169  {
170  shapeStringStream << "-Strips";
171  }
172 
173  shapeString = shapeStringStream.str();
174  }
175  elemTag->SetAttribute("SHAPE", shapeString);
176 
177  // Write BASIS
178  std::string basisString;
179  {
180  std::stringstream basisStringStream;
181  bool first = true;
182  for (std::vector<BasisType>::size_type i = 0;
183  i < fielddefs[f]->m_basis.size(); i++)
184  {
185  if (!first)
186  {
187  basisStringStream << ",";
188  }
189  basisStringStream << BasisTypeMap[fielddefs[f]->m_basis[i]];
190  first = false;
191  }
192  basisString = basisStringStream.str();
193  }
194  elemTag->SetAttribute("BASIS", basisString);
195 
196  // Write homogeneuous length details
197  if (fielddefs[f]->m_numHomogeneousDir)
198  {
199  std::string homoLenString;
200  {
201  std::stringstream homoLenStringStream;
202  bool first = true;
203  for (int i = 0; i < fielddefs[f]->m_numHomogeneousDir; ++i)
204  {
205  if (!first)
206  homoLenStringStream << ",";
207  homoLenStringStream
208  << fielddefs[f]->m_homogeneousLengths[i];
209  first = false;
210  }
211  homoLenString = homoLenStringStream.str();
212  }
213  elemTag->SetAttribute("HOMOGENEOUSLENGTHS", homoLenString);
214  }
215 
216  // Write homogeneuous planes/lines details
217  if (fielddefs[f]->m_numHomogeneousDir)
218  {
219  if (fielddefs[f]->m_homogeneousYIDs.size() > 0)
220  {
221  std::string homoYIDsString;
222  {
223  std::stringstream homoYIDsStringStream;
224  bool first = true;
225  for (int i = 0; i < fielddefs[f]->m_homogeneousYIDs.size();
226  i++)
227  {
228  if (!first)
229  {
230  homoYIDsStringStream << ",";
231  }
232  homoYIDsStringStream
233  << fielddefs[f]->m_homogeneousYIDs[i];
234  first = false;
235  }
236  homoYIDsString = homoYIDsStringStream.str();
237  }
238  elemTag->SetAttribute("HOMOGENEOUSYIDS", homoYIDsString);
239  }
240 
241  if (fielddefs[f]->m_homogeneousZIDs.size() > 0)
242  {
243  std::string homoZIDsString;
244  {
245  std::stringstream homoZIDsStringStream;
246  bool first = true;
247  for (int i = 0; i < fielddefs[f]->m_homogeneousZIDs.size();
248  i++)
249  {
250  if (!first)
251  {
252  homoZIDsStringStream << ",";
253  }
254  homoZIDsStringStream
255  << fielddefs[f]->m_homogeneousZIDs[i];
256  first = false;
257  }
258  homoZIDsString = homoZIDsStringStream.str();
259  }
260  elemTag->SetAttribute("HOMOGENEOUSZIDS", homoZIDsString);
261  }
262 
263  if (fielddefs[f]->m_homogeneousSIDs.size() > 0)
264  {
265  std::string homoSIDsString;
266  {
267  std::stringstream homoSIDsStringStream;
268  bool first = true;
269  for (int i = 0; i < fielddefs[f]->m_homogeneousSIDs.size();
270  i++)
271  {
272  if (!first)
273  {
274  homoSIDsStringStream << ",";
275  }
276  homoSIDsStringStream
277  << fielddefs[f]->m_homogeneousSIDs[i];
278  first = false;
279  }
280  homoSIDsString = homoSIDsStringStream.str();
281  }
282  elemTag->SetAttribute("HOMOGENEOUSSIDS", homoSIDsString);
283  }
284  }
285 
286  // Write NUMMODESPERDIR
287  std::string numModesString;
288  {
289  std::stringstream numModesStringStream;
290 
291  if (fielddefs[f]->m_uniOrder)
292  {
293  numModesStringStream << "UNIORDER:";
294  // Just dump single definition
295  bool first = true;
296  for (std::vector<int>::size_type i = 0;
297  i < fielddefs[f]->m_basis.size(); i++)
298  {
299  if (!first)
300  {
301  numModesStringStream << ",";
302  }
303  numModesStringStream << fielddefs[f]->m_numModes[i];
304  first = false;
305  }
306  }
307  else
308  {
309  numModesStringStream << "MIXORDER:";
310  bool first = true;
311  for (std::vector<int>::size_type i = 0;
312  i < fielddefs[f]->m_numModes.size(); i++)
313  {
314  if (!first)
315  {
316  numModesStringStream << ",";
317  }
318  numModesStringStream << fielddefs[f]->m_numModes[i];
319  first = false;
320  }
321  }
322 
323  numModesString = numModesStringStream.str();
324  }
325  elemTag->SetAttribute("NUMMODESPERDIR", numModesString);
326 
327  // Write ID
328  // Should ideally look at ways of compressing this stream
329  // if just sequential;
330  std::string idString;
331  {
332  std::stringstream idStringStream;
333  idString =
334  ParseUtils::GenerateSeqString(fielddefs[f]->m_elementIDs);
335  }
336  elemTag->SetAttribute("ID", idString);
337  elemTag->SetAttribute("COMPRESSED",
339 
340  // Add this information for future compatibility
341  // issues, for exmaple in case we end up using a 128
342  // bit machine.
343  elemTag->SetAttribute("BITSIZE",
345  std::string base64string;
346  ASSERTL0(Z_OK == CompressData::ZlibEncodeToBase64Str(fielddata[f],
347  base64string),
348  "Failed to compress field data.");
349 
350  elemTag->LinkEndChild(new TiXmlText(base64string));
351  }
352  doc.SaveFile(filename);
353 
354  m_comm->Block();
355 
356  // all data has been written
357  if (m_comm->TreatAsRankZero())
358  {
359  tm1 = m_comm->Wtime();
360  std::cout << " (" << tm1 - tm0 << "s, XML)" << std::endl;
361  }
362 }
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
std::string SetUpOutput(const std::string outname, bool perRank, bool backup=false)
Set up the filesystem ready for output.
Definition: FieldIO.cpp:407
static void AddInfoTag(TagWriterSharedPtr root, const FieldMetaDataMap &fieldmetadatamap)
Add provenance information to the field metadata map.
Definition: FieldIO.cpp:345
void SetUpFieldMetaData(const std::string &outname, const std::vector< FieldDefinitionsSharedPtr > &fielddefs, const FieldMetaDataMap &fieldmetadatamap)
Set up field meta data map.
Definition: FieldIOXml.cpp:689
static std::string GenerateSeqString(const std::vector< T > &v)
Generate a compressed comma-separated string representation of a vector of unsigned integers.
Definition: ParseUtils.h:71
int ZlibEncodeToBase64Str(std::vector< T > &in, std::string &out64)
Definition: CompressData.h:132
std::shared_ptr< XmlTagWriter > XmlTagWriterSharedPtr
Definition: FieldIOXml.h:167

References Nektar::LibUtilities::FieldIO::AddInfoTag(), ASSERTL0, ASSERTL1, Nektar::LibUtilities::BasisTypeMap, Nektar::LibUtilities::FieldIO::CheckFieldDefinition(), Nektar::ParseUtils::GenerateSeqString(), Nektar::LibUtilities::CompressData::GetBitSizeStr(), Nektar::LibUtilities::CompressData::GetCompressString(), Nektar::LibUtilities::FieldIO::m_comm, SetUpFieldMetaData(), Nektar::LibUtilities::FieldIO::SetUpOutput(), Nektar::LibUtilities::ShapeTypeMap, and Nektar::LibUtilities::CompressData::ZlibEncodeToBase64Str().

◆ WriteMultiFldFileIDs()

void Nektar::LibUtilities::FieldIOXml::WriteMultiFldFileIDs ( const std::string &  outFile,
const std::vector< std::string >  fileNames,
std::vector< std::vector< unsigned int >> &  elementList,
const FieldMetaDataMap fieldmetadatamap = NullFieldMetaDataMap 
)

Write out a file containing element ID to partition mapping.

This function writes out an XML file (usually called Info.xml) that contains the element IDs that are contained within each partition, as well as the field metadata map.

Parameters
outFileOutput multi-field file name.
fileNamesList of partition filenames.
elementListVector of element IDs that lie on each process.
fieldmetadatamapField metadata map that is written into outFile.

Definition at line 376 of file FieldIOXml.cpp.

380 {
381  TiXmlDocument doc;
382  TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
383  doc.LinkEndChild(decl);
384 
385  ASSERTL0(fileNames.size() == elementList.size(),
386  "Outfile names and list of elements ids does not match");
387 
388  TiXmlElement *root = new TiXmlElement("NEKTAR");
389  doc.LinkEndChild(root);
390 
391  AddInfoTag(XmlTagWriterSharedPtr(new XmlTagWriter(root)), fieldmetadatamap);
392 
393  for (int t = 0; t < fileNames.size(); ++t)
394  {
395  if (elementList[t].size())
396  {
397  TiXmlElement *elemIDs = new TiXmlElement("Partition");
398  root->LinkEndChild(elemIDs);
399 
400  elemIDs->SetAttribute("FileName", fileNames[t]);
401 
402  std::string IDstr = ParseUtils::GenerateSeqString(elementList[t]);
403 
404  elemIDs->LinkEndChild(new TiXmlText(IDstr));
405  }
406  }
407 
408  doc.SaveFile(outFile);
409 }

References Nektar::LibUtilities::FieldIO::AddInfoTag(), ASSERTL0, and Nektar::ParseUtils::GenerateSeqString().

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

Member Data Documentation

◆ className

std::string Nektar::LibUtilities::FieldIOXml::className
static
Initial value:
"Xml", FieldIOXml::create, "XML-based output of field data.")
static FieldIOSharedPtr create(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
Creates an instance of this class.
Definition: FieldIOXml.h:209
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
FieldIOFactory & GetFieldIOFactory()
Returns the FieldIO factory.
Definition: FieldIO.cpp:72

Name of class.

Definition at line 217 of file FieldIOXml.h.

Referenced by GetClassName().