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