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