Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
Nektar::LibUtilities::FieldIO Class Reference

Class for operating on FLD files. More...

#include <FieldIO.h>

Inheritance diagram for Nektar::LibUtilities::FieldIO:
Inheritance graph
[legend]

Public Member Functions

 FieldIO (LibUtilities::CommSharedPtr pComm, bool sharedFilesystem=false)
 Constructor. More...
 
void Write (const std::string &outFile, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, const FieldMetaDataMap &fieldinfomap=NullFieldMetaDataMap)
 Write data in FLD format. 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)
 Imports an FLD file. More...
 
void ImportFieldMetaData (std::string filename, FieldMetaDataMap &fieldmetadatamap)
 Imports the definition of the meta data. More...
 
void ImportFieldMetaData (TiXmlDocument &doc, FieldMetaDataMap &fieldmetadatamap)
 Imports the definition of the meta data. More...
 
void ImportFieldDefs (TiXmlDocument &doc, std::vector< FieldDefinitionsSharedPtr > &fielddefs, bool expChild)
 Imports the definition of the fields. More...
 
void ImportFieldData (TiXmlDocument &doc, const std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata)
 Imports the data fileds. More...
 
void WriteMultiFldFileIDs (const std::string &outfile, const std::vector< std::string > fileNames, std::vector< std::vector< unsigned int > > &elementList, const FieldMetaDataMap &fieldinfomap=NullFieldMetaDataMap)
 

Protected Member Functions

void AddInfoTag (TiXmlElement *root, const FieldMetaDataMap &fieldmetadatamap)
 add information about provenance and fieldmetadata More...
 
void GenerateSeqString (const std::vector< unsigned int > &elmtids, std::string &idString)
 
std::string SetUpOutput (const std::string outname)
 
void SetUpFieldMetaData (const std::string outname, const std::vector< FieldDefinitionsSharedPtr > &fielddefs, const FieldMetaDataMap &fieldmetadatamap)
 
void ImportMultiFldFileIDs (const std::string &inFile, std::vector< std::string > &fileNames, std::vector< std::vector< unsigned int > > &elementList, FieldMetaDataMap &fieldmetadatamap)
 
int CheckFieldDefinition (const FieldDefinitionsSharedPtr &fielddefs)
 
virtual std::string GetFileEnding () const
 

Protected Attributes

LibUtilities::CommSharedPtr m_comm
 Communicator to use when writing parallel format. More...
 
bool m_sharedFilesystem
 True if same filesystem accessible by all processes. More...
 

Detailed Description

Class for operating on FLD files.

Definition at line 137 of file FieldIO.h.

Constructor & Destructor Documentation

Nektar::LibUtilities::FieldIO::FieldIO ( LibUtilities::CommSharedPtr  pComm,
bool  sharedFilesystem = false 
)

Constructor.

Definition at line 149 of file FieldIO.cpp.

150  :
151  m_comm(pComm),
152  m_sharedFilesystem(sharedFilesystem)
153  {
154  }
bool m_sharedFilesystem
True if same filesystem accessible by all processes.
Definition: FieldIO.h:194
LibUtilities::CommSharedPtr m_comm
Communicator to use when writing parallel format.
Definition: FieldIO.h:191

Member Function Documentation

void Nektar::LibUtilities::FieldIO::AddInfoTag ( TiXmlElement *  root,
const FieldMetaDataMap fieldmetadatamap 
)
protected

add information about provenance and fieldmetadata

Definition at line 1087 of file FieldIO.cpp.

References Nektar::NekConstants::kGitBranch, Nektar::NekConstants::kGitSha1, NEKTAR_VERSION, and Nektar::LibUtilities::NullFieldMetaDataMap.

Referenced by Write(), and WriteMultiFldFileIDs().

1089  {
1090  FieldMetaDataMap ProvenanceMap;
1091 
1092  // Nektar++ release version from VERSION file
1093  ProvenanceMap["NektarVersion"] = string(NEKTAR_VERSION);
1094 
1095  // Date/time stamp
1096  ptime::time_facet *facet = new ptime::time_facet("%d-%b-%Y %H:%M:%S");
1097  std::stringstream wss;
1098  wss.imbue(locale(wss.getloc(), facet));
1099  wss << ptime::second_clock::local_time();
1100  ProvenanceMap["Timestamp"] = wss.str();
1101 
1102  // Hostname
1103  boost::system::error_code ec;
1104  ProvenanceMap["Hostname"] = ip::host_name(ec);
1105 
1106  // Git information
1107  // If built from a distributed package, do not include this
1108  if (NekConstants::kGitSha1 != "GITDIR-NOTFOUND")
1109  {
1110  ProvenanceMap["GitSHA1"] = NekConstants::kGitSha1;
1111  ProvenanceMap["GitBranch"] = NekConstants::kGitBranch;
1112  }
1113 
1114  TiXmlElement * infoTag = new TiXmlElement("Metadata");
1115  root->LinkEndChild(infoTag);
1116 
1117  TiXmlElement * v;
1118  FieldMetaDataMap::const_iterator infoit;
1119 
1120  TiXmlElement * provTag = new TiXmlElement("Provenance");
1121  infoTag->LinkEndChild(provTag);
1122  for (infoit = ProvenanceMap.begin(); infoit != ProvenanceMap.end(); ++infoit)
1123  {
1124  v = new TiXmlElement( (infoit->first).c_str() );
1125  v->LinkEndChild(new TiXmlText((infoit->second).c_str()));
1126  provTag->LinkEndChild(v);
1127  }
1128 
1129  //---------------------------------------------
1130  // write field info section
1131  if(fieldmetadatamap != NullFieldMetaDataMap)
1132  {
1133  for(infoit = fieldmetadatamap.begin(); infoit != fieldmetadatamap.end(); ++infoit)
1134  {
1135  v = new TiXmlElement( (infoit->first).c_str() );
1136  v->LinkEndChild(new TiXmlText((infoit->second).c_str()));
1137  infoTag->LinkEndChild(v);
1138  }
1139  }
1140  }
std::map< std::string, std::string > FieldMetaDataMap
Definition: FieldIO.h:53
const std::string kGitSha1
const std::string kGitBranch
#define NEKTAR_VERSION
Definition: FieldIO.cpp:65
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:54
int Nektar::LibUtilities::FieldIO::CheckFieldDefinition ( const FieldDefinitionsSharedPtr fielddefs)
protected

Definition at line 1355 of file FieldIO.cpp.

References ASSERTL0, Nektar::LibUtilities::eHexahedron, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::ePyramid, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eSegment, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::LibUtilities::StdTriData::getNumberOfCoefficients(), Nektar::LibUtilities::StdTetData::getNumberOfCoefficients(), Nektar::LibUtilities::StdPyrData::getNumberOfCoefficients(), and Nektar::LibUtilities::StdPrismData::getNumberOfCoefficients().

Referenced by ImportFieldData(), and Write().

1356  {
1357  int i;
1358 
1359  if(fielddefs->m_elementIDs.size() == 0) // empty partition
1360  {
1361  return 0;
1362  }
1363  //ASSERTL0(fielddefs->m_elementIDs.size() > 0, "Fielddefs vector must contain at least one element of data .");
1364 
1365  unsigned int numbasis = 0;
1366 
1367  // Determine nummodes vector lists are correct length
1368  switch(fielddefs->m_shapeType)
1369  {
1370  case eSegment:
1371  numbasis = 1;
1372  if(fielddefs->m_numHomogeneousDir)
1373  {
1374  numbasis += fielddefs->m_numHomogeneousDir;
1375  }
1376 
1377  break;
1378  case eTriangle:
1379  case eQuadrilateral:
1380  if(fielddefs->m_numHomogeneousDir)
1381  {
1382  numbasis = 3;
1383  }
1384  else
1385  {
1386  numbasis = 2;
1387  }
1388  break;
1389  case eTetrahedron:
1390  case ePyramid:
1391  case ePrism:
1392  case eHexahedron:
1393  numbasis = 3;
1394  break;
1395  default:
1396  ASSERTL0(false, "Unsupported shape type.");
1397  break;
1398  }
1399 
1400  unsigned int datasize = 0;
1401 
1402  ASSERTL0(fielddefs->m_basis.size() == numbasis, "Length of basis vector is incorrect");
1403 
1404  if(fielddefs->m_uniOrder == true)
1405  {
1406  unsigned int cnt = 0;
1407  // calculate datasize
1408  switch(fielddefs->m_shapeType)
1409  {
1410  case eSegment:
1411  {
1412  int l = fielddefs->m_numModes[cnt++];
1413  if(fielddefs->m_numHomogeneousDir == 1)
1414  {
1415  datasize += l*fielddefs->m_numModes[cnt++];
1416  }
1417  else if(fielddefs->m_numHomogeneousDir == 2)
1418  {
1419  int m = fielddefs->m_numModes[cnt++];
1420  datasize += l*m*fielddefs->m_numModes[cnt++];
1421  }
1422  else
1423  {
1424  datasize += l;
1425  }
1426  }
1427  break;
1428  case eTriangle:
1429  {
1430  int l = fielddefs->m_numModes[cnt++];
1431  int m = fielddefs->m_numModes[cnt++];
1432 
1433  if(fielddefs->m_numHomogeneousDir == 1)
1434  {
1435  datasize += StdTriData::getNumberOfCoefficients(l,m)*
1436  fielddefs->m_homogeneousZIDs.size();
1437  }
1438  else
1439  {
1440  datasize += StdTriData::getNumberOfCoefficients(l,m);
1441  }
1442  }
1443  break;
1444  case eQuadrilateral:
1445  {
1446  int l = fielddefs->m_numModes[cnt++];
1447  int m = fielddefs->m_numModes[cnt++];
1448  if(fielddefs->m_numHomogeneousDir == 1)
1449  {
1450  datasize += l*m*fielddefs->m_homogeneousZIDs.size();
1451  }
1452  else
1453  {
1454  datasize += l*m;
1455  }
1456  }
1457  break;
1458  case eTetrahedron:
1459  {
1460  int l = fielddefs->m_numModes[cnt++];
1461  int m = fielddefs->m_numModes[cnt++];
1462  int n = fielddefs->m_numModes[cnt++];
1463  datasize += StdTetData::getNumberOfCoefficients(l,m,n);
1464  }
1465  break;
1466  case ePyramid:
1467  {
1468  int l = fielddefs->m_numModes[cnt++];
1469  int m = fielddefs->m_numModes[cnt++];
1470  int n = fielddefs->m_numModes[cnt++];
1471  datasize += StdPyrData::getNumberOfCoefficients(l,m,n);
1472  }
1473  break;
1474  case ePrism:
1475  {
1476  int l = fielddefs->m_numModes[cnt++];
1477  int m = fielddefs->m_numModes[cnt++];
1478  int n = fielddefs->m_numModes[cnt++];
1479  datasize += StdPrismData::getNumberOfCoefficients(l,m,n);
1480  }
1481  break;
1482  case eHexahedron:
1483  {
1484  int l = fielddefs->m_numModes[cnt++];
1485  int m = fielddefs->m_numModes[cnt++];
1486  int n = fielddefs->m_numModes[cnt++];
1487  datasize += l*m*n;
1488  }
1489  break;
1490  default:
1491  ASSERTL0(false, "Unsupported shape type.");
1492  break;
1493  }
1494 
1495  datasize *= fielddefs->m_elementIDs.size();
1496  }
1497  else
1498  {
1499  unsigned int cnt = 0;
1500  // calculate data length
1501  for(i = 0; i < fielddefs->m_elementIDs.size(); ++i)
1502  {
1503  switch(fielddefs->m_shapeType)
1504  {
1505  case eSegment:
1506  {
1507  int l = fielddefs->m_numModes[cnt++];
1508  if(fielddefs->m_numHomogeneousDir == 1)
1509  {
1510  datasize += l*fielddefs->m_numModes[cnt++];
1511  }
1512  else if(fielddefs->m_numHomogeneousDir == 2)
1513  {
1514  int m = fielddefs->m_numModes[cnt++];
1515  datasize += l*m*fielddefs->m_numModes[cnt++];
1516  }
1517  else
1518  {
1519  datasize += l;
1520  }
1521  }
1522  break;
1523  case eTriangle:
1524  {
1525  int l = fielddefs->m_numModes[cnt++];
1526  int m = fielddefs->m_numModes[cnt++];
1527  if(fielddefs->m_numHomogeneousDir == 1)
1528  {
1529  datasize += StdTriData::getNumberOfCoefficients(l,m)*
1530  fielddefs->m_homogeneousZIDs.size();
1531  cnt++;
1532  }
1533  else
1534  {
1535  datasize += StdTriData::getNumberOfCoefficients(l,m);
1536  }
1537  }
1538  break;
1539  case eQuadrilateral:
1540  {
1541  int l = fielddefs->m_numModes[cnt++];
1542  int m = fielddefs->m_numModes[cnt++];
1543  if(fielddefs->m_numHomogeneousDir == 1)
1544  {
1545  datasize += l*m*fielddefs->
1546  m_homogeneousZIDs.size();
1547  cnt++;
1548  }
1549  else
1550  {
1551  datasize += l*m;
1552  }
1553  }
1554  break;
1555  case eTetrahedron:
1556  {
1557  int l = fielddefs->m_numModes[cnt++];
1558  int m = fielddefs->m_numModes[cnt++];
1559  int n = fielddefs->m_numModes[cnt++];
1560  datasize += StdTetData::getNumberOfCoefficients(l,m,n);
1561  }
1562  break;
1563  case ePyramid:
1564  {
1565  int l = fielddefs->m_numModes[cnt++];
1566  int m = fielddefs->m_numModes[cnt++];
1567  int n = fielddefs->m_numModes[cnt++];
1568  datasize += StdPyrData::getNumberOfCoefficients(l,m,n);
1569  }
1570  break;
1571  case ePrism:
1572  {
1573  int l = fielddefs->m_numModes[cnt++];
1574  int m = fielddefs->m_numModes[cnt++];
1575  int n = fielddefs->m_numModes[cnt++];
1576  datasize += StdPrismData::getNumberOfCoefficients(l,m,n);
1577  }
1578  break;
1579  case eHexahedron:
1580  {
1581  int l = fielddefs->m_numModes[cnt++];
1582  int m = fielddefs->m_numModes[cnt++];
1583  int n = fielddefs->m_numModes[cnt++];
1584  datasize += l*m*n;
1585  }
1586  break;
1587  default:
1588  ASSERTL0(false, "Unsupported shape type.");
1589  break;
1590  }
1591  }
1592  }
1593 
1594  return datasize;
1595  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:286
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:186
int getNumberOfCoefficients(int Na, int Nb)
Definition: ShapeType.hpp:111
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:232
void Nektar::LibUtilities::FieldIO::GenerateSeqString ( const std::vector< unsigned int > &  elmtids,
std::string &  idString 
)
protected

Definition at line 1146 of file FieldIO.cpp.

Referenced by Write(), and WriteMultiFldFileIDs().

1148  {
1149  std::stringstream idStringStream;
1150  bool setdash = true;
1151  unsigned int endval;
1152 
1153  idStringStream << elmtids[0];
1154  for (int i = 1; i < elmtids.size(); ++i)
1155  {
1156  if(elmtids[i] == elmtids[i-1]+1)
1157  {
1158  if(setdash)
1159  {
1160  idStringStream << "-";
1161  setdash = false;
1162  }
1163 
1164  if(i == elmtids.size()-1) // last element
1165  {
1166  idStringStream << elmtids[i];
1167  }
1168  else
1169  {
1170  endval = elmtids[i];
1171  }
1172  }
1173  else
1174  {
1175  if(setdash == false) // finish off previous dash sequence
1176  {
1177  idStringStream << endval;
1178  setdash = true;
1179  }
1180 
1181 
1182  idStringStream << "," << elmtids[i];
1183  }
1184  }
1185  idString = idStringStream.str();
1186  }
virtual std::string Nektar::LibUtilities::FieldIO::GetFileEnding ( ) const
inlineprotectedvirtual

Reimplemented in Nektar::LibUtilities::PtsIO.

Definition at line 218 of file FieldIO.h.

Referenced by SetUpFieldMetaData(), and SetUpOutput().

219  {
220  return "fld";
221  };
void Nektar::LibUtilities::FieldIO::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 
)

Imports an FLD file.

Definition at line 409 of file FieldIO.cpp.

References ASSERTL0, ImportFieldData(), ImportFieldDefs(), ImportFieldMetaData(), ImportMultiFldFileIDs(), Nektar::iterator, Nektar::NullInt1DArray, Nektar::LibUtilities::NullVectorNekDoubleVector, and Nektar::LibUtilities::PortablePath().

Referenced by Nektar::MultiRegions::ExpList::ExtractFileBCs(), and Nektar::LibUtilities::Import().

414  {
415 
416  std::string infile = infilename;
417 
418  fs::path pinfilename(infilename);
419 
420  if(fs::is_directory(pinfilename)) // check to see that infile is a directory
421  {
422  fs::path infofile("Info.xml");
423  fs::path fullpath = pinfilename / infofile;
424  infile = PortablePath(fullpath);
425 
426  std::vector<std::string> filenames;
427  std::vector<std::vector<unsigned int> > elementIDs_OnPartitions;
428 
429 
430  ImportMultiFldFileIDs(infile,filenames, elementIDs_OnPartitions,
431  fieldmetadatamap);
432 
433  // Load metadata
434  ImportFieldMetaData(infile,fieldmetadatamap);
435 
436  if(ElementIDs == NullInt1DArray) //load all fields
437  {
438  for(int i = 0; i < filenames.size(); ++i)
439  {
440  fs::path pfilename(filenames[i]);
441  fullpath = pinfilename / pfilename;
442  string fname = PortablePath(fullpath);
443 
444  TiXmlDocument doc1(fname);
445  bool loadOkay1 = doc1.LoadFile();
446 
447  std::stringstream errstr;
448  errstr << "Unable to load file: " << fname << std::endl;
449  errstr << "Reason: " << doc1.ErrorDesc() << std::endl;
450  errstr << "Position: Line " << doc1.ErrorRow() << ", Column " << doc1.ErrorCol() << std::endl;
451  ASSERTL0(loadOkay1, errstr.str());
452 
453  ImportFieldDefs(doc1, fielddefs, false);
454  if(fielddata != NullVectorNekDoubleVector)
455  {
456  ImportFieldData(doc1, fielddefs, fielddata);
457  }
458  }
459 
460  }
461  else // only load relevant partitions
462  {
463  int i,j;
464  map<int,vector<int> > FileIDs;
465  map<int,vector<int> >::iterator it;
466  set<int> LoadFile;
467 
468  for(i = 0; i < elementIDs_OnPartitions.size(); ++i)
469  {
470  for(j = 0; j < elementIDs_OnPartitions[i].size(); ++j)
471  {
472  FileIDs[elementIDs_OnPartitions[i][j]].push_back(i);
473  }
474  }
475 
476  for(i = 0; i < ElementIDs.num_elements(); ++i)
477  {
478  it = FileIDs.find(ElementIDs[i]);
479  if (it != FileIDs.end())
480  {
481  for (j = 0; j < it->second.size(); ++j)
482  {
483  LoadFile.insert(it->second[j]);
484  }
485  }
486  }
487 
488  set<int>::iterator iter;
489  for(iter = LoadFile.begin(); iter != LoadFile.end(); ++iter)
490  {
491  fs::path pfilename(filenames[*iter]);
492  fullpath = pinfilename / pfilename;
493  string fname = PortablePath(fullpath);
494  TiXmlDocument doc1(fname);
495  bool loadOkay1 = doc1.LoadFile();
496 
497  std::stringstream errstr;
498  errstr << "Unable to load file: " << fname << std::endl;
499  errstr << "Reason: " << doc1.ErrorDesc() << std::endl;
500  errstr << "Position: Line " << doc1.ErrorRow() << ", Column " << doc1.ErrorCol() << std::endl;
501  ASSERTL0(loadOkay1, errstr.str());
502 
503  ImportFieldDefs(doc1, fielddefs, false);
504  if(fielddata != NullVectorNekDoubleVector)
505  {
506  ImportFieldData(doc1, fielddefs, fielddata);
507  }
508  }
509  }
510  }
511  else // serial format case
512  {
513 
514  TiXmlDocument doc(infile);
515  bool loadOkay = doc.LoadFile();
516 
517  std::stringstream errstr;
518  errstr << "Unable to load file: " << infile << std::endl;
519  errstr << "Reason: " << doc.ErrorDesc() << std::endl;
520  errstr << "Position: Line " << doc.ErrorRow() << ", Column " <<
521  doc.ErrorCol() << std::endl;
522  ASSERTL0(loadOkay, errstr.str());
523 
524  ImportFieldMetaData(doc,fieldmetadatamap);
525  ImportFieldDefs(doc, fielddefs, false);
526  if(fielddata != NullVectorNekDoubleVector)
527  {
528  ImportFieldData(doc, fielddefs, fielddata);
529  }
530  }
531  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
void ImportFieldDefs(TiXmlDocument &doc, std::vector< FieldDefinitionsSharedPtr > &fielddefs, bool expChild)
Imports the definition of the fields.
Definition: FieldIO.cpp:726
void ImportFieldData(TiXmlDocument &doc, const std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata)
Imports the data fileds.
Definition: FieldIO.cpp:1018
void ImportMultiFldFileIDs(const std::string &inFile, std::vector< std::string > &fileNames, std::vector< std::vector< unsigned int > > &elementList, FieldMetaDataMap &fieldmetadatamap)
Definition: FieldIO.cpp:577
static std::vector< std::vector< NekDouble > > NullVectorNekDoubleVector
Definition: FieldIO.h:55
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:41
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
void ImportFieldMetaData(std::string filename, FieldMetaDataMap &fieldmetadatamap)
Imports the definition of the meta data.
Definition: FieldIO.cpp:637
static Array< OneD, int > NullInt1DArray
void Nektar::LibUtilities::FieldIO::ImportFieldData ( TiXmlDocument &  doc,
const std::vector< FieldDefinitionsSharedPtr > &  fielddefs,
std::vector< std::vector< NekDouble > > &  fielddata 
)

Imports the data fileds.

Definition at line 1018 of file FieldIO.cpp.

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

Referenced by Import().

1019  {
1020  int cntdumps = 0;
1021 
1022  TiXmlHandle docHandle(&doc);
1023  TiXmlElement* master = NULL; // Master tag within which all data is contained.
1024 
1025  master = doc.FirstChildElement("NEKTAR");
1026  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
1027 
1028  // Loop through all nektar tags, finding all of the element tags.
1029  while (master)
1030  {
1031  TiXmlElement* element = master->FirstChildElement("ELEMENTS");
1032  ASSERTL0(element, "Unable to find ELEMENTS tag within nektar tag.");
1033  while (element)
1034  {
1035  // Extract the body, which the "data".
1036  TiXmlNode* elementChild = element->FirstChild();
1037  ASSERTL0(elementChild, "Unable to extract the data from the element tag.");
1038  std::string elementStr;
1039  while(elementChild)
1040  {
1041  if (elementChild->Type() == TiXmlNode::TINYXML_TEXT)
1042  {
1043  elementStr += elementChild->ToText()->ValueStr();
1044  }
1045  elementChild = elementChild->NextSibling();
1046  }
1047 
1048  std::vector<NekDouble> elementFieldData;
1049  // Convert from base64 to binary.
1050 
1051  const char *CompressStr = element->Attribute("COMPRESSED");
1052  if(CompressStr)
1053  {
1054  if(!boost::iequals(CompressStr,
1056  {
1057  WARNINGL0(false, "Compressed formats do not match. "
1058  "Expected: "
1060  + " but got "+ string(CompressStr));
1061  }
1062  }
1063 
1065  elementStr,
1066  elementFieldData),
1067  "Failed to decompress field data.");
1068 
1069 
1070  fielddata.push_back(elementFieldData);
1071 
1072  int datasize = CheckFieldDefinition(fielddefs[cntdumps]);
1073  ASSERTL0(fielddata[cntdumps].size() == datasize*fielddefs[cntdumps]->m_fields.size(),"Input data is not the same length as header infoarmation");
1074 
1075  cntdumps++;
1076 
1077  element = element->NextSiblingElement("ELEMENTS");
1078  }
1079  master = master->NextSiblingElement("NEKTAR");
1080  }
1081  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
int CheckFieldDefinition(const FieldDefinitionsSharedPtr &fielddefs)
Definition: FieldIO.cpp:1355
#define WARNINGL0(condition, msg)
Definition: ErrorUtil.hpp:194
int ZlibDecodeFromBase64Str(std::string &in64, std::vector< T > &out)
Definition: CompressData.h:243
void Nektar::LibUtilities::FieldIO::ImportFieldDefs ( TiXmlDocument &  doc,
std::vector< FieldDefinitionsSharedPtr > &  fielddefs,
bool  expChild 
)

Imports the definition of the fields.

The bool decides if the FieldDefs are in <EXPANSIONS> or in <NEKTAR>.

Definition at line 726 of file FieldIO.cpp.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), ASSERTL0, ASSERTL1, Nektar::LibUtilities::BasisTypeMap, Nektar::ParseUtils::GenerateOrderedStringVector(), Nektar::ParseUtils::GenerateOrderedVector(), Nektar::ParseUtils::GenerateSeqVector(), Nektar::ParseUtils::GenerateUnOrderedVector(), Nektar::LibUtilities::CompressData::GetCompressString(), Nektar::LibUtilities::kPointsTypeStr, Nektar::LibUtilities::ShapeTypeMap, Nektar::LibUtilities::SIZE_BasisType, Nektar::LibUtilities::SIZE_PointsType, Nektar::LibUtilities::SIZE_ShapeType, and WARNINGL0.

Referenced by Import(), and Nektar::SpatialDomains::MeshGraph::ReadExpansions().

728  {
729  TiXmlHandle docHandle(&doc);
730  TiXmlElement* master = NULL; // Master tag within which all data is contained.
731 
732  master = doc.FirstChildElement("NEKTAR");
733  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
734  std::string strLoop = "NEKTAR";
735  TiXmlElement* loopXml = master;
736 
737  TiXmlElement *expansionTypes;
738  if(expChild)
739  {
740  expansionTypes = master->FirstChildElement("EXPANSIONS");
741  ASSERTL0(expansionTypes, "Unable to find EXPANSIONS tag in file.");
742  loopXml = expansionTypes;
743  strLoop = "EXPANSIONS";
744  }
745 
746  // Loop through all nektar tags, finding all of the element tags.
747  while (loopXml)
748  {
749  TiXmlElement* element = loopXml->FirstChildElement("ELEMENTS");
750  ASSERTL0(element, "Unable to find ELEMENTS tag within nektar tag.");
751 
752  while (element)
753  {
754  // Extract the attributes.
755  std::string idString;
756  std::string shapeString;
757  std::string basisString;
758  std::string homoLengthsString;
759  std::string homoSIDsString;
760  std::string homoZIDsString;
761  std::string homoYIDsString;
762  std::string numModesString;
763  std::string numPointsString;
764  std::string fieldsString;
765  std::string pointsString;
766  bool pointDef = false;
767  bool numPointDef = false;
768  TiXmlAttribute *attr = element->FirstAttribute();
769  while (attr)
770  {
771  std::string attrName(attr->Name());
772  if (attrName == "FIELDS")
773  {
774  fieldsString.insert(0, attr->Value());
775  }
776  else if (attrName == "SHAPE")
777  {
778  shapeString.insert(0, attr->Value());
779  }
780  else if (attrName == "BASIS")
781  {
782  basisString.insert(0, attr->Value());
783  }
784  else if (attrName == "HOMOGENEOUSLENGTHS")
785  {
786  homoLengthsString.insert(0,attr->Value());
787  }
788  else if (attrName == "HOMOGENEOUSSIDS")
789  {
790  homoSIDsString.insert(0,attr->Value());
791  }
792  else if (attrName == "HOMOGENEOUSZIDS")
793  {
794  homoZIDsString.insert(0,attr->Value());
795  }
796  else if (attrName == "HOMOGENEOUSYIDS")
797  {
798  homoYIDsString.insert(0,attr->Value());
799  }
800  else if (attrName == "NUMMODESPERDIR")
801  {
802  numModesString.insert(0, attr->Value());
803  }
804  else if (attrName == "ID")
805  {
806  idString.insert(0, attr->Value());
807  }
808  else if (attrName == "POINTSTYPE")
809  {
810  pointsString.insert(0, attr->Value());
811  pointDef = true;
812  }
813  else if (attrName == "NUMPOINTSPERDIR")
814  {
815  numPointsString.insert(0, attr->Value());
816  numPointDef = true;
817  }
818  else if (attrName == "COMPRESSED")
819  {
820  if(!boost::iequals(attr->Value(),
822  {
823  WARNINGL0(false, "Compressed formats do not "
824  "match. Expected: "
826  + " but got "+ string(attr->Value()));
827  }
828  }
829  else if (attrName =="BITSIZE")
830  {
831  // This information is for future
832  // compatibility issues, for exmaple in
833  // case we end up using a 128 bit machine.
834  // Currently just do nothing
835  }
836  else
837  {
838  std::string errstr("Unknown attribute: ");
839  errstr += attrName;
840  ASSERTL1(false, errstr.c_str());
841  }
842 
843  // Get the next attribute.
844  attr = attr->Next();
845  }
846 
847 
848  // Check to see if using strips formulation
849  bool strips = false;
850  if(shapeString.find("Strips")!=string::npos)
851  {
852  strips = true;
853  }
854 
855  // Check to see if homogeneous expansion and if so
856  // strip down the shapeString definition
857  int numHomoDir = 0;
858  size_t loc;
859  //---> This finds the first location of 'n'!
860  if((loc = shapeString.find_first_of("-"))!=string::npos)
861  {
862  if(shapeString.find("Exp1D")!=string::npos)
863  {
864  numHomoDir = 1;
865  }
866  else // HomogeneousExp1D
867  {
868  numHomoDir = 2;
869  }
870 
871  shapeString.erase(loc,shapeString.length());
872  }
873 
874  // Reconstruct the fielddefs.
875  std::vector<unsigned int> elementIds;
876  {
877  bool valid = ParseUtils::GenerateSeqVector(idString.c_str(), elementIds);
878  ASSERTL0(valid, "Unable to correctly parse the element ids.");
879  }
880 
881  // Get the geometrical shape
882  ShapeType shape;
883  bool valid = false;
884  for (unsigned int j = 0; j < SIZE_ShapeType; j++)
885  {
886  if (ShapeTypeMap[j] == shapeString)
887  {
888  shape = (ShapeType) j;
889  valid = true;
890  break;
891  }
892  }
893 
894  ASSERTL0(valid, std::string("Unable to correctly parse the shape type: ").append(shapeString).c_str());
895 
896  // Get the basis
897  std::vector<std::string> basisStrings;
898  std::vector<BasisType> basis;
899  valid = ParseUtils::GenerateOrderedStringVector(basisString.c_str(), basisStrings);
900  ASSERTL0(valid, "Unable to correctly parse the basis types.");
901  for (std::vector<std::string>::size_type i = 0; i < basisStrings.size(); i++)
902  {
903  valid = false;
904  for (unsigned int j = 0; j < SIZE_BasisType; j++)
905  {
906  if (BasisTypeMap[j] == basisStrings[i])
907  {
908  basis.push_back((BasisType) j);
909  valid = true;
910  break;
911  }
912  }
913  ASSERTL0(valid, std::string("Unable to correctly parse the basis type: ").append(basisStrings[i]).c_str());
914  }
915 
916  // Get homoLengths
917  std::vector<NekDouble> homoLengths;
918  if(numHomoDir)
919  {
920  valid = ParseUtils::GenerateUnOrderedVector(homoLengthsString.c_str(), homoLengths);
921  ASSERTL0(valid, "Unable to correctly parse the number of homogeneous lengths.");
922  }
923 
924  // Get Homogeneous strips IDs
925  std::vector<unsigned int> homoSIDs;
926  if(strips)
927  {
928  valid = ParseUtils::GenerateSeqVector(homoSIDsString.c_str(), homoSIDs);
929  ASSERTL0(valid, "Unable to correctly parse homogeneous strips IDs.");
930  }
931  // Get Homogeneous points IDs
932  std::vector<unsigned int> homoZIDs;
933  std::vector<unsigned int> homoYIDs;
934 
935  if(numHomoDir == 1)
936  {
937  valid = ParseUtils::GenerateSeqVector(homoZIDsString.c_str(), homoZIDs);
938  ASSERTL0(valid, "Unable to correctly parse homogeneous planes IDs.");
939  }
940 
941  if(numHomoDir == 2)
942  {
943  valid = ParseUtils::GenerateSeqVector(homoZIDsString.c_str(), homoZIDs);
944  ASSERTL0(valid, "Unable to correctly parse homogeneous lines IDs in z-direction.");
945  valid = ParseUtils::GenerateSeqVector(homoYIDsString.c_str(), homoYIDs);
946  ASSERTL0(valid, "Unable to correctly parse homogeneous lines IDs in y-direction.");
947  }
948 
949 
950  // Get points type
951  std::vector<PointsType> points;
952 
953  if(pointDef)
954  {
955  std::vector<std::string> pointsStrings;
956  valid = ParseUtils::GenerateOrderedStringVector(pointsString.c_str(), pointsStrings);
957  ASSERTL0(valid, "Unable to correctly parse the points types.");
958  for (std::vector<std::string>::size_type i = 0; i < pointsStrings.size(); i++)
959  {
960  valid = false;
961  for (unsigned int j = 0; j < SIZE_PointsType; j++)
962  {
963  if (kPointsTypeStr[j] == pointsStrings[i])
964  {
965  points.push_back((PointsType) j);
966  valid = true;
967  break;
968  }
969  }
970 
971  ASSERTL0(valid, std::string("Unable to correctly parse the points type: ").append(pointsStrings[i]).c_str());
972  }
973  }
974 
975  // Get numModes
976  std::vector<unsigned int> numModes;
977  bool UniOrder = false;
978 
979  if(strstr(numModesString.c_str(),"UNIORDER:"))
980  {
981  UniOrder = true;
982  }
983 
984  valid = ParseUtils::GenerateOrderedVector(numModesString.c_str()+9, numModes);
985  ASSERTL0(valid, "Unable to correctly parse the number of modes.");
986 
987  // Get numPoints
988  std::vector<unsigned int> numPoints;
989  if(numPointDef)
990  {
991  valid = ParseUtils::GenerateOrderedVector(numPointsString.c_str(), numPoints);
992  ASSERTL0(valid, "Unable to correctly parse the number of points.");
993  }
994 
995  // Get fields names
996  std::vector<std::string> Fields;
997  valid = ParseUtils::GenerateOrderedStringVector(fieldsString.c_str(), Fields);
998  ASSERTL0(valid, "Unable to correctly parse the number of fields.");
999 
1000  FieldDefinitionsSharedPtr fielddef =
1002  elementIds, basis, UniOrder, numModes, Fields, numHomoDir,
1003  homoLengths, strips, homoSIDs, homoZIDs, homoYIDs,
1004  points, pointDef, numPoints, numPointDef);
1005 
1006  fielddefs.push_back(fielddef);
1007 
1008  element = element->NextSiblingElement("ELEMENTS");
1009  }
1010  loopXml = loopXml->NextSiblingElement(strLoop);
1011  }
1012  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
static bool GenerateOrderedStringVector(const char *const str, std::vector< std::string > &vec)
Definition: ParseUtils.hpp:143
static bool GenerateOrderedVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:97
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
const char *const BasisTypeMap[]
Definition: Foundations.hpp:47
const std::string kPointsTypeStr[]
Definition: Foundations.hpp:69
boost::shared_ptr< FieldDefinitions > FieldDefinitionsSharedPtr
Definition: FieldIO.h:118
static bool GenerateSeqVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:79
const char *const ShapeTypeMap[]
Definition: ShapeType.hpp:66
#define WARNINGL0(condition, msg)
Definition: ErrorUtil.hpp:194
static bool GenerateUnOrderedVector(const char *const str, std::vector< NekDouble > &vec)
Definition: ParseUtils.hpp:128
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:218
void Nektar::LibUtilities::FieldIO::ImportFieldMetaData ( std::string  filename,
FieldMetaDataMap fieldmetadatamap 
)

Imports the definition of the meta data.

Definition at line 637 of file FieldIO.cpp.

References ASSERTL0.

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

639  {
640  TiXmlDocument doc(filename);
641  bool loadOkay = doc.LoadFile();
642 
643  std::stringstream errstr;
644  errstr << "Unable to load file: " << filename << std::endl;
645  errstr << "Reason: " << doc.ErrorDesc() << std::endl;
646  errstr << "Position: Line " << doc.ErrorRow() << ", Column " << doc.ErrorCol() << std::endl;
647  ASSERTL0(loadOkay, errstr.str());
648 
649  ImportFieldMetaData(doc,fieldmetadatamap);
650  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
void ImportFieldMetaData(std::string filename, FieldMetaDataMap &fieldmetadatamap)
Imports the definition of the meta data.
Definition: FieldIO.cpp:637
void Nektar::LibUtilities::FieldIO::ImportFieldMetaData ( TiXmlDocument &  doc,
FieldMetaDataMap fieldmetadatamap 
)

Imports the definition of the meta data.

Definition at line 653 of file FieldIO.cpp.

References ASSERTL0.

655  {
656 
657  TiXmlHandle docHandle(&doc);
658  TiXmlElement* master = 0; // Master tag within which all data is contained.
659  TiXmlElement* metadata = 0;
660 
661  master = doc.FirstChildElement("NEKTAR");
662  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
663  std::string strLoop = "NEKTAR";
664 
665  // Retain original metadata structure for backwards compatibility
666  // TODO: Remove old metadata format
667  metadata = master->FirstChildElement("FIELDMETADATA");
668  if(metadata)
669  {
670  TiXmlElement *param = metadata->FirstChildElement("P");
671 
672  while (param)
673  {
674  TiXmlAttribute *paramAttr = param->FirstAttribute();
675  std::string attrName(paramAttr->Name());
676  std::string paramString;
677 
678  if(attrName == "PARAM")
679  {
680  paramString.insert(0,paramAttr->Value());
681  }
682  else
683  {
684  ASSERTL0(false,"PARAM not provided as an attribute in FIELDMETADATA section");
685  }
686 
687  // Now read body of param
688  std::string paramBodyStr;
689 
690  TiXmlNode *paramBody = param->FirstChild();
691 
692  paramBodyStr += paramBody->ToText()->Value();
693 
694  fieldmetadatamap[paramString] = paramBodyStr;
695  param = param->NextSiblingElement("P");
696  }
697  }
698 
699  // New metadata format
700  metadata = master->FirstChildElement("Metadata");
701  if(metadata)
702  {
703  TiXmlElement *param = metadata->FirstChildElement();
704 
705  while (param)
706  {
707  std::string paramString = param->Value();
708  if (paramString != "Provenance")
709  {
710  // Now read body of param
711  TiXmlNode *paramBody = param->FirstChild();
712  std::string paramBodyStr = paramBody->ToText()->Value();
713 
714  fieldmetadatamap[paramString] = paramBodyStr;
715  }
716  param = param->NextSiblingElement();
717  }
718  }
719 
720  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
void Nektar::LibUtilities::FieldIO::ImportMultiFldFileIDs ( const std::string &  inFile,
std::vector< std::string > &  fileNames,
std::vector< std::vector< unsigned int > > &  elementList,
FieldMetaDataMap fieldmetadatamap 
)
protected

Definition at line 577 of file FieldIO.cpp.

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

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

581  {
582  TiXmlDocument doc(inFile);
583  bool loadOkay = doc.LoadFile();
584 
585 
586  std::stringstream errstr;
587  errstr << "Unable to load file: " << inFile<< std::endl;
588  errstr << "Reason: " << doc.ErrorDesc() << std::endl;
589  errstr << "Position: Line " << doc.ErrorRow() << ", Column " << doc.ErrorCol() << std::endl;
590  ASSERTL0(loadOkay, errstr.str());
591 
592  // Handle on XML document
593  TiXmlHandle docHandle(&doc);
594 
595  // Retrieve main NEKTAR tag - XML specification states one
596  // top-level element tag per file.
597  TiXmlElement* master = doc.FirstChildElement("NEKTAR");
598  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
599 
600  // Partition element tag name
601  std::string strPartition = "Partition";
602 
603  // First attempt to get the first Partition element
604  TiXmlElement* fldfileIDs = master->FirstChildElement(strPartition.c_str());
605  if (!fldfileIDs)
606  {
607  // If this files try previous name
608  strPartition = "MultipleFldFiles";
609  fldfileIDs = master->FirstChildElement("MultipleFldFiles");
610  }
611  ASSERTL0(fldfileIDs,
612  "Unable to find 'Partition' or 'MultipleFldFiles' tag "
613  "within nektar tag.");
614 
615  while (fldfileIDs)
616  {
617  // Read file name of partition file
618  const char *attr = fldfileIDs->Attribute("FileName");
619  ASSERTL0(attr, "'FileName' not provided as an attribute of '"
620  + strPartition + "' tag.");
621  fileNames.push_back(std::string(attr));
622 
623  const char* elementIDs = fldfileIDs->GetText();
624  ASSERTL0(elementIDs, "Element IDs not specified.");
625 
626  std::string elementIDsStr(elementIDs);
627 
628  std::vector<unsigned int> idvec;
629  ParseUtils::GenerateSeqVector(elementIDsStr.c_str(),idvec);
630 
631  elementList.push_back(idvec);
632 
633  fldfileIDs = fldfileIDs->NextSiblingElement(strPartition.c_str());
634  }
635  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
static bool GenerateSeqVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:79
void Nektar::LibUtilities::FieldIO::SetUpFieldMetaData ( const std::string  outname,
const std::vector< FieldDefinitionsSharedPtr > &  fielddefs,
const FieldMetaDataMap fieldmetadatamap 
)
protected

Definition at line 1285 of file FieldIO.cpp.

References ASSERTL0, GetFileEnding(), m_comm, Nektar::LibUtilities::PortablePath(), Nektar::LibUtilities::ReduceMax, and WriteMultiFldFileIDs().

Referenced by Write().

1289  {
1290  ASSERTL0(!outname.empty(), "Empty path given to SetUpFieldMetaData()");
1291 
1292  int nprocs = m_comm->GetSize();
1293  int rank = m_comm->GetRank();
1294 
1295  fs::path specPath (outname);
1296 
1297  // Compute number of elements on this process and share with other
1298  // processes. Also construct list of elements on this process from
1299  // available vector of field definitions.
1300  std::vector<unsigned int> elmtnums(nprocs,0);
1301  std::vector<unsigned int> idlist;
1302  int i;
1303  for (i = 0; i < fielddefs.size(); ++i)
1304  {
1305  elmtnums[rank] += fielddefs[i]->m_elementIDs.size();
1306  idlist.insert(idlist.end(), fielddefs[i]->m_elementIDs.begin(),
1307  fielddefs[i]->m_elementIDs.end());
1308  }
1309  m_comm->AllReduce(elmtnums,LibUtilities::ReduceMax);
1310 
1311  // Collate per-process element lists on root process to generate
1312  // the info file.
1313  if (rank == 0)
1314  {
1315  std::vector<std::vector<unsigned int> > ElementIDs(nprocs);
1316 
1317  // Populate the list of element ID lists from all processes
1318  ElementIDs[0] = idlist;
1319  for (i = 1; i < nprocs; ++i)
1320  {
1321  std::vector<unsigned int> tmp(elmtnums[i]);
1322  m_comm->Recv(i, tmp);
1323  ElementIDs[i] = tmp;
1324  }
1325 
1326  // Set up output names
1327  std::vector<std::string> filenames;
1328  for(int i = 0; i < nprocs; ++i)
1329  {
1330  boost::format pad("P%1$07d.%2$s");
1331  pad % i % GetFileEnding();
1332  filenames.push_back(pad.str());
1333  }
1334 
1335  // Write the Info.xml file
1336  string infofile = LibUtilities::PortablePath(
1337  specPath / fs::path("Info.xml"));
1338 
1339  cout << "Writing: " << specPath << endl;
1340  WriteMultiFldFileIDs(infofile, filenames, ElementIDs,
1341  fieldmetadatamap);
1342  }
1343  else
1344  {
1345  // Send this process's ID list to the root process
1346  m_comm->Send(0, idlist);
1347  }
1348 
1349  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:41
LibUtilities::CommSharedPtr m_comm
Communicator to use when writing parallel format.
Definition: FieldIO.h:191
void WriteMultiFldFileIDs(const std::string &outfile, const std::vector< std::string > fileNames, std::vector< std::vector< unsigned int > > &elementList, const FieldMetaDataMap &fieldinfomap=NullFieldMetaDataMap)
Definition: FieldIO.cpp:537
virtual std::string GetFileEnding() const
Definition: FieldIO.h:218
std::string Nektar::LibUtilities::FieldIO::SetUpOutput ( const std::string  outname)
protected

Definition at line 1192 of file FieldIO.cpp.

References ASSERTL0, GetFileEnding(), m_comm, m_sharedFilesystem, and Nektar::LibUtilities::PortablePath().

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

1193  {
1194  ASSERTL0(!outname.empty(), "Empty path given to SetUpOutput()");
1195 
1196  int nprocs = m_comm->GetSize();
1197  int rank = m_comm->GetRank();
1198 
1199  // Path to output: will be directory if parallel, normal file if
1200  // serial.
1201  fs::path specPath (outname);
1202  fs::path fulloutname;
1203 
1204  if (nprocs == 1)
1205  {
1206  fulloutname = specPath;
1207  }
1208  else
1209  {
1210  // Guess at filename that might belong to this process.
1211  boost::format pad("P%1$07d.%2$s");
1212  pad % m_comm->GetRank() % GetFileEnding();
1213 
1214  // Generate full path name
1215  fs::path poutfile(pad.str());
1216  fulloutname = specPath / poutfile;
1217  }
1218 
1219  // Remove any existing file which is in the way
1220  if (m_comm->RemoveExistingFiles())
1221  {
1222  if (m_sharedFilesystem)
1223  {
1224  // First, each process clears up its .fld file. This might
1225  // or might not be there (we might have changed numbers of
1226  // processors between runs, for example), but we can try
1227  // anyway.
1228  try
1229  {
1230  fs::remove_all(fulloutname);
1231  }
1232  catch (fs::filesystem_error& e)
1233  {
1234  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
1235  "Filesystem error: " + string(e.what()));
1236  }
1237  }
1238 
1239  m_comm->Block();
1240 
1241  // Now get rank 0 processor to tidy everything else up.
1242  if (rank == 0 || !m_sharedFilesystem)
1243  {
1244  try
1245  {
1246  fs::remove_all(specPath);
1247  }
1248  catch (fs::filesystem_error& e)
1249  {
1250  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
1251  "Filesystem error: " + string(e.what()));
1252  }
1253  }
1254 
1255  m_comm->Block();
1256  }
1257 
1258  // serial processing just add ending.
1259  if(nprocs == 1)
1260  {
1261  cout << "Writing: " << specPath << endl;
1262  return LibUtilities::PortablePath(specPath);
1263  }
1264 
1265  // Create the destination directory
1266  try
1267  {
1268  if (rank == 0 || !m_sharedFilesystem)
1269  {
1270  fs::create_directory(specPath);
1271  }
1272  }
1273  catch (fs::filesystem_error& e)
1274  {
1275  ASSERTL0(false, "Filesystem error: " + string(e.what()));
1276  }
1277 
1278  m_comm->Block();
1279 
1280  // Return the full path to the partition for this process
1281  return LibUtilities::PortablePath(fulloutname);
1282  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
bool m_sharedFilesystem
True if same filesystem accessible by all processes.
Definition: FieldIO.h:194
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:41
LibUtilities::CommSharedPtr m_comm
Communicator to use when writing parallel format.
Definition: FieldIO.h:191
virtual std::string GetFileEnding() const
Definition: FieldIO.h:218
void Nektar::LibUtilities::FieldIO::Write ( const std::string &  outFile,
std::vector< FieldDefinitionsSharedPtr > &  fielddefs,
std::vector< std::vector< NekDouble > > &  fielddata,
const FieldMetaDataMap fieldinfomap = NullFieldMetaDataMap 
)

Write data in FLD format.

Definition at line 160 of file FieldIO.cpp.

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

Referenced by main(), and Nektar::LibUtilities::Write().

164  {
165  // Check everything seems sensible
166  ASSERTL1(fielddefs.size() == fielddata.size(),
167  "Length of fielddefs and fielddata incompatible");
168  for (int f = 0; f < fielddefs.size(); ++f)
169  {
170  ASSERTL1(fielddata[f].size() > 0,
171  "Fielddata vector must contain at least one value.");
172 
173  ASSERTL1(fielddata[f].size() ==
174  fielddefs[f]->m_fields.size() *
175  CheckFieldDefinition(fielddefs[f]),
176  "Invalid size of fielddata vector.");
177  }
178 
179  // Prepare to write out data. In parallel, we must create directory
180  // and determine the full pathname to the file to write out.
181  // Any existing file/directory which is in the way is removed.
182  std::string filename = SetUpOutput(outFile);
183  if (m_comm->GetSize() > 1)
184  {
185  SetUpFieldMetaData(outFile, fielddefs, fieldmetadatamap);
186  }
187 
188  // Create the file (partition)
189  TiXmlDocument doc;
190  TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "utf-8", "");
191  doc.LinkEndChild(decl);
192 
193  TiXmlElement * root = new TiXmlElement("NEKTAR");
194  doc.LinkEndChild(root);
195 
196  AddInfoTag(root,fieldmetadatamap);
197 
198  for (int f = 0; f < fielddefs.size(); ++f)
199  {
200  //---------------------------------------------
201  // Write ELEMENTS
202  TiXmlElement * elemTag = new TiXmlElement("ELEMENTS");
203  root->LinkEndChild(elemTag);
204 
205  // Write FIELDS
206  std::string fieldsString;
207  {
208  std::stringstream fieldsStringStream;
209  bool first = true;
210  for (std::vector<int>::size_type i = 0; i
211  < fielddefs[f]->m_fields.size(); i++)
212  {
213  if (!first)
214  fieldsStringStream << ",";
215  fieldsStringStream << fielddefs[f]->m_fields[i];
216  first = false;
217  }
218  fieldsString = fieldsStringStream.str();
219  }
220  elemTag->SetAttribute("FIELDS", fieldsString);
221 
222  // Write SHAPE
223  std::string shapeString;
224  {
225  std::stringstream shapeStringStream;
226  shapeStringStream << ShapeTypeMap[fielddefs[f]->m_shapeType];
227  if(fielddefs[f]->m_numHomogeneousDir == 1)
228  {
229  shapeStringStream << "-HomogenousExp1D";
230  }
231  else if (fielddefs[f]->m_numHomogeneousDir == 2)
232  {
233  shapeStringStream << "-HomogenousExp2D";
234  }
235 
236  if (fielddefs[f]->m_homoStrips)
237  {
238  shapeStringStream << "-Strips";
239  }
240 
241  shapeString = shapeStringStream.str();
242  }
243  elemTag->SetAttribute("SHAPE", shapeString);
244 
245  // Write BASIS
246  std::string basisString;
247  {
248  std::stringstream basisStringStream;
249  bool first = true;
250  for (std::vector<BasisType>::size_type i = 0; i < fielddefs[f]->m_basis.size(); i++)
251  {
252  if (!first)
253  basisStringStream << ",";
254  basisStringStream
255  << BasisTypeMap[fielddefs[f]->m_basis[i]];
256  first = false;
257  }
258  basisString = basisStringStream.str();
259  }
260  elemTag->SetAttribute("BASIS", basisString);
261 
262  // Write homogeneuous length details
263  if(fielddefs[f]->m_numHomogeneousDir)
264  {
265  std::string homoLenString;
266  {
267  std::stringstream homoLenStringStream;
268  bool first = true;
269  for (int i = 0; i < fielddefs[f]->m_numHomogeneousDir; ++i)
270  {
271  if (!first)
272  homoLenStringStream << ",";
273  homoLenStringStream
274  << fielddefs[f]->m_homogeneousLengths[i];
275  first = false;
276  }
277  homoLenString = homoLenStringStream.str();
278  }
279  elemTag->SetAttribute("HOMOGENEOUSLENGTHS", homoLenString);
280  }
281 
282  // Write homogeneuous planes/lines details
283  if(fielddefs[f]->m_numHomogeneousDir)
284  {
285  if(fielddefs[f]->m_homogeneousYIDs.size() > 0)
286  {
287  std::string homoYIDsString;
288  {
289  std::stringstream homoYIDsStringStream;
290  bool first = true;
291  for(int i = 0; i < fielddefs[f]->m_homogeneousYIDs.size(); i++)
292  {
293  if (!first)
294  homoYIDsStringStream << ",";
295  homoYIDsStringStream << fielddefs[f]->m_homogeneousYIDs[i];
296  first = false;
297  }
298  homoYIDsString = homoYIDsStringStream.str();
299  }
300  elemTag->SetAttribute("HOMOGENEOUSYIDS", homoYIDsString);
301  }
302 
303  if(fielddefs[f]->m_homogeneousZIDs.size() > 0)
304  {
305  std::string homoZIDsString;
306  {
307  std::stringstream homoZIDsStringStream;
308  bool first = true;
309  for(int i = 0; i < fielddefs[f]->m_homogeneousZIDs.size(); i++)
310  {
311  if (!first)
312  homoZIDsStringStream << ",";
313  homoZIDsStringStream << fielddefs[f]->m_homogeneousZIDs[i];
314  first = false;
315  }
316  homoZIDsString = homoZIDsStringStream.str();
317  }
318  elemTag->SetAttribute("HOMOGENEOUSZIDS", homoZIDsString);
319  }
320 
321  if(fielddefs[f]->m_homogeneousSIDs.size() > 0)
322  {
323  std::string homoSIDsString;
324  {
325  std::stringstream homoSIDsStringStream;
326  bool first = true;
327  for(int i = 0; i < fielddefs[f]->m_homogeneousSIDs.size(); i++)
328  {
329  if (!first)
330  homoSIDsStringStream << ",";
331  homoSIDsStringStream << fielddefs[f]->m_homogeneousSIDs[i];
332  first = false;
333  }
334  homoSIDsString = homoSIDsStringStream.str();
335  }
336  elemTag->SetAttribute("HOMOGENEOUSSIDS", homoSIDsString);
337  }
338  }
339 
340  // Write NUMMODESPERDIR
341  std::string numModesString;
342  {
343  std::stringstream numModesStringStream;
344 
345  if (fielddefs[f]->m_uniOrder)
346  {
347  numModesStringStream << "UNIORDER:";
348  // Just dump single definition
349  bool first = true;
350  for (std::vector<int>::size_type i = 0; i
351  < fielddefs[f]->m_basis.size(); i++)
352  {
353  if (!first)
354  numModesStringStream << ",";
355  numModesStringStream << fielddefs[f]->m_numModes[i];
356  first = false;
357  }
358  }
359  else
360  {
361  numModesStringStream << "MIXORDER:";
362  bool first = true;
363  for (std::vector<int>::size_type i = 0; i
364  < fielddefs[f]->m_numModes.size(); i++)
365  {
366  if (!first)
367  numModesStringStream << ",";
368  numModesStringStream << fielddefs[f]->m_numModes[i];
369  first = false;
370  }
371  }
372 
373  numModesString = numModesStringStream.str();
374  }
375  elemTag->SetAttribute("NUMMODESPERDIR", numModesString);
376 
377  // Write ID
378  // Should ideally look at ways of compressing this stream
379  // if just sequential;
380  std::string idString;
381  {
382  std::stringstream idStringStream;
383  GenerateSeqString(fielddefs[f]->m_elementIDs,idString);
384  }
385  elemTag->SetAttribute("ID", idString);
386  elemTag->SetAttribute("COMPRESSED",
388 
389  // Add this information for future compatibility
390  // issues, for exmaple in case we end up using a 128
391  // bit machine.
392  elemTag->SetAttribute("BITSIZE",
394  std::string base64string;
396  fielddata[f], base64string),
397  "Failed to compress field data.");
398 
399  elemTag->LinkEndChild(new TiXmlText(base64string));
400 
401  }
402  doc.SaveFile(filename);
403  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
const char *const BasisTypeMap[]
Definition: Foundations.hpp:47
std::string SetUpOutput(const std::string outname)
Definition: FieldIO.cpp:1192
int CheckFieldDefinition(const FieldDefinitionsSharedPtr &fielddefs)
Definition: FieldIO.cpp:1355
const char *const ShapeTypeMap[]
Definition: ShapeType.hpp:66
void GenerateSeqString(const std::vector< unsigned int > &elmtids, std::string &idString)
Definition: FieldIO.cpp:1146
void AddInfoTag(TiXmlElement *root, const FieldMetaDataMap &fieldmetadatamap)
add information about provenance and fieldmetadata
Definition: FieldIO.cpp:1087
LibUtilities::CommSharedPtr m_comm
Communicator to use when writing parallel format.
Definition: FieldIO.h:191
int ZlibEncodeToBase64Str(std::vector< T > &in, std::string &out64)
Definition: CompressData.h:151
void SetUpFieldMetaData(const std::string outname, const std::vector< FieldDefinitionsSharedPtr > &fielddefs, const FieldMetaDataMap &fieldmetadatamap)
Definition: FieldIO.cpp:1285
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:218
void Nektar::LibUtilities::FieldIO::WriteMultiFldFileIDs ( const std::string &  outfile,
const std::vector< std::string >  fileNames,
std::vector< std::vector< unsigned int > > &  elementList,
const FieldMetaDataMap fieldinfomap = NullFieldMetaDataMap 
)

Definition at line 537 of file FieldIO.cpp.

References AddInfoTag(), ASSERTL0, and GenerateSeqString().

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

541  {
542  TiXmlDocument doc;
543  TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "utf-8", "");
544  doc.LinkEndChild(decl);
545 
546  ASSERTL0(fileNames.size() == elementList.size(),"Outfile names and list of elements ids does not match");
547 
548  TiXmlElement * root = new TiXmlElement("NEKTAR");
549  doc.LinkEndChild(root);
550 
551  AddInfoTag(root,fieldmetadatamap);
552 
553  for (int t = 0; t < fileNames.size(); ++t)
554  {
555  if(elementList[t].size())
556  {
557  TiXmlElement * elemIDs = new TiXmlElement("Partition");
558  root->LinkEndChild(elemIDs);
559 
560  elemIDs->SetAttribute("FileName",fileNames[t]);
561 
562  string IDstring;
563 
564  GenerateSeqString(elementList[t],IDstring);
565 
566  elemIDs->LinkEndChild(new TiXmlText(IDstring));
567  }
568  }
569 
570  doc.SaveFile(outFile);
571  }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
void GenerateSeqString(const std::vector< unsigned int > &elmtids, std::string &idString)
Definition: FieldIO.cpp:1146
void AddInfoTag(TiXmlElement *root, const FieldMetaDataMap &fieldmetadatamap)
add information about provenance and fieldmetadata
Definition: FieldIO.cpp:1087

Member Data Documentation

LibUtilities::CommSharedPtr Nektar::LibUtilities::FieldIO::m_comm
protected

Communicator to use when writing parallel format.

Definition at line 191 of file FieldIO.h.

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

bool Nektar::LibUtilities::FieldIO::m_sharedFilesystem
protected

True if same filesystem accessible by all processes.

Definition at line 194 of file FieldIO.h.

Referenced by SetUpOutput().