Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties 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/asio/ip/host_name.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/make_shared.hpp>
40 #include <boost/format.hpp>
41 
45 
46 #include <loki/Singleton.h>
47 
48 #include <fstream>
49 #include <set>
50 
51 #ifdef NEKTAR_USE_MPI
52 #include <mpi.h>
53 #endif
54 
55 #ifndef NEKTAR_VERSION
56 #define NEKTAR_VERSION "Unknown"
57 #endif
58 
59 namespace berrc = boost::system::errc;
60 namespace ptime = boost::posix_time;
61 namespace ip = boost::asio::ip;
62 
63 namespace Nektar
64 {
65 namespace LibUtilities
66 {
67 
69  "io-format", "i", "Default input/output format (e.g. Xml, Hdf5)");
70 
71 /**
72  * @brief Returns the FieldIO factory.
73  */
75 {
76  typedef Loki::
77  SingletonHolder<FieldIOFactory, Loki::CreateUsingNew, Loki::NoDestroy,
78  Loki::ClassLevelLockable> Type;
79  return Type::Instance();
80 }
81 
82 /// Enumerator for auto-detection of FieldIO types.
86 };
87 
88 
89 /**
90  * @brief Determine file type of given input file.
91  *
92  * This method attempts to identify the file type of a given input file @p
93  * filename. It returns a string corresponding to GetFieldIOFactory() or throws
94  * an assertion if it cannot be identified.
95  *
96  * @param filename Input filename
97  * @param comm Communicator for parallel runs
98  *
99  * @return FieldIO format of @p filename.
100  */
101 const std::string FieldIO::GetFileType(const std::string &filename,
102  CommSharedPtr comm)
103 {
104  FieldIOType ioType = eXML;
105  int size = comm->GetSize();
106  int rank = comm->GetRank();
107 
108  if (size == 1 || rank == 0)
109  {
110  std::string datafilename;
111 
112  // If input is a directory, check for root processor file.
113  if (fs::is_directory(filename))
114  {
115  fs::path p0file("P0000000.fld");
116  fs::path fullpath = filename / p0file;
117  datafilename = PortablePath(fullpath);
118  }
119  else
120  {
121  datafilename = filename;
122  }
123 
124  // Read first 8 bytes. If they correspond with magic bytes below it's an
125  // HDF5 file. XML is potentially a nightmare with all the different
126  // encodings so we'll just assume it's OK if it's not HDF.
127  const unsigned char magic[8] = {
128  0x89, 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a};
129 
130  std::ifstream datafile(datafilename.c_str(), ios_base::binary);
131  ASSERTL0(datafile.good(), "Unable to open file: " + filename);
132 
133  ioType = eHDF5;
134  for (unsigned i = 0; i < 8 && datafile.good(); ++i)
135  {
136  unsigned char byte = datafile.get();
137  if (byte != magic[i])
138  {
139  ioType = eXML;
140  break;
141  }
142  }
143  }
144 
145  if (size > 1)
146  {
147  int code = (int)ioType;
148  comm->Bcast(code, 0);
149  ioType = (FieldIOType)code;
150  }
151 
152  std::string iofmt;
153  if (ioType == eXML)
154  {
155  iofmt = "Xml";
156  }
157  else if (ioType == eHDF5)
158  {
159  iofmt = "Hdf5";
160  }
161  else
162  {
163  // Error
164  ASSERTL0(false, "Unknown file format");
165  }
166 
167  return iofmt;
168 }
169 
170 /**
171  * @brief Returns an object for the default FieldIO method.
172  *
173  * This function returns a FieldIO class as determined by the hard-coded default
174  * (XML), which can be overridden by changing the session reader SOLVERINFO
175  * variable FieldIOFormat.
176  *
177  * @param session Session reader
178  *
179  * @return FieldIO object
180  */
183 {
184  std::string iofmt("Xml");
185  if (session->DefinesSolverInfo("IOFormat"))
186  {
187  iofmt = session->GetSolverInfo("IOFormat");
188  }
189 
190  if (session->DefinesCmdLineArgument("io-format"))
191  {
192  iofmt = session->GetCmdLineArgument<std::string>("io-format");
193  }
194 
196  iofmt,
197  session->GetComm(),
198  session->GetSharedFilesystem());
199 }
200 
201 /**
202  * @brief Construct a FieldIO object for a given input filename.
203  *
204  * This is a convenience function that takes an input filename and constructs
205  * the appropriate FieldIO subclass, using FieldIO::GetFileType.
206  *
207  * @param session Session reader
208  * @param filename Input filename
209  *
210  * @return FieldIO class reader for @p filename.
211  */
214  const std::string &filename)
215 {
216  const std::string iofmt =
217  FieldIO::GetFileType(filename, session->GetComm());
219  iofmt,
220  session->GetComm(),
221  session->GetSharedFilesystem());
222 }
223 
224 /**
225  * @brief This function allows for data to be written to an FLD file when a
226  * session and/or communicator is not instantiated. Typically used in utilities
227  * which do not take XML input and operate in serial only.
228  *
229  * @param outFile Output filename
230  * @param fielddefs Field definitions that define the output
231  * @param fielddata Binary field data that stores the output corresponding
232  * to @p fielddefs.
233  * @param fieldinfomap Associated field metadata map.
234  */
235 void Write(const std::string &outFile,
236  std::vector<FieldDefinitionsSharedPtr> &fielddefs,
237  std::vector<std::vector<NekDouble> > &fielddata,
238  const FieldMetaDataMap &fieldinfomap,
239  const bool backup)
240 {
241 #ifdef NEKTAR_USE_MPI
242  int size;
243  int init;
244  MPI_Initialized(&init);
245 
246  // If MPI has been initialised we can check the number of processes
247  // and, if > 1, tell the user he should not be running this
248  // function in parallel. If it is not initialised, we do not
249  // initialise it here, and assume the user knows what they are
250  // doing.
251  if (init)
252  {
253  MPI_Comm_size(MPI_COMM_WORLD, &size);
254  ASSERTL0(size == 1,
255  "This static function is not available in parallel. Please"
256  "instantiate a FieldIO object for parallel use.");
257  }
258 #endif
259  CommSharedPtr c = GetCommFactory().CreateInstance("Serial", 0, 0);
260  FieldIOSharedPtr f = GetFieldIOFactory().CreateInstance("Xml", c, false);
261  f->Write(outFile, fielddefs, fielddata, fieldinfomap, backup);
262 }
263 
264 /**
265  * @brief This function allows for data to be imported from an FLD file when a
266  * session and/or communicator is not instantiated. Typically used in utilities
267  * which only operate in serial.
268  *
269  * @param infilename Input filename (or directory if parallel format)
270  * @param fielddefs On return contains field definitions as read from the
271  * input.
272  * @param fielddata On return, contains binary field data that stores the
273  * input corresponding to @p fielddefs.
274  * @param fieldinfo On returnm, contains the associated field metadata map.
275  * @param ElementIDs Element IDs that lie on this processor, which can be
276  * optionally supplied to avoid reading the entire file on
277  * each processor.
278  */
280  const std::string &infilename,
281  std::vector<FieldDefinitionsSharedPtr> &fielddefs,
282  std::vector<std::vector<NekDouble> > &fielddata,
283  FieldMetaDataMap &fieldinfomap,
284  const Array<OneD, int> &ElementIDs)
285 {
286 #ifdef NEKTAR_USE_MPI
287  int size;
288  int init;
289  MPI_Initialized(&init);
290 
291  // If MPI has been initialised we can check the number of processes
292  // and, if > 1, tell the user he should not be running this
293  // function in parallel. If it is not initialised, we do not
294  // initialise it here, and assume the user knows what they are
295  // doing.
296  if (init)
297  {
298  MPI_Comm_size(MPI_COMM_WORLD, &size);
299  ASSERTL0(size == 1,
300  "This static function is not available in parallel. Please"
301  "instantiate a FieldIO object for parallel use.");
302  }
303 #endif
304  CommSharedPtr c = GetCommFactory().CreateInstance("Serial", 0, 0);
305  const std::string iofmt = FieldIO::GetFileType(infilename, c);
306  FieldIOSharedPtr f = GetFieldIOFactory().CreateInstance(iofmt, c, false);
307  f->Import(infilename, fielddefs, fielddata, fieldinfomap, ElementIDs);
308 }
309 
310 /**
311  * @brief Constructor for FieldIO base class.
312  */
313 FieldIO::FieldIO(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
314  : m_comm(pComm), m_sharedFilesystem(sharedFilesystem)
315 {
316 }
317 
318 /**
319  * @brief Add provenance information to the field metadata map.
320  *
321  * This routine adds some basic provenance information to the field metadata to
322  * enable better tracking of version information:
323  *
324  * - Nektar++ version
325  * - Date and time of simulation
326  * - Hostname of the machine the simulation was performed on
327  * - git SHA1 and branch name, if Nektar++ was compiled from git and not
328  * e.g. a tarball.
329  *
330  * @param root Root tag, which is encapsulated using the TagWriter
331  * structure to enable multi-file format support.
332  * @param fieldmetadatamap Any existing field metadata.
333  */
335  const FieldMetaDataMap &fieldmetadatamap)
336 {
337  FieldMetaDataMap ProvenanceMap;
338 
339  // Nektar++ release version from VERSION file
340  ProvenanceMap["NektarVersion"] = string(NEKTAR_VERSION);
341 
342  // Date/time stamp
343  ptime::time_facet *facet = new ptime::time_facet("%d-%b-%Y %H:%M:%S");
344  std::stringstream wss;
345  wss.imbue(locale(wss.getloc(), facet));
346  wss << ptime::second_clock::local_time();
347  ProvenanceMap["Timestamp"] = wss.str();
348 
349  // Hostname
350  boost::system::error_code ec;
351  ProvenanceMap["Hostname"] = ip::host_name(ec);
352 
353  // Git information
354  // If built from a distributed package, do not include this
355  if (NekConstants::kGitSha1 != "GITDIR-NOTFOUND")
356  {
357  ProvenanceMap["GitSHA1"] = NekConstants::kGitSha1;
358  ProvenanceMap["GitBranch"] = NekConstants::kGitBranch;
359  }
360 
361  TagWriterSharedPtr infoTag = root->AddChild("Metadata");
362 
363  FieldMetaDataMap::const_iterator infoit;
364 
365  TagWriterSharedPtr provTag = infoTag->AddChild("Provenance");
366  for (infoit = ProvenanceMap.begin(); infoit != ProvenanceMap.end();
367  ++infoit)
368  {
369  provTag->SetAttr(infoit->first, infoit->second);
370  }
371 
372  //---------------------------------------------
373  // write field info section
374  if (fieldmetadatamap != NullFieldMetaDataMap)
375  {
376  for (infoit = fieldmetadatamap.begin();
377  infoit != fieldmetadatamap.end();
378  ++infoit)
379  {
380  infoTag->SetAttr(infoit->first, infoit->second);
381  }
382  }
383 }
384 
385 /**
386  * @brief Set up the filesystem ready for output.
387  *
388  * This function sets up the output given an output filename @p outname. This
389  * will therefore remove any file or directory with the desired output filename
390  * and return the absolute path to the output.
391  *
392  * If @p perRank is set, a new directory will be created to contain one file per
393  * process rank.
394  *
395  * @param outname Desired output filename.
396  * @param perRank True if one file-per-rank output is required.
397  *
398  * @return Absolute path to resulting file.
399  */
400 std::string FieldIO::SetUpOutput(const std::string outname, bool perRank, bool backup)
401 {
402  ASSERTL0(!outname.empty(), "Empty path given to SetUpOutput()");
403 
404  int nprocs = m_comm->GetSize();
405  int rank = m_comm->GetRank();
406 
407  // Path to output: will be directory if parallel, normal file if
408  // serial.
409  fs::path specPath(outname), fulloutname;
410 
411  // in case we are rank 0 or not on a shared filesystem, check if the specPath already exists
412  if (backup && (rank == 0 || !m_sharedFilesystem) && fs::exists(specPath))
413  {
414  // rename. foo/bar_123.chk -> foo/bar_123.bak0.chk and in case
415  // foo/bar_123.bak0.chk already exists, foo/bar_123.chk -> foo/bar_123.bak1.chk
416  fs::path bakPath = specPath;
417  int cnt = 0;
418  while (fs::exists(bakPath))
419  {
420  bakPath = specPath.parent_path();
421  bakPath += specPath.stem();
422  bakPath += fs::path(".bak" + boost::lexical_cast<std::string>(cnt++));
423  bakPath += specPath.extension();
424  }
425  std::cout << "renaming " << specPath << " -> " << bakPath << std::endl;
426  try
427  {
428  fs::rename(specPath, bakPath);
429  }
430  catch (fs::filesystem_error &e)
431  {
432  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
433  "Filesystem error: " + string(e.what()));
434  }
435  }
436 
437  // wait until rank 0 has moved the old specPath and the changes
438  // have propagated through the filesystem
439  if (backup)
440  {
441  m_comm->Block();
442  int exists = 1;
443  while (exists && perRank)
444  {
445  exists = fs::exists(specPath);
446  m_comm->AllReduce(exists, ReduceMax);
447  }
448  }
449 
450  if (nprocs == 1)
451  {
452  fulloutname = specPath;
453  }
454  else
455  {
456  // Guess at filename that might belong to this process.
457  boost::format pad("P%1$07d.%2$s");
458  pad % m_comm->GetRank() % GetFileEnding();
459 
460  // Generate full path name
461  fs::path poutfile(pad.str());
462  fulloutname = specPath / poutfile;
463  }
464 
465  // Remove any existing file which is in the way
466  if (m_comm->RemoveExistingFiles() && !backup)
467  {
468  if (m_sharedFilesystem)
469  {
470  // First, each process clears up its .fld file. This might or might
471  // not be there (we might have changed numbers of processors between
472  // runs, for example), but we can try anyway.
473  try
474  {
475  fs::remove_all(fulloutname);
476  }
477  catch (fs::filesystem_error &e)
478  {
479  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
480  "Filesystem error: " + string(e.what()));
481  }
482  }
483 
484  m_comm->Block();
485 
486  // Now get rank 0 processor to tidy everything else up.
487  if (rank == 0 || !m_sharedFilesystem)
488  {
489  try
490  {
491  fs::remove_all(specPath);
492  }
493  catch (fs::filesystem_error &e)
494  {
495  ASSERTL0(e.code().value() == berrc::no_such_file_or_directory,
496  "Filesystem error: " + string(e.what()));
497  }
498  }
499 
500  // wait until rank 0 has removed specPath and the changes
501  // have propagated through the filesystem
502  m_comm->Block();
503  int exists = 1;
504  while (exists && perRank)
505  {
506  exists = fs::exists(specPath);
507  m_comm->AllReduce(exists, ReduceMax);
508  }
509  }
510 
511  if (rank == 0)
512  {
513  cout << "Writing: " << specPath;
514  }
515 
516  // serial processing just add ending.
517  if (nprocs == 1)
518  {
519  return LibUtilities::PortablePath(specPath);
520  }
521 
522  // Create the destination directory
523  if (perRank)
524  {
525  try
526  {
527  if (rank == 0 || !m_sharedFilesystem)
528  {
529  fs::create_directory(specPath);
530  }
531  }
532  catch (fs::filesystem_error &e)
533  {
534  ASSERTL0(false, "Filesystem error: " + string(e.what()));
535  }
536 
537  m_comm->Block();
538 
539  // Sit in a loop and make sure target directory has been created
540  int created = 0;
541  while (!created)
542  {
543  created = fs::is_directory(specPath);
544  m_comm->AllReduce(created, ReduceMin);
545  }
546  }
547  else
548  {
549  fulloutname = specPath;
550  }
551 
552  // Return the full path to the partition for this process
553  return LibUtilities::PortablePath(fulloutname);
554 }
555 
556 /**
557  * @brief Check field definitions for correctness and return storage size.
558  *
559  * @param fielddefs Field definitions to check.
560  */
562 {
563  int i;
564 
565  if (fielddefs->m_elementIDs.size() == 0) // empty partition
566  {
567  return 0;
568  }
569 
570  unsigned int numbasis = 0;
571 
572  // Determine nummodes vector lists are correct length
573  switch (fielddefs->m_shapeType)
574  {
575  case eSegment:
576  numbasis = 1;
577  if (fielddefs->m_numHomogeneousDir)
578  {
579  numbasis += fielddefs->m_numHomogeneousDir;
580  }
581 
582  break;
583  case eTriangle:
584  case eQuadrilateral:
585  if (fielddefs->m_numHomogeneousDir)
586  {
587  numbasis = 3;
588  }
589  else
590  {
591  numbasis = 2;
592  }
593  break;
594  case eTetrahedron:
595  case ePyramid:
596  case ePrism:
597  case eHexahedron:
598  numbasis = 3;
599  break;
600  default:
601  ASSERTL0(false, "Unsupported shape type.");
602  break;
603  }
604 
605  unsigned int datasize = 0;
606 
607  ASSERTL0(fielddefs->m_basis.size() == numbasis,
608  "Length of basis vector is incorrect");
609 
610  if (fielddefs->m_uniOrder == true)
611  {
612  unsigned int cnt = 0;
613  // calculate datasize
614  switch (fielddefs->m_shapeType)
615  {
616  case eSegment:
617  {
618  int l = fielddefs->m_numModes[cnt++];
619  if (fielddefs->m_numHomogeneousDir == 1)
620  {
621  datasize += l * fielddefs->m_homogeneousZIDs.size();
622  cnt++;
623  }
624  else if (fielddefs->m_numHomogeneousDir == 2)
625  {
626  datasize += l * fielddefs->m_homogeneousYIDs.size();
627  cnt += 2;
628  }
629  else
630  {
631  datasize += l;
632  }
633  }
634  break;
635  case eTriangle:
636  {
637  int l = fielddefs->m_numModes[cnt++];
638  int m = fielddefs->m_numModes[cnt++];
639 
640  if (fielddefs->m_numHomogeneousDir == 1)
641  {
642  datasize += StdTriData::getNumberOfCoefficients(l, m) *
643  fielddefs->m_homogeneousZIDs.size();
644  }
645  else
646  {
647  datasize += StdTriData::getNumberOfCoefficients(l, m);
648  }
649  }
650  break;
651  case eQuadrilateral:
652  {
653  int l = fielddefs->m_numModes[cnt++];
654  int m = fielddefs->m_numModes[cnt++];
655  if (fielddefs->m_numHomogeneousDir == 1)
656  {
657  datasize += l * m * fielddefs->m_homogeneousZIDs.size();
658  }
659  else
660  {
661  datasize += l * m;
662  }
663  }
664  break;
665  case eTetrahedron:
666  {
667  int l = fielddefs->m_numModes[cnt++];
668  int m = fielddefs->m_numModes[cnt++];
669  int n = fielddefs->m_numModes[cnt++];
670  datasize += StdTetData::getNumberOfCoefficients(l, m, n);
671  }
672  break;
673  case ePyramid:
674  {
675  int l = fielddefs->m_numModes[cnt++];
676  int m = fielddefs->m_numModes[cnt++];
677  int n = fielddefs->m_numModes[cnt++];
678  datasize += StdPyrData::getNumberOfCoefficients(l, m, n);
679  }
680  break;
681  case ePrism:
682  {
683  int l = fielddefs->m_numModes[cnt++];
684  int m = fielddefs->m_numModes[cnt++];
685  int n = fielddefs->m_numModes[cnt++];
686  datasize += StdPrismData::getNumberOfCoefficients(l, m, n);
687  }
688  break;
689  case eHexahedron:
690  {
691  int l = fielddefs->m_numModes[cnt++];
692  int m = fielddefs->m_numModes[cnt++];
693  int n = fielddefs->m_numModes[cnt++];
694  datasize += l * m * n;
695  }
696  break;
697  default:
698  ASSERTL0(false, "Unsupported shape type.");
699  break;
700  }
701 
702  datasize *= fielddefs->m_elementIDs.size();
703  }
704  else
705  {
706  unsigned int cnt = 0;
707  // calculate data length
708  for (i = 0; i < fielddefs->m_elementIDs.size(); ++i)
709  {
710  switch (fielddefs->m_shapeType)
711  {
712  case eSegment:
713  {
714  int l = fielddefs->m_numModes[cnt++];
715  if (fielddefs->m_numHomogeneousDir == 1)
716  {
717  datasize += l * fielddefs->m_homogeneousZIDs.size();
718  cnt++;
719  }
720  else if (fielddefs->m_numHomogeneousDir == 2)
721  {
722  datasize += l * fielddefs->m_homogeneousYIDs.size();
723  cnt += 2;
724  }
725  else
726  {
727  datasize += l;
728  }
729  }
730  break;
731  case eTriangle:
732  {
733  int l = fielddefs->m_numModes[cnt++];
734  int m = fielddefs->m_numModes[cnt++];
735  if (fielddefs->m_numHomogeneousDir == 1)
736  {
737  datasize += StdTriData::getNumberOfCoefficients(l, m) *
738  fielddefs->m_homogeneousZIDs.size();
739  cnt++;
740  }
741  else
742  {
743  datasize += StdTriData::getNumberOfCoefficients(l, m);
744  }
745  }
746  break;
747  case eQuadrilateral:
748  {
749  int l = fielddefs->m_numModes[cnt++];
750  int m = fielddefs->m_numModes[cnt++];
751  if (fielddefs->m_numHomogeneousDir == 1)
752  {
753  datasize += l * m * fielddefs->m_homogeneousZIDs.size();
754  cnt++;
755  }
756  else
757  {
758  datasize += l * m;
759  }
760  }
761  break;
762  case eTetrahedron:
763  {
764  int l = fielddefs->m_numModes[cnt++];
765  int m = fielddefs->m_numModes[cnt++];
766  int n = fielddefs->m_numModes[cnt++];
767  datasize += StdTetData::getNumberOfCoefficients(l, m, n);
768  }
769  break;
770  case ePyramid:
771  {
772  int l = fielddefs->m_numModes[cnt++];
773  int m = fielddefs->m_numModes[cnt++];
774  int n = fielddefs->m_numModes[cnt++];
775  datasize += StdPyrData::getNumberOfCoefficients(l, m, n);
776  }
777  break;
778  case ePrism:
779  {
780  int l = fielddefs->m_numModes[cnt++];
781  int m = fielddefs->m_numModes[cnt++];
782  int n = fielddefs->m_numModes[cnt++];
783  datasize += StdPrismData::getNumberOfCoefficients(l, m, n);
784  }
785  break;
786  case eHexahedron:
787  {
788  int l = fielddefs->m_numModes[cnt++];
789  int m = fielddefs->m_numModes[cnt++];
790  int n = fielddefs->m_numModes[cnt++];
791  datasize += l * m * n;
792  }
793  break;
794  default:
795  ASSERTL0(false, "Unsupported shape type.");
796  break;
797  }
798  }
799  }
800 
801  return datasize;
802 }
803 }
804 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:286
LibUtilities::NekFactory< std::string, FieldIO, LibUtilities::CommSharedPtr, bool > FieldIOFactory
Datatype of the NekFactory used to instantiate classes.
Definition: FieldIO.h:197
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
void Import(const std::string &infilename, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, FieldMetaDataMap &fieldinfomap, const Array< OneD, int > &ElementIDs)
This function allows for data to be imported from an FLD file when a session and/or communicator is n...
Definition: FieldIO.cpp:279
boost::shared_ptr< FieldDefinitions > FieldDefinitionsSharedPtr
Definition: FieldIO.h:181
static std::string RegisterCmdLineArgument(const std::string &pName, const std::string &pShortName, const std::string &pDescription)
Registers a command-line argument with the session reader.
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:186
FieldIOFactory & GetFieldIOFactory()
Returns the FieldIO factory.
Definition: FieldIO.cpp:74
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
Definition: MeshPartition.h:51
std::map< std::string, std::string > FieldMetaDataMap
Definition: FieldIO.h:54
CommFactory & GetCommFactory()
Definition: Comm.cpp:61
int CheckFieldDefinition(const FieldDefinitionsSharedPtr &fielddefs)
Check field definitions for correctness and return storage size.
Definition: FieldIO.cpp:561
bool m_sharedFilesystem
Boolean dictating whether we are on a shared filesystem.
Definition: FieldIO.h:267
boost::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:55
const std::string kGitSha1
FieldIOType
Enumerator for auto-detection of FieldIO types.
Definition: FieldIO.cpp:83
static const std::string GetFileType(const std::string &filename, CommSharedPtr comm)
Determine file type of given input file.
Definition: FieldIO.cpp:101
#define LIB_UTILITIES_EXPORT
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
boost::shared_ptr< FieldIO > FieldIOSharedPtr
Definition: FieldIO.h:309
const std::string kGitBranch
std::string SetUpOutput(const std::string outname, bool perRank, bool backup=false)
Set up the filesystem ready for output.
Definition: FieldIO.cpp:400
void Write(const std::string &outFile, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, const FieldMetaDataMap &fieldinfomap, const bool backup)
This function allows for data to be written to an FLD file when a session and/or communicator is not ...
Definition: FieldIO.cpp:235
LibUtilities::CommSharedPtr m_comm
Communicator to use when writing parallel format.
Definition: FieldIO.h:265
int getNumberOfCoefficients(int Na, int Nb, int Nc)
Definition: ShapeType.hpp:232
static boost::shared_ptr< FieldIO > CreateDefault(const LibUtilities::SessionReaderSharedPtr session)
Returns an object for the default FieldIO method.
Definition: FieldIO.cpp:181
static boost::shared_ptr< FieldIO > CreateForFile(const LibUtilities::SessionReaderSharedPtr session, const std::string &filename)
Construct a FieldIO object for a given input filename.
Definition: FieldIO.cpp:212
#define NEKTAR_VERSION
Definition: FieldIO.cpp:56
virtual std::string GetFileEnding() const
Helper function that determines default file extension.
Definition: FieldIO.h:279
boost::shared_ptr< TagWriter > TagWriterSharedPtr
Definition: FieldIO.h:71
std::string fldCmdFormat
Definition: FieldIO.cpp:68
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:55
void AddInfoTag(TagWriterSharedPtr root, const FieldMetaDataMap &fieldmetadatamap)
Add provenance information to the field metadata map.
Definition: FieldIO.cpp:334
Provides a generic Factory class.
Definition: NekFactory.hpp:116
FieldIO(LibUtilities::CommSharedPtr pComm, bool sharedFilesystem)
Constructor for FieldIO base class.
Definition: FieldIO.cpp:313