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