Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FieldIO.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: FieldIO.cpp
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: I/O routines relating to Fields
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 #include <boost/format.hpp>
37 #include <boost/date_time/posix_time/posix_time.hpp>
38 #include <boost/date_time/posix_time/posix_time_io.hpp>
39 #include <boost/asio/ip/host_name.hpp>
40 #include <boost/archive/iterators/base64_from_binary.hpp>
41 #include <boost/archive/iterators/binary_from_base64.hpp>
42 #include <boost/archive/iterators/transform_width.hpp>
43 #include <boost/iostreams/copy.hpp>
44 #include <boost/iostreams/filter/zlib.hpp>
45 #include <boost/iostreams/filtering_stream.hpp>
46 #include <boost/assign/list_of.hpp>
47 
53 
54 #include "zlib.h"
55 #include <set>
56 
57 #ifdef NEKTAR_USE_MPI
58 #include <mpi.h>
59 #endif
60 
61 // Buffer size for zlib compression/decompression
62 #define CHUNK 16384
63 
64 #ifndef NEKTAR_VERSION
65 #define NEKTAR_VERSION "Unknown"
66 #endif
67 
68 namespace ptime = boost::posix_time;
69 namespace ip = boost::asio::ip;
70 namespace berrc = boost::system::errc;
71 
72 namespace Nektar
73 {
74  namespace LibUtilities
75  {
76  /**
77  * This function allows for data to be written to an FLD file when a
78  * session and/or communicator is not instantiated. Typically used in
79  * utilities which do not take XML input and operate in serial only.
80  */
81  void Write( const std::string &outFile,
82  std::vector<FieldDefinitionsSharedPtr> &fielddefs,
83  std::vector<std::vector<NekDouble> > &fielddata,
84  const FieldMetaDataMap &fieldinfomap)
85  {
86 #ifdef NEKTAR_USE_MPI
87  int size;
88  int init;
89  MPI_Initialized(&init);
90 
91  // If MPI has been initialised we can check the number of processes
92  // and, if > 1, tell the user he should not be running this
93  // function in parallel. If it is not initialised, we do not
94  // initialise it here, and assume the user knows what they are
95  // doing.
96  if (init)
97  {
98  MPI_Comm_size( MPI_COMM_WORLD, &size );
99  ASSERTL0(size == 1,
100  "This static function is not available in parallel. Please"
101  "instantiate a FieldIO object for parallel use.");
102  }
103 #endif
104  CommSharedPtr c = GetCommFactory().CreateInstance("Serial", 0, 0);
105  FieldIO f(c);
106  f.Write(outFile, fielddefs, fielddata, fieldinfomap);
107  }
108 
109 
110  /**
111  * This function allows for data to be imported from an FLD file when
112  * a session and/or communicator is not instantiated. Typically used in
113  * utilities which only operate in serial.
114  */
116  const std::string& infilename,
117  std::vector<FieldDefinitionsSharedPtr> &fielddefs,
118  std::vector<std::vector<NekDouble> > &fielddata,
119  FieldMetaDataMap &fieldinfomap,
120  const Array<OneD, int> ElementiDs)
121  {
122 #ifdef NEKTAR_USE_MPI
123  int size;
124  int init;
125  MPI_Initialized(&init);
126 
127  // If MPI has been initialised we can check the number of processes
128  // and, if > 1, tell the user he should not be running this
129  // function in parallel. If it is not initialised, we do not
130  // initialise it here, and assume the user knows what they are
131  // doing.
132  if (init)
133  {
134  MPI_Comm_size( MPI_COMM_WORLD, &size );
135  ASSERTL0(size == 1,
136  "This static function is not available in parallel. Please"
137  "instantiate a FieldIO object for parallel use.");
138  }
139 #endif
140  CommSharedPtr c = GetCommFactory().CreateInstance("Serial", 0, 0);
141  FieldIO f(c);
142  f.Import(infilename, fielddefs, fielddata, fieldinfomap, ElementiDs);
143  }
144 
145 
146  /**
147  *
148  */
150  bool sharedFilesystem) :
151  m_comm(pComm),
152  m_sharedFilesystem(sharedFilesystem)
153  {
154  }
155 
156 
157  /**
158  *
159  */
160  void FieldIO::Write(const std::string &outFile,
161  std::vector<FieldDefinitionsSharedPtr> &fielddefs,
162  std::vector<std::vector<NekDouble> > &fielddata,
163  const FieldMetaDataMap &fieldmetadatamap)
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  SetUpFieldMetaData(outFile, fielddefs, fieldmetadatamap);
184 
185  // Create the file (partition)
186  TiXmlDocument doc;
187  TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "utf-8", "");
188  doc.LinkEndChild(decl);
189 
190  TiXmlElement * root = new TiXmlElement("NEKTAR");
191  doc.LinkEndChild(root);
192 
193  AddInfoTag(root,fieldmetadatamap);
194 
195  for (int f = 0; f < fielddefs.size(); ++f)
196  {
197  //---------------------------------------------
198  // Write ELEMENTS
199  TiXmlElement * elemTag = new TiXmlElement("ELEMENTS");
200  root->LinkEndChild(elemTag);
201 
202  // Write FIELDS
203  std::string fieldsString;
204  {
205  std::stringstream fieldsStringStream;
206  bool first = true;
207  for (std::vector<int>::size_type i = 0; i
208  < fielddefs[f]->m_fields.size(); i++)
209  {
210  if (!first)
211  fieldsStringStream << ",";
212  fieldsStringStream << fielddefs[f]->m_fields[i];
213  first = false;
214  }
215  fieldsString = fieldsStringStream.str();
216  }
217  elemTag->SetAttribute("FIELDS", fieldsString);
218 
219  // Write SHAPE
220  std::string shapeString;
221  {
222  std::stringstream shapeStringStream;
223  shapeStringStream << ShapeTypeMap[fielddefs[f]->m_shapeType];
224  if(fielddefs[f]->m_numHomogeneousDir == 1)
225  {
226  shapeStringStream << "-HomogenousExp1D";
227  }
228  else if (fielddefs[f]->m_numHomogeneousDir == 2)
229  {
230  shapeStringStream << "-HomogenousExp2D";
231  }
232 
233  if (fielddefs[f]->m_homoStrips)
234  {
235  shapeStringStream << "-Strips";
236  }
237 
238  shapeString = shapeStringStream.str();
239  }
240  elemTag->SetAttribute("SHAPE", shapeString);
241 
242  // Write BASIS
243  std::string basisString;
244  {
245  std::stringstream basisStringStream;
246  bool first = true;
247  for (std::vector<BasisType>::size_type i = 0; i < fielddefs[f]->m_basis.size(); i++)
248  {
249  if (!first)
250  basisStringStream << ",";
251  basisStringStream
252  << BasisTypeMap[fielddefs[f]->m_basis[i]];
253  first = false;
254  }
255  basisString = basisStringStream.str();
256  }
257  elemTag->SetAttribute("BASIS", basisString);
258 
259  // Write homogeneuous length details
260  if(fielddefs[f]->m_numHomogeneousDir)
261  {
262  std::string homoLenString;
263  {
264  std::stringstream homoLenStringStream;
265  bool first = true;
266  for (int i = 0; i < fielddefs[f]->m_numHomogeneousDir; ++i)
267  {
268  if (!first)
269  homoLenStringStream << ",";
270  homoLenStringStream
271  << fielddefs[f]->m_homogeneousLengths[i];
272  first = false;
273  }
274  homoLenString = homoLenStringStream.str();
275  }
276  elemTag->SetAttribute("HOMOGENEOUSLENGTHS", homoLenString);
277  }
278 
279  // Write homogeneuous planes/lines details
280  if(fielddefs[f]->m_numHomogeneousDir)
281  {
282  if(fielddefs[f]->m_homogeneousYIDs.size() > 0)
283  {
284  std::string homoYIDsString;
285  {
286  std::stringstream homoYIDsStringStream;
287  bool first = true;
288  for(int i = 0; i < fielddefs[f]->m_homogeneousYIDs.size(); i++)
289  {
290  if (!first)
291  homoYIDsStringStream << ",";
292  homoYIDsStringStream << fielddefs[f]->m_homogeneousYIDs[i];
293  first = false;
294  }
295  homoYIDsString = homoYIDsStringStream.str();
296  }
297  elemTag->SetAttribute("HOMOGENEOUSYIDS", homoYIDsString);
298  }
299 
300  if(fielddefs[f]->m_homogeneousZIDs.size() > 0)
301  {
302  std::string homoZIDsString;
303  {
304  std::stringstream homoZIDsStringStream;
305  bool first = true;
306  for(int i = 0; i < fielddefs[f]->m_homogeneousZIDs.size(); i++)
307  {
308  if (!first)
309  homoZIDsStringStream << ",";
310  homoZIDsStringStream << fielddefs[f]->m_homogeneousZIDs[i];
311  first = false;
312  }
313  homoZIDsString = homoZIDsStringStream.str();
314  }
315  elemTag->SetAttribute("HOMOGENEOUSZIDS", homoZIDsString);
316  }
317 
318  if(fielddefs[f]->m_homogeneousSIDs.size() > 0)
319  {
320  std::string homoSIDsString;
321  {
322  std::stringstream homoSIDsStringStream;
323  bool first = true;
324  for(int i = 0; i < fielddefs[f]->m_homogeneousSIDs.size(); i++)
325  {
326  if (!first)
327  homoSIDsStringStream << ",";
328  homoSIDsStringStream << fielddefs[f]->m_homogeneousSIDs[i];
329  first = false;
330  }
331  homoSIDsString = homoSIDsStringStream.str();
332  }
333  elemTag->SetAttribute("HOMOGENEOUSSIDS", homoSIDsString);
334  }
335  }
336 
337  // Write NUMMODESPERDIR
338  std::string numModesString;
339  {
340  std::stringstream numModesStringStream;
341 
342  if (fielddefs[f]->m_uniOrder)
343  {
344  numModesStringStream << "UNIORDER:";
345  // Just dump single definition
346  bool first = true;
347  for (std::vector<int>::size_type i = 0; i
348  < fielddefs[f]->m_basis.size(); i++)
349  {
350  if (!first)
351  numModesStringStream << ",";
352  numModesStringStream << fielddefs[f]->m_numModes[i];
353  first = false;
354  }
355  }
356  else
357  {
358  numModesStringStream << "MIXORDER:";
359  bool first = true;
360  for (std::vector<int>::size_type i = 0; i
361  < fielddefs[f]->m_numModes.size(); i++)
362  {
363  if (!first)
364  numModesStringStream << ",";
365  numModesStringStream << fielddefs[f]->m_numModes[i];
366  first = false;
367  }
368  }
369 
370  numModesString = numModesStringStream.str();
371  }
372  elemTag->SetAttribute("NUMMODESPERDIR", numModesString);
373 
374  // Write ID
375  // Should ideally look at ways of compressing this stream
376  // if just sequential;
377  std::string idString;
378  {
379  std::stringstream idStringStream;
380  GenerateSeqString(fielddefs[f]->m_elementIDs,idString);
381  }
382  elemTag->SetAttribute("ID", idString);
383  elemTag->SetAttribute("COMPRESSED",
385 
386  // Add this information for future compatibility
387  // issues, for exmaple in case we end up using a 128
388  // bit machine.
389  elemTag->SetAttribute("BITSIZE",
391  std::string base64string;
393  fielddata[f], base64string),
394  "Failed to compress field data.");
395 
396  elemTag->LinkEndChild(new TiXmlText(base64string));
397 
398  }
399  doc.SaveFile(filename);
400  }
401 
402 
403  /**
404  *
405  */
406  void FieldIO::Import(const std::string& infilename,
407  std::vector<FieldDefinitionsSharedPtr> &fielddefs,
408  std::vector<std::vector<NekDouble> > &fielddata,
409  FieldMetaDataMap &fieldmetadatamap,
410  const Array<OneD, int> ElementIDs)
411  {
412 
413  std::string infile = infilename;
414 
415  fs::path pinfilename(infilename);
416 
417  if(fs::is_directory(pinfilename)) // check to see that infile is a directory
418  {
419  fs::path infofile("Info.xml");
420  fs::path fullpath = pinfilename / infofile;
421  infile = PortablePath(fullpath);
422 
423  std::vector<std::string> filenames;
424  std::vector<std::vector<unsigned int> > elementIDs_OnPartitions;
425 
426 
427  ImportMultiFldFileIDs(infile,filenames, elementIDs_OnPartitions,
428  fieldmetadatamap);
429 
430  // Load metadata
431  ImportFieldMetaData(infile,fieldmetadatamap);
432 
433  if(ElementIDs == NullInt1DArray) //load all fields
434  {
435  for(int i = 0; i < filenames.size(); ++i)
436  {
437  fs::path pfilename(filenames[i]);
438  fullpath = pinfilename / pfilename;
439  string fname = PortablePath(fullpath);
440 
441  TiXmlDocument doc1(fname);
442  bool loadOkay1 = doc1.LoadFile();
443 
444  std::stringstream errstr;
445  errstr << "Unable to load file: " << fname << std::endl;
446  errstr << "Reason: " << doc1.ErrorDesc() << std::endl;
447  errstr << "Position: Line " << doc1.ErrorRow() << ", Column " << doc1.ErrorCol() << std::endl;
448  ASSERTL0(loadOkay1, errstr.str());
449 
450  ImportFieldDefs(doc1, fielddefs, false);
451  if(fielddata != NullVectorNekDoubleVector)
452  {
453  ImportFieldData(doc1, fielddefs, fielddata);
454  }
455  }
456 
457  }
458  else // only load relevant partitions
459  {
460  int i,j;
461  map<int,vector<int> > FileIDs;
462  map<int,vector<int> >::iterator it;
463  set<int> LoadFile;
464 
465  for(i = 0; i < elementIDs_OnPartitions.size(); ++i)
466  {
467  for(j = 0; j < elementIDs_OnPartitions[i].size(); ++j)
468  {
469  FileIDs[elementIDs_OnPartitions[i][j]].push_back(i);
470  }
471  }
472 
473  for(i = 0; i < ElementIDs.num_elements(); ++i)
474  {
475  it = FileIDs.find(ElementIDs[i]);
476  if (it != FileIDs.end())
477  {
478  for (j = 0; j < it->second.size(); ++j)
479  {
480  LoadFile.insert(it->second[j]);
481  }
482  }
483  }
484 
485  set<int>::iterator iter;
486  for(iter = LoadFile.begin(); iter != LoadFile.end(); ++iter)
487  {
488  fs::path pfilename(filenames[*iter]);
489  fullpath = pinfilename / pfilename;
490  string fname = PortablePath(fullpath);
491  TiXmlDocument doc1(fname);
492  bool loadOkay1 = doc1.LoadFile();
493 
494  std::stringstream errstr;
495  errstr << "Unable to load file: " << fname << std::endl;
496  errstr << "Reason: " << doc1.ErrorDesc() << std::endl;
497  errstr << "Position: Line " << doc1.ErrorRow() << ", Column " << doc1.ErrorCol() << std::endl;
498  ASSERTL0(loadOkay1, errstr.str());
499 
500  ImportFieldDefs(doc1, fielddefs, false);
501  if(fielddata != NullVectorNekDoubleVector)
502  {
503  ImportFieldData(doc1, fielddefs, fielddata);
504  }
505  }
506  }
507  }
508  else // serial format case
509  {
510 
511  TiXmlDocument doc(infile);
512  bool loadOkay = doc.LoadFile();
513 
514  std::stringstream errstr;
515  errstr << "Unable to load file: " << infile << std::endl;
516  errstr << "Reason: " << doc.ErrorDesc() << std::endl;
517  errstr << "Position: Line " << doc.ErrorRow() << ", Column " <<
518  doc.ErrorCol() << std::endl;
519  ASSERTL0(loadOkay, errstr.str());
520 
521  ImportFieldMetaData(doc,fieldmetadatamap);
522  ImportFieldDefs(doc, fielddefs, false);
523  if(fielddata != NullVectorNekDoubleVector)
524  {
525  ImportFieldData(doc, fielddefs, fielddata);
526  }
527  }
528  }
529 
530 
531  /**
532  *
533  */
534  void FieldIO::WriteMultiFldFileIDs(const std::string &outFile,
535  const std::vector<std::string> fileNames,
536  std::vector<std::vector<unsigned int> > &elementList,
537  const FieldMetaDataMap &fieldmetadatamap)
538  {
539  TiXmlDocument doc;
540  TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "utf-8", "");
541  doc.LinkEndChild(decl);
542 
543  ASSERTL0(fileNames.size() == elementList.size(),"Outfile names and list of elements ids does not match");
544 
545  TiXmlElement * root = new TiXmlElement("NEKTAR");
546  doc.LinkEndChild(root);
547 
548  AddInfoTag(root,fieldmetadatamap);
549 
550  for (int t = 0; t < fileNames.size(); ++t)
551  {
552  if(elementList[t].size())
553  {
554  TiXmlElement * elemIDs = new TiXmlElement("Partition");
555  root->LinkEndChild(elemIDs);
556 
557  elemIDs->SetAttribute("FileName",fileNames[t]);
558 
559  string IDstring;
560 
561  GenerateSeqString(elementList[t],IDstring);
562 
563  elemIDs->LinkEndChild(new TiXmlText(IDstring));
564  }
565  }
566 
567  doc.SaveFile(outFile);
568  }
569 
570 
571  /**
572  *
573  */
574  void FieldIO::ImportMultiFldFileIDs(const std::string &inFile,
575  std::vector<std::string> &fileNames,
576  std::vector<std::vector<unsigned int> > &elementList,
577  FieldMetaDataMap &fieldmetadatamap)
578  {
579  TiXmlDocument doc(inFile);
580  bool loadOkay = doc.LoadFile();
581 
582 
583  std::stringstream errstr;
584  errstr << "Unable to load file: " << inFile<< std::endl;
585  errstr << "Reason: " << doc.ErrorDesc() << std::endl;
586  errstr << "Position: Line " << doc.ErrorRow() << ", Column " << doc.ErrorCol() << std::endl;
587  ASSERTL0(loadOkay, errstr.str());
588 
589  // Handle on XML document
590  TiXmlHandle docHandle(&doc);
591 
592  // Retrieve main NEKTAR tag - XML specification states one
593  // top-level element tag per file.
594  TiXmlElement* master = doc.FirstChildElement("NEKTAR");
595  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
596 
597  // Partition element tag name
598  std::string strPartition = "Partition";
599 
600  // First attempt to get the first Partition element
601  TiXmlElement* fldfileIDs = master->FirstChildElement(strPartition.c_str());
602  if (!fldfileIDs)
603  {
604  // If this files try previous name
605  strPartition = "MultipleFldFiles";
606  fldfileIDs = master->FirstChildElement("MultipleFldFiles");
607  }
608  ASSERTL0(fldfileIDs,
609  "Unable to find 'Partition' or 'MultipleFldFiles' tag "
610  "within nektar tag.");
611 
612  while (fldfileIDs)
613  {
614  // Read file name of partition file
615  const char *attr = fldfileIDs->Attribute("FileName");
616  ASSERTL0(attr, "'FileName' not provided as an attribute of '"
617  + strPartition + "' tag.");
618  fileNames.push_back(std::string(attr));
619 
620  const char* elementIDs = fldfileIDs->GetText();
621  ASSERTL0(elementIDs, "Element IDs not specified.");
622 
623  std::string elementIDsStr(elementIDs);
624 
625  std::vector<unsigned int> idvec;
626  ParseUtils::GenerateSeqVector(elementIDsStr.c_str(),idvec);
627 
628  elementList.push_back(idvec);
629 
630  fldfileIDs = fldfileIDs->NextSiblingElement(strPartition.c_str());
631  }
632  }
633 
634  void FieldIO::ImportFieldMetaData(std::string filename,
635  FieldMetaDataMap &fieldmetadatamap)
636  {
637  TiXmlDocument doc(filename);
638  bool loadOkay = doc.LoadFile();
639 
640  std::stringstream errstr;
641  errstr << "Unable to load file: " << filename << std::endl;
642  errstr << "Reason: " << doc.ErrorDesc() << std::endl;
643  errstr << "Position: Line " << doc.ErrorRow() << ", Column " << doc.ErrorCol() << std::endl;
644  ASSERTL0(loadOkay, errstr.str());
645 
646  ImportFieldMetaData(doc,fieldmetadatamap);
647  }
648 
649 
650  void FieldIO::ImportFieldMetaData(TiXmlDocument &doc,
651  FieldMetaDataMap &fieldmetadatamap)
652  {
653 
654  TiXmlHandle docHandle(&doc);
655  TiXmlElement* master = 0; // Master tag within which all data is contained.
656  TiXmlElement* metadata = 0;
657 
658  master = doc.FirstChildElement("NEKTAR");
659  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
660  std::string strLoop = "NEKTAR";
661 
662  // Retain original metadata structure for backwards compatibility
663  // TODO: Remove old metadata format
664  metadata = master->FirstChildElement("FIELDMETADATA");
665  if(metadata)
666  {
667  TiXmlElement *param = metadata->FirstChildElement("P");
668 
669  while (param)
670  {
671  TiXmlAttribute *paramAttr = param->FirstAttribute();
672  std::string attrName(paramAttr->Name());
673  std::string paramString;
674 
675  if(attrName == "PARAM")
676  {
677  paramString.insert(0,paramAttr->Value());
678  }
679  else
680  {
681  ASSERTL0(false,"PARAM not provided as an attribute in FIELDMETADATA section");
682  }
683 
684  // Now read body of param
685  std::string paramBodyStr;
686 
687  TiXmlNode *paramBody = param->FirstChild();
688 
689  paramBodyStr += paramBody->ToText()->Value();
690 
691  fieldmetadatamap[paramString] = paramBodyStr;
692  param = param->NextSiblingElement("P");
693  }
694  }
695 
696  // New metadata format
697  metadata = master->FirstChildElement("Metadata");
698  if(metadata)
699  {
700  TiXmlElement *param = metadata->FirstChildElement();
701 
702  while (param)
703  {
704  std::string paramString = param->Value();
705  if (paramString != "Provenance")
706  {
707  // Now read body of param
708  TiXmlNode *paramBody = param->FirstChild();
709  std::string paramBodyStr = paramBody->ToText()->Value();
710 
711  fieldmetadatamap[paramString] = paramBodyStr;
712  }
713  param = param->NextSiblingElement();
714  }
715  }
716 
717  }
718 
719 
720  /**
721  * The bool decides if the FieldDefs are in <EXPANSIONS> or in <NEKTAR>.
722  */
723  void FieldIO::ImportFieldDefs(TiXmlDocument &doc, std::vector<FieldDefinitionsSharedPtr> &fielddefs,
724  bool expChild)
725  {
726  TiXmlHandle docHandle(&doc);
727  TiXmlElement* master = NULL; // Master tag within which all data is contained.
728 
729  master = doc.FirstChildElement("NEKTAR");
730  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
731  std::string strLoop = "NEKTAR";
732  TiXmlElement* loopXml = master;
733 
734  TiXmlElement *expansionTypes;
735  if(expChild)
736  {
737  expansionTypes = master->FirstChildElement("EXPANSIONS");
738  ASSERTL0(expansionTypes, "Unable to find EXPANSIONS tag in file.");
739  loopXml = expansionTypes;
740  strLoop = "EXPANSIONS";
741  }
742 
743  // Loop through all nektar tags, finding all of the element tags.
744  while (loopXml)
745  {
746  TiXmlElement* element = loopXml->FirstChildElement("ELEMENTS");
747  ASSERTL0(element, "Unable to find ELEMENTS tag within nektar tag.");
748 
749  while (element)
750  {
751  // Extract the attributes.
752  std::string idString;
753  std::string shapeString;
754  std::string basisString;
755  std::string homoLengthsString;
756  std::string homoSIDsString;
757  std::string homoZIDsString;
758  std::string homoYIDsString;
759  std::string numModesString;
760  std::string numPointsString;
761  std::string fieldsString;
762  std::string pointsString;
763  bool pointDef = false;
764  bool numPointDef = false;
765  TiXmlAttribute *attr = element->FirstAttribute();
766  while (attr)
767  {
768  std::string attrName(attr->Name());
769  if (attrName == "FIELDS")
770  {
771  fieldsString.insert(0, attr->Value());
772  }
773  else if (attrName == "SHAPE")
774  {
775  shapeString.insert(0, attr->Value());
776  }
777  else if (attrName == "BASIS")
778  {
779  basisString.insert(0, attr->Value());
780  }
781  else if (attrName == "HOMOGENEOUSLENGTHS")
782  {
783  homoLengthsString.insert(0,attr->Value());
784  }
785  else if (attrName == "HOMOGENEOUSSIDS")
786  {
787  homoSIDsString.insert(0,attr->Value());
788  }
789  else if (attrName == "HOMOGENEOUSZIDS")
790  {
791  homoZIDsString.insert(0,attr->Value());
792  }
793  else if (attrName == "HOMOGENEOUSYIDS")
794  {
795  homoYIDsString.insert(0,attr->Value());
796  }
797  else if (attrName == "NUMMODESPERDIR")
798  {
799  numModesString.insert(0, attr->Value());
800  }
801  else if (attrName == "ID")
802  {
803  idString.insert(0, attr->Value());
804  }
805  else if (attrName == "POINTSTYPE")
806  {
807  pointsString.insert(0, attr->Value());
808  pointDef = true;
809  }
810  else if (attrName == "NUMPOINTSPERDIR")
811  {
812  numPointsString.insert(0, attr->Value());
813  numPointDef = true;
814  }
815  else if (attrName == "COMPRESSED")
816  {
817  if(!boost::iequals(attr->Value(),
819  {
820  WARNINGL0(false, "Compressed formats do not "
821  "match. Expected: "
823  + " but got "+ string(attr->Value()));
824  }
825  }
826  else if (attrName =="BITSIZE")
827  {
828  // This information is for future
829  // compatibility issues, for exmaple in
830  // case we end up using a 128 bit machine.
831  // Currently just do nothing
832  }
833  else
834  {
835  std::string errstr("Unknown attribute: ");
836  errstr += attrName;
837  ASSERTL1(false, errstr.c_str());
838  }
839 
840  // Get the next attribute.
841  attr = attr->Next();
842  }
843 
844 
845  // Check to see if using strips formulation
846  bool strips = false;
847  if(shapeString.find("Strips")!=string::npos)
848  {
849  strips = true;
850  }
851 
852  // Check to see if homogeneous expansion and if so
853  // strip down the shapeString definition
854  int numHomoDir = 0;
855  size_t loc;
856  //---> This finds the first location of 'n'!
857  if((loc = shapeString.find_first_of("-"))!=string::npos)
858  {
859  if(shapeString.find("Exp1D")!=string::npos)
860  {
861  numHomoDir = 1;
862  }
863  else // HomogeneousExp1D
864  {
865  numHomoDir = 2;
866  }
867 
868  shapeString.erase(loc,shapeString.length());
869  }
870 
871  // Reconstruct the fielddefs.
872  std::vector<unsigned int> elementIds;
873  {
874  bool valid = ParseUtils::GenerateSeqVector(idString.c_str(), elementIds);
875  ASSERTL0(valid, "Unable to correctly parse the element ids.");
876  }
877 
878  // Get the geometrical shape
879  ShapeType shape;
880  bool valid = false;
881  for (unsigned int j = 0; j < SIZE_ShapeType; j++)
882  {
883  if (ShapeTypeMap[j] == shapeString)
884  {
885  shape = (ShapeType) j;
886  valid = true;
887  break;
888  }
889  }
890 
891  ASSERTL0(valid, std::string("Unable to correctly parse the shape type: ").append(shapeString).c_str());
892 
893  // Get the basis
894  std::vector<std::string> basisStrings;
895  std::vector<BasisType> basis;
896  valid = ParseUtils::GenerateOrderedStringVector(basisString.c_str(), basisStrings);
897  ASSERTL0(valid, "Unable to correctly parse the basis types.");
898  for (std::vector<std::string>::size_type i = 0; i < basisStrings.size(); i++)
899  {
900  valid = false;
901  for (unsigned int j = 0; j < SIZE_BasisType; j++)
902  {
903  if (BasisTypeMap[j] == basisStrings[i])
904  {
905  basis.push_back((BasisType) j);
906  valid = true;
907  break;
908  }
909  }
910  ASSERTL0(valid, std::string("Unable to correctly parse the basis type: ").append(basisStrings[i]).c_str());
911  }
912 
913  // Get homoLengths
914  std::vector<NekDouble> homoLengths;
915  if(numHomoDir)
916  {
917  valid = ParseUtils::GenerateUnOrderedVector(homoLengthsString.c_str(), homoLengths);
918  ASSERTL0(valid, "Unable to correctly parse the number of homogeneous lengths.");
919  }
920 
921  // Get Homogeneous strips IDs
922  std::vector<unsigned int> homoSIDs;
923  if(strips)
924  {
925  valid = ParseUtils::GenerateSeqVector(homoSIDsString.c_str(), homoSIDs);
926  ASSERTL0(valid, "Unable to correctly parse homogeneous strips IDs.");
927  }
928  // Get Homogeneous points IDs
929  std::vector<unsigned int> homoZIDs;
930  std::vector<unsigned int> homoYIDs;
931 
932  if(numHomoDir == 1)
933  {
934  valid = ParseUtils::GenerateSeqVector(homoZIDsString.c_str(), homoZIDs);
935  ASSERTL0(valid, "Unable to correctly parse homogeneous planes IDs.");
936  }
937 
938  if(numHomoDir == 2)
939  {
940  valid = ParseUtils::GenerateSeqVector(homoZIDsString.c_str(), homoZIDs);
941  ASSERTL0(valid, "Unable to correctly parse homogeneous lines IDs in z-direction.");
942  valid = ParseUtils::GenerateSeqVector(homoYIDsString.c_str(), homoYIDs);
943  ASSERTL0(valid, "Unable to correctly parse homogeneous lines IDs in y-direction.");
944  }
945 
946 
947  // Get points type
948  std::vector<PointsType> points;
949 
950  if(pointDef)
951  {
952  std::vector<std::string> pointsStrings;
953  valid = ParseUtils::GenerateOrderedStringVector(pointsString.c_str(), pointsStrings);
954  ASSERTL0(valid, "Unable to correctly parse the points types.");
955  for (std::vector<std::string>::size_type i = 0; i < pointsStrings.size(); i++)
956  {
957  valid = false;
958  for (unsigned int j = 0; j < SIZE_PointsType; j++)
959  {
960  if (kPointsTypeStr[j] == pointsStrings[i])
961  {
962  points.push_back((PointsType) j);
963  valid = true;
964  break;
965  }
966  }
967 
968  ASSERTL0(valid, std::string("Unable to correctly parse the points type: ").append(pointsStrings[i]).c_str());
969  }
970  }
971 
972  // Get numModes
973  std::vector<unsigned int> numModes;
974  bool UniOrder = false;
975 
976  if(strstr(numModesString.c_str(),"UNIORDER:"))
977  {
978  UniOrder = true;
979  }
980 
981  valid = ParseUtils::GenerateOrderedVector(numModesString.c_str()+9, numModes);
982  ASSERTL0(valid, "Unable to correctly parse the number of modes.");
983 
984  // Get numPoints
985  std::vector<unsigned int> numPoints;
986  if(numPointDef)
987  {
988  valid = ParseUtils::GenerateOrderedVector(numPointsString.c_str(), numPoints);
989  ASSERTL0(valid, "Unable to correctly parse the number of points.");
990  }
991 
992  // Get fields names
993  std::vector<std::string> Fields;
994  valid = ParseUtils::GenerateOrderedStringVector(fieldsString.c_str(), Fields);
995  ASSERTL0(valid, "Unable to correctly parse the number of fields.");
996 
997  FieldDefinitionsSharedPtr fielddef =
999  elementIds, basis, UniOrder, numModes, Fields, numHomoDir,
1000  homoLengths, strips, homoSIDs, homoZIDs, homoYIDs,
1001  points, pointDef, numPoints, numPointDef);
1002 
1003  fielddefs.push_back(fielddef);
1004 
1005  element = element->NextSiblingElement("ELEMENTS");
1006  }
1007  loopXml = loopXml->NextSiblingElement(strLoop);
1008  }
1009  }
1010 
1011 
1012  /**
1013  *
1014  */
1015  void FieldIO::ImportFieldData(TiXmlDocument &doc, const std::vector<FieldDefinitionsSharedPtr> &fielddefs, std::vector<std::vector<NekDouble> > &fielddata)
1016  {
1017  int cntdumps = 0;
1018 
1019  TiXmlHandle docHandle(&doc);
1020  TiXmlElement* master = NULL; // Master tag within which all data is contained.
1021 
1022  master = doc.FirstChildElement("NEKTAR");
1023  ASSERTL0(master, "Unable to find NEKTAR tag in file.");
1024 
1025  // Loop through all nektar tags, finding all of the element tags.
1026  while (master)
1027  {
1028  TiXmlElement* element = master->FirstChildElement("ELEMENTS");
1029  ASSERTL0(element, "Unable to find ELEMENTS tag within nektar tag.");
1030  while (element)
1031  {
1032  // Extract the body, which the "data".
1033  TiXmlNode* elementChild = element->FirstChild();
1034  ASSERTL0(elementChild, "Unable to extract the data from the element tag.");
1035  std::string elementStr;
1036  while(elementChild)
1037  {
1038  if (elementChild->Type() == TiXmlNode::TINYXML_TEXT)
1039  {
1040  elementStr += elementChild->ToText()->ValueStr();
1041  }
1042  elementChild = elementChild->NextSibling();
1043  }
1044 
1045  std::vector<NekDouble> elementFieldData;
1046  // Convert from base64 to binary.
1047 
1048  const char *CompressStr = element->Attribute("COMPRESSED");
1049  if(CompressStr)
1050  {
1051  if(!boost::iequals(CompressStr,
1053  {
1054  WARNINGL0(false, "Compressed formats do not match. "
1055  "Expected: "
1057  + " but got "+ string(CompressStr));
1058  }
1059  }
1060 
1062  elementStr,
1063  elementFieldData),
1064  "Failed to decompress field data.");
1065 
1066 
1067  fielddata.push_back(elementFieldData);
1068 
1069  int datasize = CheckFieldDefinition(fielddefs[cntdumps]);
1070  ASSERTL0(fielddata[cntdumps].size() == datasize*fielddefs[cntdumps]->m_fields.size(),"Input data is not the same length as header infoarmation");
1071 
1072  cntdumps++;
1073 
1074  element = element->NextSiblingElement("ELEMENTS");
1075  }
1076  master = master->NextSiblingElement("NEKTAR");
1077  }
1078  }
1079 
1080 
1081  /**
1082  * \brief add information about provenance and fieldmetadata
1083  */
1084  void FieldIO::AddInfoTag(TiXmlElement * root,
1085  const FieldMetaDataMap &fieldmetadatamap)
1086  {
1087  FieldMetaDataMap ProvenanceMap;
1088 
1089  // Nektar++ release version from VERSION file
1090  ProvenanceMap["NektarVersion"] = string(NEKTAR_VERSION);
1091 
1092  // Date/time stamp
1093  ptime::time_facet *facet = new ptime::time_facet("%d-%b-%Y %H:%M:%S");
1094  std::stringstream wss;
1095  wss.imbue(locale(wss.getloc(), facet));
1096  wss << ptime::second_clock::local_time();
1097  ProvenanceMap["Timestamp"] = wss.str();
1098 
1099  // Hostname
1100  boost::system::error_code ec;
1101  ProvenanceMap["Hostname"] = ip::host_name(ec);
1102 
1103  // Git information
1104  // If built from a distributed package, do not include this
1105  if (NekConstants::kGitSha1 != "GITDIR-NOTFOUND")
1106  {
1107  ProvenanceMap["GitSHA1"] = NekConstants::kGitSha1;
1108  ProvenanceMap["GitBranch"] = NekConstants::kGitBranch;
1109  }
1110 
1111  TiXmlElement * infoTag = new TiXmlElement("Metadata");
1112  root->LinkEndChild(infoTag);
1113 
1114  TiXmlElement * v;
1115  FieldMetaDataMap::const_iterator infoit;
1116 
1117  TiXmlElement * provTag = new TiXmlElement("Provenance");
1118  infoTag->LinkEndChild(provTag);
1119  for (infoit = ProvenanceMap.begin(); infoit != ProvenanceMap.end(); ++infoit)
1120  {
1121  v = new TiXmlElement( (infoit->first).c_str() );
1122  v->LinkEndChild(new TiXmlText((infoit->second).c_str()));
1123  provTag->LinkEndChild(v);
1124  }
1125 
1126  //---------------------------------------------
1127  // write field info section
1128  if(fieldmetadatamap != NullFieldMetaDataMap)
1129  {
1130  for(infoit = fieldmetadatamap.begin(); infoit != fieldmetadatamap.end(); ++infoit)
1131  {
1132  v = new TiXmlElement( (infoit->first).c_str() );
1133  v->LinkEndChild(new TiXmlText((infoit->second).c_str()));
1134  infoTag->LinkEndChild(v);
1135  }
1136  }
1137  }
1138 
1139 
1140  /**
1141  *
1142  */
1143  void FieldIO::GenerateSeqString(const std::vector<unsigned int> &elmtids,
1144  std::string &idString)
1145  {
1146  std::stringstream idStringStream;
1147  bool setdash = true;
1148  unsigned int endval;
1149 
1150  idStringStream << elmtids[0];
1151  for (int i = 1; i < elmtids.size(); ++i)
1152  {
1153  if(elmtids[i] == elmtids[i-1]+1)
1154  {
1155  if(setdash)
1156  {
1157  idStringStream << "-";
1158  setdash = false;
1159  }
1160 
1161  if(i == elmtids.size()-1) // last element
1162  {
1163  idStringStream << elmtids[i];
1164  }
1165  else
1166  {
1167  endval = elmtids[i];
1168  }
1169  }
1170  else
1171  {
1172  if(setdash == false) // finish off previous dash sequence
1173  {
1174  idStringStream << endval;
1175  setdash = true;
1176  }
1177 
1178 
1179  idStringStream << "," << elmtids[i];
1180  }
1181  }
1182  idString = idStringStream.str();
1183  }
1184 
1185 
1186  /**
1187  *
1188  */
1189  std::string FieldIO::SetUpOutput(const std::string outname)
1190  {
1191  ASSERTL0(!outname.empty(), "Empty path given to SetUpOutput()");
1192 
1193  int nprocs = m_comm->GetSize();
1194  int rank = m_comm->GetRank();
1195 
1196  // Path to output: will be directory if parallel, normal file if
1197  // serial.
1198  fs::path specPath (outname);
1199  fs::path fulloutname;
1200 
1201  if (nprocs == 1)
1202  {
1203  fulloutname = specPath;
1204  }
1205  else
1206  {
1207  // Guess at filename that might belong to this process.
1208  boost::format pad("P%1$07d.%2$s");
1209  pad % m_comm->GetRank() % GetFileEnding();
1210 
1211  // Generate full path name
1212  fs::path poutfile(pad.str());
1213  fulloutname = specPath / poutfile;
1214  }
1215 
1216  // Remove any existing file which is in the way
1217  if (m_comm->RemoveExistingFiles())
1218  {
1219  if (m_sharedFilesystem)
1220  {
1221  // First, each process clears up its .fld file. This might
1222  // or might not be there (we might have changed numbers of
1223  // processors between runs, for example), but we can try
1224  // anyway.
1225  try
1226  {
1227  fs::remove_all(fulloutname);
1228  }
1229  catch (fs::filesystem_error& e)
1230  {
1231  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
1232  "Filesystem error: " + string(e.what()));
1233  }
1234  }
1235 
1236  m_comm->Block();
1237 
1238  // Now get rank 0 processor to tidy everything else up.
1239  if (rank == 0 || !m_sharedFilesystem)
1240  {
1241  try
1242  {
1243  fs::remove_all(specPath);
1244  }
1245  catch (fs::filesystem_error& e)
1246  {
1247  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
1248  "Filesystem error: " + string(e.what()));
1249  }
1250  }
1251 
1252  m_comm->Block();
1253  }
1254 
1255  // serial processing just add ending.
1256  if(nprocs == 1)
1257  {
1258  cout << "Writing: " << specPath << endl;
1259  return LibUtilities::PortablePath(specPath);
1260  }
1261 
1262  // Create the destination directory
1263  try
1264  {
1265  if (rank == 0 || !m_sharedFilesystem)
1266  {
1267  fs::create_directory(specPath);
1268  }
1269  }
1270  catch (fs::filesystem_error& e)
1271  {
1272  ASSERTL0(false, "Filesystem error: " + string(e.what()));
1273  }
1274 
1275  m_comm->Block();
1276 
1277  // Return the full path to the partition for this process
1278  return LibUtilities::PortablePath(fulloutname);
1279  }
1280 
1281 
1283  const string outname,
1284  const vector< FieldDefinitionsSharedPtr > &fielddefs,
1285  const FieldMetaDataMap &fieldmetadatamap)
1286  {
1287  ASSERTL0(!outname.empty(), "Empty path given to SetUpFieldMetaData()");
1288 
1289  int nprocs = m_comm->GetSize();
1290  int rank = m_comm->GetRank();
1291 
1292  fs::path specPath (outname);
1293 
1294  // Compute number of elements on this process and share with other
1295  // processes. Also construct list of elements on this process from
1296  // available vector of field definitions.
1297  std::vector<unsigned int> elmtnums(nprocs,0);
1298  std::vector<unsigned int> idlist;
1299  int i;
1300  for (i = 0; i < fielddefs.size(); ++i)
1301  {
1302  elmtnums[rank] += fielddefs[i]->m_elementIDs.size();
1303  idlist.insert(idlist.end(), fielddefs[i]->m_elementIDs.begin(),
1304  fielddefs[i]->m_elementIDs.end());
1305  }
1306  m_comm->AllReduce(elmtnums,LibUtilities::ReduceMax);
1307 
1308  // Collate per-process element lists on root process to generate
1309  // the info file.
1310  if (rank == 0)
1311  {
1312  std::vector<std::vector<unsigned int> > ElementIDs(nprocs);
1313 
1314  // Populate the list of element ID lists from all processes
1315  ElementIDs[0] = idlist;
1316  for (i = 1; i < nprocs; ++i)
1317  {
1318  std::vector<unsigned int> tmp(elmtnums[i]);
1319  m_comm->Recv(i, tmp);
1320  ElementIDs[i] = tmp;
1321  }
1322 
1323  // Set up output names
1324  std::vector<std::string> filenames;
1325  for(int i = 0; i < nprocs; ++i)
1326  {
1327  boost::format pad("P%1$07d.%2$s");
1328  pad % i % GetFileEnding();
1329  filenames.push_back(pad.str());
1330  }
1331 
1332  // Write the Info.xml file
1333  string infofile = LibUtilities::PortablePath(
1334  specPath / fs::path("Info.xml"));
1335 
1336  cout << "Writing: " << specPath << endl;
1337  WriteMultiFldFileIDs(infofile, filenames, ElementIDs,
1338  fieldmetadatamap);
1339  }
1340  else
1341  {
1342  // Send this process's ID list to the root process
1343  m_comm->Send(0, idlist);
1344  }
1345 
1346  }
1347 
1348 
1349  /**
1350  *
1351  */
1353  {
1354  int i;
1355 
1356  if(fielddefs->m_elementIDs.size() == 0) // empty partition
1357  {
1358  return 0;
1359  }
1360  //ASSERTL0(fielddefs->m_elementIDs.size() > 0, "Fielddefs vector must contain at least one element of data .");
1361 
1362  unsigned int numbasis = 0;
1363 
1364  // Determine nummodes vector lists are correct length
1365  switch(fielddefs->m_shapeType)
1366  {
1367  case eSegment:
1368  numbasis = 1;
1369  if(fielddefs->m_numHomogeneousDir)
1370  {
1371  numbasis += fielddefs->m_numHomogeneousDir;
1372  }
1373 
1374  break;
1375  case eTriangle:
1376  case eQuadrilateral:
1377  if(fielddefs->m_numHomogeneousDir)
1378  {
1379  numbasis = 3;
1380  }
1381  else
1382  {
1383  numbasis = 2;
1384  }
1385  break;
1386  case eTetrahedron:
1387  case ePyramid:
1388  case ePrism:
1389  case eHexahedron:
1390  numbasis = 3;
1391  break;
1392  default:
1393  ASSERTL0(false, "Unsupported shape type.");
1394  break;
1395  }
1396 
1397  unsigned int datasize = 0;
1398 
1399  ASSERTL0(fielddefs->m_basis.size() == numbasis, "Length of basis vector is incorrect");
1400 
1401  if(fielddefs->m_uniOrder == true)
1402  {
1403  unsigned int cnt = 0;
1404  // calculate datasize
1405  switch(fielddefs->m_shapeType)
1406  {
1407  case eSegment:
1408  {
1409  int l = fielddefs->m_numModes[cnt++];
1410  if(fielddefs->m_numHomogeneousDir == 1)
1411  {
1412  datasize += l*fielddefs->m_numModes[cnt++];
1413  }
1414  else if(fielddefs->m_numHomogeneousDir == 2)
1415  {
1416  int m = fielddefs->m_numModes[cnt++];
1417  datasize += l*m*fielddefs->m_numModes[cnt++];
1418  }
1419  else
1420  {
1421  datasize += l;
1422  }
1423  }
1424  break;
1425  case eTriangle:
1426  {
1427  int l = fielddefs->m_numModes[cnt++];
1428  int m = fielddefs->m_numModes[cnt++];
1429 
1430  if(fielddefs->m_numHomogeneousDir == 1)
1431  {
1432  datasize += StdTriData::getNumberOfCoefficients(l,m)*
1433  fielddefs->m_homogeneousZIDs.size();
1434  }
1435  else
1436  {
1437  datasize += StdTriData::getNumberOfCoefficients(l,m);
1438  }
1439  }
1440  break;
1441  case eQuadrilateral:
1442  {
1443  int l = fielddefs->m_numModes[cnt++];
1444  int m = fielddefs->m_numModes[cnt++];
1445  if(fielddefs->m_numHomogeneousDir == 1)
1446  {
1447  datasize += l*m*fielddefs->m_homogeneousZIDs.size();
1448  }
1449  else
1450  {
1451  datasize += l*m;
1452  }
1453  }
1454  break;
1455  case eTetrahedron:
1456  {
1457  int l = fielddefs->m_numModes[cnt++];
1458  int m = fielddefs->m_numModes[cnt++];
1459  int n = fielddefs->m_numModes[cnt++];
1460  datasize += StdTetData::getNumberOfCoefficients(l,m,n);
1461  }
1462  break;
1463  case ePyramid:
1464  {
1465  int l = fielddefs->m_numModes[cnt++];
1466  int m = fielddefs->m_numModes[cnt++];
1467  int n = fielddefs->m_numModes[cnt++];
1468  datasize += StdPyrData::getNumberOfCoefficients(l,m,n);
1469  }
1470  break;
1471  case ePrism:
1472  {
1473  int l = fielddefs->m_numModes[cnt++];
1474  int m = fielddefs->m_numModes[cnt++];
1475  int n = fielddefs->m_numModes[cnt++];
1476  datasize += StdPrismData::getNumberOfCoefficients(l,m,n);
1477  }
1478  break;
1479  case eHexahedron:
1480  {
1481  int l = fielddefs->m_numModes[cnt++];
1482  int m = fielddefs->m_numModes[cnt++];
1483  int n = fielddefs->m_numModes[cnt++];
1484  datasize += l*m*n;
1485  }
1486  break;
1487  default:
1488  ASSERTL0(false, "Unsupported shape type.");
1489  break;
1490  }
1491 
1492  datasize *= fielddefs->m_elementIDs.size();
1493  }
1494  else
1495  {
1496  unsigned int cnt = 0;
1497  // calculate data length
1498  for(i = 0; i < fielddefs->m_elementIDs.size(); ++i)
1499  {
1500  switch(fielddefs->m_shapeType)
1501  {
1502  case eSegment:
1503  {
1504  int l = fielddefs->m_numModes[cnt++];
1505  if(fielddefs->m_numHomogeneousDir == 1)
1506  {
1507  datasize += l*fielddefs->m_numModes[cnt++];
1508  }
1509  else if(fielddefs->m_numHomogeneousDir == 2)
1510  {
1511  int m = fielddefs->m_numModes[cnt++];
1512  datasize += l*m*fielddefs->m_numModes[cnt++];
1513  }
1514  else
1515  {
1516  datasize += l;
1517  }
1518  }
1519  break;
1520  case eTriangle:
1521  {
1522  int l = fielddefs->m_numModes[cnt++];
1523  int m = fielddefs->m_numModes[cnt++];
1524  if(fielddefs->m_numHomogeneousDir == 1)
1525  {
1526  datasize += StdTriData::getNumberOfCoefficients(l,m)*
1527  fielddefs->m_homogeneousZIDs.size();
1528  cnt++;
1529  }
1530  else
1531  {
1532  datasize += StdTriData::getNumberOfCoefficients(l,m);
1533  }
1534  }
1535  break;
1536  case eQuadrilateral:
1537  {
1538  int l = fielddefs->m_numModes[cnt++];
1539  int m = fielddefs->m_numModes[cnt++];
1540  if(fielddefs->m_numHomogeneousDir == 1)
1541  {
1542  datasize += l*m*fielddefs->
1543  m_homogeneousZIDs.size();
1544  cnt++;
1545  }
1546  else
1547  {
1548  datasize += l*m;
1549  }
1550  }
1551  break;
1552  case eTetrahedron:
1553  {
1554  int l = fielddefs->m_numModes[cnt++];
1555  int m = fielddefs->m_numModes[cnt++];
1556  int n = fielddefs->m_numModes[cnt++];
1557  datasize += StdTetData::getNumberOfCoefficients(l,m,n);
1558  }
1559  break;
1560  case ePyramid:
1561  {
1562  int l = fielddefs->m_numModes[cnt++];
1563  int m = fielddefs->m_numModes[cnt++];
1564  int n = fielddefs->m_numModes[cnt++];
1565  datasize += StdPyrData::getNumberOfCoefficients(l,m,n);
1566  }
1567  break;
1568  case ePrism:
1569  {
1570  int l = fielddefs->m_numModes[cnt++];
1571  int m = fielddefs->m_numModes[cnt++];
1572  int n = fielddefs->m_numModes[cnt++];
1573  datasize += StdPrismData::getNumberOfCoefficients(l,m,n);
1574  }
1575  break;
1576  case eHexahedron:
1577  {
1578  int l = fielddefs->m_numModes[cnt++];
1579  int m = fielddefs->m_numModes[cnt++];
1580  int n = fielddefs->m_numModes[cnt++];
1581  datasize += l*m*n;
1582  }
1583  break;
1584  default:
1585  ASSERTL0(false, "Unsupported shape type.");
1586  break;
1587  }
1588  }
1589  }
1590 
1591  return datasize;
1592  }
1593  }
1594 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
static bool GenerateOrderedStringVector(const char *const str, std::vector< std::string > &vec)
Definition: ParseUtils.hpp:143
void ImportFieldDefs(TiXmlDocument &doc, std::vector< FieldDefinitionsSharedPtr > &fielddefs, bool expChild)
Imports the definition of the fields.
Definition: FieldIO.cpp:723
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:286
static bool GenerateOrderedVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:97
tBaseSharedPtr CreateInstance(tKey idKey BOOST_PP_COMMA_IF(MAX_PARAM) BOOST_PP_ENUM_BINARY_PARAMS(MAX_PARAM, tParam, x))
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:162
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
const char *const BasisTypeMap[]
Definition: Foundations.hpp:47
void ImportFieldData(TiXmlDocument &doc, const std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata)
Imports the data fileds.
Definition: FieldIO.cpp:1015
const std::string kPointsTypeStr[]
Definition: Foundations.hpp:69
FieldIO(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem=false)
Constructor.
Definition: FieldIO.cpp:149
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.
Definition: FieldIO.cpp:406
boost::shared_ptr< FieldDefinitions > FieldDefinitionsSharedPtr
Definition: FieldIO.h:118
void ImportMultiFldFileIDs(const std::string &inFile, std::vector< std::string > &fileNames, std::vector< std::vector< unsigned int > > &elementList, FieldMetaDataMap &fieldmetadatamap)
Definition: FieldIO.cpp:574
std::string SetUpOutput(const std::string outname)
Definition: FieldIO.cpp:1189
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:186
static bool GenerateSeqVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:79
std::map< std::string, std::string > FieldMetaDataMap
Definition: FieldIO.h:53
CommFactory & GetCommFactory()
Definition: Comm.cpp:64
int CheckFieldDefinition(const FieldDefinitionsSharedPtr &fielddefs)
Definition: FieldIO.cpp:1352
const char *const ShapeTypeMap[]
Definition: ShapeType.hpp:66
void Import(const std::string &infilename, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, FieldMetaDataMap &fieldinfomap, const Array< OneD, int > ElementiDs)
Imports an FLD file.
Definition: FieldIO.cpp:115
void GenerateSeqString(const std::vector< unsigned int > &elmtids, std::string &idString)
Definition: FieldIO.cpp:1143
bool m_sharedFilesystem
True if same filesystem accessible by all processes.
Definition: FieldIO.h:194
boost::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
void AddInfoTag(TiXmlElement *root, const FieldMetaDataMap &fieldmetadatamap)
add information about provenance and fieldmetadata
Definition: FieldIO.cpp:1084
const std::string kGitSha1
#define LIB_UTILITIES_EXPORT
#define WARNINGL0(condition, msg)
Definition: ErrorUtil.hpp:167
static std::vector< std::vector< NekDouble > > NullVectorNekDoubleVector
Definition: FieldIO.h:55
int getNumberOfCoefficients(int Na, int Nb)
Definition: ShapeType.hpp:111
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:41
const std::string kGitBranch
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:1282
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:232
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
#define NEKTAR_VERSION
Definition: FieldIO.cpp:65
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:534
Class for operating on FLD files.
Definition: FieldIO.h:137
void ImportFieldMetaData(std::string filename, FieldMetaDataMap &fieldmetadatamap)
Imports the definition of the meta data.
Definition: FieldIO.cpp:634
virtual std::string GetFileEnding() const
Definition: FieldIO.h:218
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.
Definition: FieldIO.cpp:160
void Write(const std::string &outFile, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, const FieldMetaDataMap &fieldinfomap)
Write a field file in serial only.
Definition: FieldIO.cpp:81
static Array< OneD, int > NullInt1DArray
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:191
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:54
int ZlibDecodeFromBase64Str(std::string &in64, std::vector< T > &out)
Definition: CompressData.h:243