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