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  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  }
404 
405 
406  /**
407  *
408  */
409  void FieldIO::Import(const std::string& infilename,
410  std::vector<FieldDefinitionsSharedPtr> &fielddefs,
411  std::vector<std::vector<NekDouble> > &fielddata,
412  FieldMetaDataMap &fieldmetadatamap,
413  const Array<OneD, int> ElementIDs)
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  }
532 
533 
534  /**
535  *
536  */
537  void FieldIO::WriteMultiFldFileIDs(const std::string &outFile,
538  const std::vector<std::string> fileNames,
539  std::vector<std::vector<unsigned int> > &elementList,
540  const FieldMetaDataMap &fieldmetadatamap)
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  }
572 
573 
574  /**
575  *
576  */
577  void FieldIO::ImportMultiFldFileIDs(const std::string &inFile,
578  std::vector<std::string> &fileNames,
579  std::vector<std::vector<unsigned int> > &elementList,
580  FieldMetaDataMap &fieldmetadatamap)
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  }
636 
637  void FieldIO::ImportFieldMetaData(std::string filename,
638  FieldMetaDataMap &fieldmetadatamap)
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  }
651 
652 
653  void FieldIO::ImportFieldMetaData(TiXmlDocument &doc,
654  FieldMetaDataMap &fieldmetadatamap)
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  }
721 
722 
723  /**
724  * The bool decides if the FieldDefs are in <EXPANSIONS> or in <NEKTAR>.
725  */
726  void FieldIO::ImportFieldDefs(TiXmlDocument &doc, std::vector<FieldDefinitionsSharedPtr> &fielddefs,
727  bool expChild)
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  }
1013 
1014 
1015  /**
1016  *
1017  */
1018  void FieldIO::ImportFieldData(TiXmlDocument &doc, const std::vector<FieldDefinitionsSharedPtr> &fielddefs, std::vector<std::vector<NekDouble> > &fielddata)
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  }
1082 
1083 
1084  /**
1085  * \brief add information about provenance and fieldmetadata
1086  */
1087  void FieldIO::AddInfoTag(TiXmlElement * root,
1088  const FieldMetaDataMap &fieldmetadatamap)
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  }
1141 
1142 
1143  /**
1144  *
1145  */
1146  void FieldIO::GenerateSeqString(const std::vector<unsigned int> &elmtids,
1147  std::string &idString)
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  }
1187 
1188 
1189  /**
1190  *
1191  */
1192  std::string FieldIO::SetUpOutput(const std::string outname)
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  }
1283 
1284 
1286  const string outname,
1287  const vector< FieldDefinitionsSharedPtr > &fielddefs,
1288  const FieldMetaDataMap &fieldmetadatamap)
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  }
1350 
1351 
1352  /**
1353  *
1354  */
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  }
1596  }
1597 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
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:726
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:1018
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:409
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:577
std::string SetUpOutput(const std::string outname)
Definition: FieldIO.cpp:1192
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:1355
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:1146
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:1087
const std::string kGitSha1
#define LIB_UTILITIES_EXPORT
#define WARNINGL0(condition, msg)
Definition: ErrorUtil.hpp:194
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:1285
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:537
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:637
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:218
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:54
int ZlibDecodeFromBase64Str(std::string &in64, std::vector< T > &out)
Definition: CompressData.h:243