Loading...
Searching...
No Matches
ensightSurfaceReader.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2015-2025 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
29#include "ensightCase.H"
30#include "stringOps.H"
32
33// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34
35namespace Foam
36{
39}
40
41
42// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
43
44namespace Foam
45{
46
47// Extract timeset and fileset from split line information
48// when the minElements has been satisfied.
49// For example,
50// ----
51// model: 1 some-geometry
52// model: 1 1 some-geometry
53// ----
54// would be split *after* the 'model:' resulting in these sub-strings:
55//
56// ("1" "some-geometry")
57// ("1" "1" some-geometry")
58//
59// thus call extractTimeset with minElements == 2
60//
61static inline labelPair extractTimeset
62(
63 const SubStrings& split,
64 const std::size_t minElements
65)
66{
67 ISpanStream is;
68
69 labelPair result(-1, -1);
70 if (split.size() >= minElements)
71 {
72 is.reset(split[0]);
73 is >> result.first();
74
75 if (split.size() > minElements)
76 {
77 is.reset(split[1]);
78 is >> result.second();
79 }
80 }
81
82 return result;
84
85} // End namespace Foam
86
87
88// * * * * * * * * * * Protected Static Member Functions * * * * * * * * * * //
89
90bool Foam::ensightSurfaceReader::readLine(ISstream& is, std::string& line)
91{
92 do
93 {
94 is.getLine(line);
95
96 // Trim out any '#' comments (trailing or otherwise)
97 const auto pos = line.find('#');
98 if (pos != std::string::npos)
99 {
100 line.erase(pos);
101 }
104 while (line.empty() && is.good());
105
106 return !line.empty();
107}
108
109
111(
112 const word& expected,
113 const string& buffer,
114 const ISstream& is
115)
116{
117 // Be more generous with our expectations.
118 // Eg, ensight specifies the "VARIABLE" entry,
119 // but accepts "VARIABLES" as well.
120
121 if (!expected.empty() && !buffer.starts_with(expected))
122 {
124 << "Expected section header '" << expected
125 << "' but read " << buffer << nl
126 << exit(FatalIOError);
128
130 << "Read section header: " << buffer.c_str() << nl;
131}
132
133
135(
136 const word& expected,
137 ISstream& is
138)
139{
140 string buffer;
141 readLine(is, buffer);
142
143 checkSection(expected, buffer, is);
144}
145
146
147// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
148
151(
153) const
154{
155 string buffer;
156
157 Pair<idTypes> idHandling(idTypes::NONE, idTypes::NONE);
158
159 // Ensight Geometry File
160 is.read(buffer);
161 DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
162
163 // Description - 1
164 is.read(buffer);
165 DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
166
167 // "node id (off|assign|given|ignore)" - "given" is not actually supported
168 is.read(buffer);
169 DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
170
171 if (buffer.contains("ignore"))
172 {
173 idHandling.first() = idTypes::IGNORE;
174 }
175 else if (buffer.contains("given"))
176 {
177 idHandling.first() = idTypes::GIVEN;
178 }
179
180 // "element id (off|assign|given|ignore)"
181 is.read(buffer);
182 DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
183
184 if (buffer.contains("ignore"))
185 {
186 idHandling.second() = idTypes::IGNORE;
187 }
188 else if (buffer.contains("given"))
189 {
190 idHandling.second() = idTypes::GIVEN;
191 }
192
193
194 // "part" - but could also be an optional "extents"
195 is.read(buffer);
196 DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
197
198 if (buffer.contains("extents"))
199 {
200 // Optional extents - read and discard 6 floats
201 // (xmin, xmax, ymin, ymax, zmin, zmax)
202
203 is.skip<scalar>(6);
204
205 // "part"
206 is.read(buffer);
207 DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
208 }
209
210 // The part number
211 label intValue;
212 is.read(intValue);
213 DebugInfo<< "part number: " << intValue << nl;
214
215 // Part description / name
216 is.read(buffer);
217 DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
218
219 // "coordinates"
220 is.read(buffer);
221 DebugInfo<< "buffer [" << buffer.length() << "] " << buffer << nl;
222
223 return idHandling;
224}
225
226
228{
230
231 enum ParseSection { UNKNOWN, FORMAT, GEOMETRY, VARIABLE, TIME, FILE };
232
233 if (!is.good())
234 {
236 << "Cannot read file " << is.name()
237 << exit(FatalError);
238 }
239
240 string buffer;
242
243 ParseSection parseState = ParseSection::UNKNOWN;
244
245 // FORMAT
246 // ~~~~~~
247
248 debugSection("FORMAT", is);
249 readLine(is, buffer); // type: ensight gold
250 parseState = ParseSection::FORMAT;
251
252 // GEOMETRY
253 // ~~~~~~~~
254 debugSection("GEOMETRY", is);
255 parseState = ParseSection::GEOMETRY;
256
257 do
258 {
259 readLine(is, buffer);
260
261 if (buffer.starts_with("VARIABLE"))
262 {
263 parseState = ParseSection::VARIABLE;
264 break;
265 }
266
267 if (buffer.contains("change_coords_only"))
268 {
270 << "No support for moving points, only topology change" << nl
271 << exit(FatalIOError);
272 }
273
274 // Extract filename from GEOMETRY section
275 // ====
276 // model: [ts] [fs] filename [change_coords_only [cstep]]
277 //
278 // ====
279
280 // TBD:
281 // check for "model:" vs "measured:" ?
282
283 const auto pos_colon = buffer.find(':');
284
285 if
286 (
287 (pos_colon == std::string::npos)
288 )
289 {
291 << "Error reading geometry 'model:'" << nl
292 << exit(FatalIOError);
293 }
294
295 split = stringOps::splitSpace(buffer, pos_colon+1);
296
297 if (split.empty())
298 {
300 << "Error reading geometry 'model:'" << nl
301 << exit(FatalIOError);
302 }
303
304 // With timeset? - need at least 2 entries
305 meshTimeset_ = extractTimeset(split, 2);
306 meshFileName_ = split[split.size()-1].str();
307
308 DebugInfo << "mesh file:" << meshFileName_ << endl;
309 }
310 while (false);
311
312
313 if (parseState != ParseSection::VARIABLE)
314 {
315 debugSection("VARIABLE", is);
316 parseState = ParseSection::VARIABLE;
317 }
318
319 // Read the field description
320 DynamicList<labelPair> dynFieldTimesets(16);
321 DynamicList<word> dynFieldNames(16);
322 DynamicList<string> dynFieldFileNames(16);
323
324 // VARIABLE
325 // ~~~~~~~~
326
327 while (is.good())
328 {
329 readLine(is, buffer);
330
331 if (buffer.starts_with("TIME"))
332 {
333 parseState = ParseSection::TIME;
334 break;
335 }
336
337 // Read the field name and associated file name.
338 // Eg,
339 // scalar per element: [ts] [fs] p data/********/p
340 // but ignore
341 // scalar per node: [ts] [fs] other data/********/other
342
343 const auto pos_colon = buffer.find(':');
344
345 if (pos_colon == std::string::npos)
346 {
347 DebugInfo<< "ignore variable line: " << buffer << nl;
348 continue;
349 }
350
351 // TODO? handle variable descriptions with spaces (they are quoted)
352
353 split = stringOps::splitSpace(buffer, pos_colon+1);
354
355 if (split.size() < 2)
356 {
358 << "Error reading field file name, variable line: "
359 << buffer << endl;
360 continue;
361 }
362
363 auto pos_key = buffer.find("element");
364 if ((pos_key == std::string::npos) || (pos_colon < pos_key))
365 {
366 DebugInfo<< "ignore variable line: " << buffer << nl;
367 continue;
368 }
369
370 DebugInfo<< "variable line: " << buffer << nl;
371
372 // With timeset? - need at least 3 entries
373 dynFieldTimesets.push_back(extractTimeset(split, 3));
374
375 dynFieldNames.push_back(split[split.size()-2].str());
376 dynFieldFileNames.push_back(split[split.size()-1].str());
377 }
378 fieldTimesets_.transfer(dynFieldTimesets);
379 fieldNames_.transfer(dynFieldNames);
380 fieldFileNames_.transfer(dynFieldFileNames);
381
383 << "fieldNames: " << fieldNames_ << nl
384 << "fieldFileNames: " << fieldFileNames_ << nl;
385
386
387 if (parseState != ParseSection::TIME)
388 {
390 << "Did not find section header 'TIME'" << nl
391 << exit(FatalIOError);
392 }
393
394
395 // Determine which unique timeset or fileset to expect
396
397 labelHashSet expectTimeset;
398 labelHashSet expectFileset;
399
400 expectTimeset.insert(meshTimeset_.first());
401 expectFileset.insert(meshTimeset_.second());
402
403 for (const auto& tup : fieldTimesets_)
404 {
405 expectTimeset.insert(tup.first());
406 expectFileset.insert(tup.second());
407 }
408
409 // Remove placeholders
410 expectTimeset.erase(-1);
411 expectFileset.erase(-1);
412
413
415 << "expect timesets: " << flatOutput(expectTimeset) << nl
416 << "expect filesets: " << flatOutput(expectFileset) << nl;
417
418
419 // TIME
420 // ~~~~
421 // style 1:
422 // ====
423 // time set: <int> [description]
424 // number of steps: <int>
425 // filename start number: <int>
426 // filename increment: <int>
427 // time values: time_1 .. time_N
428 // ====
429 //
430 // style 2:
431 // ====
432 // time set: <int> [description]
433 // number of steps: <int>
434 // filename numbers: int_1 .. int_N
435 // time values: time_1 .. time_N
436 // ====
437 //
438 // style 3:
439 // ====
440 // time set: <int> [description]
441 // number of steps: <int>
442 // filename numbers file: <filename>
443 // time values file: <filename>
444 // ====
445
446
447 // Currently only handling style 1, style 2
448 // and only a single time set
449
450 // time set = 1
451 {
452 // time set: <int>
453 {
454 readLine(is, buffer);
455 }
456
457 // number of steps: <int>
458 label nTimes = 0;
459 {
460 readLine(is, buffer);
462 readFrom(split.back(), nTimes);
463 }
464
465 // filename start number: <int>
466 // filename increment: <int>
467 //
468 // OR:
469 // filename numbers: ...
470
471 readLine(is, buffer);
472 auto pos_colon = buffer.find(':');
473
474 if (buffer.contains("numbers:"))
475 {
476 // Split out trailing values...
477 split = stringOps::splitSpace(buffer, pos_colon+1);
478
479 fileNumbers_.resize_nocopy(nTimes);
480
481 label numRead = 0;
482 while (numRead < nTimes)
483 {
484 for (const auto& chunk : split)
485 {
486 std::string str(chunk.str());
487
488 if (!Foam::readLabel(str, fileNumbers_[numRead]))
489 {
491 << "Could not parse label: " << str << nl
492 << exit(FatalIOError);
493 }
494 ++numRead;
495
496 if (numRead == nTimes)
497 {
498 break;
499 }
500 }
501
502 // Get more input
503 if (numRead < nTimes)
504 {
505 readLine(is, buffer);
507 }
508 }
509
510 timeStartIndex_ = 0;
511 timeIncrement_ = 0;
512 fileNumbers_.resize(numRead);
513 }
514 else
515 {
516 // filename start number: <int>
518 readFrom(split.back(), timeStartIndex_);
519
520 // filename increment: <int>
521 readLine(is, buffer);
523 readFrom(split.back(), timeIncrement_);
524
525 fileNumbers_.clear();
526 }
527
529 << "nTimes: " << nTimes
530 << " start-index: " << timeStartIndex_
531 << " increment: " << timeIncrement_
532 << " file numbers: " << flatOutput(fileNumbers_) << nl;
533
534
535 // time values: time_1 .. time_N
536 readLine(is, buffer);
537
538 // Split out trailing values...
539 {
540 const auto pos_colon = buffer.find(':');
541 const auto pos_key = buffer.find("values");
542
543 if
544 (
545 (pos_colon == std::string::npos)
546 || (pos_key == std::string::npos) || (pos_colon < pos_key)
547 )
548 {
549 split.clear();
550 }
551 else
552 {
553 split = stringOps::splitSpace(buffer, pos_colon+1);
554 }
555 }
556
557 timeValues_.resize_nocopy(nTimes);
558
559 label numRead = 0;
560 while (numRead < nTimes)
561 {
562 for (const auto& chunk : split)
563 {
564 auto& inst = timeValues_[numRead];
565
566 // Retain character representation
567 inst.name() = word(chunk.str());
568
569 if (!Foam::readScalar(inst.name(), inst.value()))
570 {
572 << "Could not parse scalar: " << inst.name() << nl
573 << exit(FatalIOError);
574 }
575 ++numRead;
576
577 if (numRead == nTimes)
578 {
579 break;
580 }
581 }
582
583 // Get more input
584 if (numRead < nTimes)
585 {
586 readLine(is, buffer);
588 }
589 }
590
591 timeValues_.resize(numRead);
592 }
593
594 // Not yet:
595
596 // FILE
597 // ~~~~
598 // file set: <int>
599 // filename index: <int> - file index number in the file name
600 // number of steps: <int>
601}
602
603
604// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
605
607(
608 const fileName& fName,
609 const dictionary& options
610)
611:
612 surfaceReader(fName, options),
613 masterOnly_
614 (
615 UPstream::parRun()
616 && options.getOrDefault("masterOnly", false)
617 ),
618 readFormat_(IOstreamOption::ASCII), // Placeholder value
619 baseDir_(fName.path()),
620 meshTimeset_(-1,-1),
621 timeStartIndex_(0),
622 timeIncrement_(1)
623{
624 if (options.getOrDefault("debug", false))
625 {
626 debug |= 1;
627 }
628
630 {
631 IFstream is(fName);
632 readCase(is);
633 }
634
636 {
638 (
649 );
650 }
651}
652
653
654// * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
655
657(
658 const fileName& geometryFile,
659 const label timeIndex
660)
661{
663
664 {
665 // Auto-detect ascii/binary format
666 ensightReadFile is(geometryFile);
667
668 // Format detected from the geometry
669 readFormat_ = is.format();
670
671 // For transient single-file
672 is.seekTime(timeIndex);
673
675 << "File: " << is.name()
676 << " format: "
677 << IOstreamOption::formatNames[readFormat_] << endl;
678
679 Pair<idTypes> idHandling = readGeometryHeader(is);
680
681 label nPoints;
682 is.read(nPoints);
683
685 << "nPoints: " << nPoints << nl;
686
687 if (idHandling.first() == idTypes::GIVEN)
688 {
690 << "Treating node id 'given' as being 'ignore'" << nl
691 << "If something fails, this could be the reason" << nl
692 << endl;
693
694 idHandling.first() = idTypes::IGNORE;
695 }
696
697 if (idHandling.first() == idTypes::IGNORE)
698 {
700 << "Ignore " << nPoints << " node ids" << nl;
701
702 // Read and discard labels
703 is.skip<label>(nPoints);
704 }
705
707 is.readPoints(nPoints, points);
708
709
710 // Read faces - may be a mix of tria3, quad4, nsided
711 DynamicList<face> dynFaces(nPoints/3);
712 DynamicList<faceInfoTuple> faceTypeInfo(16);
713
714 string buffer;
715
716 while (is.good())
717 {
718 // The element type
719 is.read(buffer);
720
721 if (!is.good())
722 {
723 break;
724 }
725 else if (buffer.contains("BEGIN TIME STEP"))
726 {
727 // Graciously handle a miscued start
728 continue;
729 }
730 else if (buffer.contains("END TIME STEP"))
731 {
732 // END TIME STEP is a valid means to terminate input
733 break;
734 }
735
736 if
737 (
738 buffer
740 )
741 {
742 label elemCount;
743 is.read(elemCount);
744
745 faceTypeInfo.emplace_back
746 (
748 elemCount
749 );
750
752 << "faceType <"
754 << "> count: "
755 << elemCount << nl;
756
757 if
758 (
759 idHandling.second() == idTypes::IGNORE
760 || idHandling.second() == idTypes::GIVEN
761 )
762 {
764 << "Ignore " << elemCount << " element ids" << nl;
765
766 // Read and discard labels
767 is.skip<label>(elemCount);
768 }
769
770 // Extend and fill the new trailing portion
771 const label startElemi = dynFaces.size();
772 dynFaces.resize(startElemi+elemCount, face(3)); // tria3
773 faceList::subList myElements = dynFaces.slice(startElemi);
774
775 for (auto& f : myElements)
776 {
777 for (label& fp : f)
778 {
779 is.read(fp);
780 }
781 }
782 }
783 else if
784 (
785 buffer
787 )
788 {
789 label elemCount;
790 is.read(elemCount);
791
792 faceTypeInfo.emplace_back
793 (
795 elemCount
796 );
797
799 << "faceType <"
801 << "> count: "
802 << elemCount << nl;
803
804 if
805 (
806 idHandling.second() == idTypes::IGNORE
807 || idHandling.second() == idTypes::GIVEN
808 )
809 {
811 << "Ignore " << elemCount << " element ids" << nl;
812
813 // Read and discard labels
814 is.skip<label>(elemCount);
815 }
816
817 // Extend and fill the new trailing portion
818 const label startElemi = dynFaces.size();
819 dynFaces.resize(startElemi + elemCount, face(4)); // quad4
820 faceList::subList myElements = dynFaces.slice(startElemi);
821
822 for (auto& f : myElements)
823 {
824 for (label& fp : f)
825 {
826 is.read(fp);
827 }
828 }
829 }
830 else if
831 (
832 buffer
834 )
835 {
836 label elemCount;
837 is.read(elemCount);
838
839 faceTypeInfo.emplace_back
840 (
842 elemCount
843 );
844
846 << "faceType <"
848 << "> count: " << elemCount << nl;
849
850 if
851 (
852 idHandling.second() == idTypes::IGNORE
853 || idHandling.second() == idTypes::GIVEN
854 )
855 {
857 << "Ignore " << elemCount << " element ids" << nl;
858
859 // Read and discard labels
860 is.skip<label>(elemCount);
861 }
862
863 // Extend and fill the new trailing portion
864 const label startElemi = dynFaces.size();
865 dynFaces.resize(startElemi + elemCount);
866 faceList::subList myElements = dynFaces.slice(startElemi);
867
868 for (auto& f : myElements)
869 {
870 label nVerts;
871 is.read(nVerts);
872
873 f.resize(nVerts);
874 }
875
876 for (auto& f : myElements)
877 {
878 for (label& fp : f)
879 {
880 is.read(fp);
881 }
882 }
883 }
884 else
885 {
886 if (debug)
887 {
889 << "Unknown face type: <" << buffer.c_str()
890 << ">. Stopping read and continuing with current "
891 << "elements only" << endl;
892 }
893 break;
894 }
895 }
896
897 // From 1-based Ensight addressing to 0-based OF addressing
898 for (auto& f : dynFaces)
899 {
900 for (label& fp : f)
901 {
902 --fp;
903 }
904 }
905
906 faceTypeInfo_.transfer(faceTypeInfo);
907 faceList faces(std::move(dynFaces));
908
910 << "read nFaces: " << faces.size() << nl
911 << "file schema: " << faceTypeInfo_ << nl;
912
913 return meshedSurface(std::move(points), std::move(faces));
914 }
915}
916
917
919(
920 const label timeIndex
921)
922{
924
925 if (!surfPtr_)
926 {
927 surfPtr_.reset(new meshedSurface);
928 auto& surf = *surfPtr_;
929
930 fileName geomFile
931 (
932 baseDir_
933 / ensightCase::expand_mask(meshFileName_, timeIndex)
934 );
935
936 if (!masterOnly_ || UPstream::master(UPstream::worldComm))
937 {
938 surf = readGeometry(geomFile, timeIndex);
939 }
940
941 if (masterOnly_ && UPstream::parRun())
942 {
943 // Note: don't need faceTypeInfo_ on (non-reading) ranks
946 }
947
948 return *surfPtr_;
949}
950
953{
954 return timeValues_;
955}
956
957
959(
960 const label timeIndex
961) const
962{
963 return fieldNames_;
964}
965
966
968(
969 const label timeIndex,
970 const label fieldIndex,
971 const scalar& refValue
972) const
973{
974 return readField<scalar>(timeIndex, fieldIndex);
975}
976
977
979(
980 const label timeIndex,
981 const label fieldIndex,
982 const vector& refValue
992 const label timeIndex,
993 const label fieldIndex,
994 const sphericalTensor& refValue
995) const
996{
997 return readField<sphericalTensor>(timeIndex, fieldIndex);
998}
999
1000
1002(
1003 const label timeIndex,
1004 const label fieldIndex,
1005 const symmTensor& refValue
1006) const
1007{
1008 return readField<symmTensor>(timeIndex, fieldIndex);
1009}
1010
1011
1013(
1014 const label timeIndex,
1015 const label fieldIndex,
1016 const tensor& refValue
1017) const
1018{
1019 return readField<tensor>(timeIndex, fieldIndex);
1020}
1021
1022
1023// ************************************************************************* //
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
if(patchID !=-1)
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
T & emplace_back(Args &&... args)
Construct an element at the end of the list, return reference to the new list element.
void push_back(const T &val)
Copy append an element to the end of this list.
void resize(const label len)
Alter addressable list size, allocating new space if required while recovering old content.
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition HashSet.H:229
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition HashTable.C:489
Input from file stream as an ISstream, normally using std::ifstream for the actual input.
Definition IFstream.H:55
virtual const fileName & name() const override
Read/write access to the name of the stream.
Definition ISstream.H:147
A simple container for options an IOstream can normally have.
streamFormat format() const noexcept
Get the current stream format.
static const Enum< streamFormat > formatNames
Stream format names (ascii, binary).
bool good() const noexcept
True if next operation might succeed.
Definition IOstream.H:281
Similar to IStringStream but using an externally managed buffer for its input. This allows the input ...
void reset(const char *buffer, size_t nbytes)
Reset input area, position to buffer start and clear errors.
Generic input stream using a standard (STL) stream.
Definition ISstream.H:54
virtual const fileName & name() const override
The name of the input serial stream. (eg, the name of the Fstream file name).
Definition ISstream.H:147
ISstream & getLine(std::string &str, char delim='\n')
Raw, low-level getline (until delimiter) into a string.
Definition ISstreamI.H:69
virtual Istream & read(token &t) override
Return next token from stream.
Definition ISstream.C:535
SubList< face > subList
Definition List.H:129
void resize(const label len)
Adjust allocated size of list.
Definition ListI.H:153
An ordered pair of two objects of type <T> with first() and second() elements.
Definition Pair.H:66
const T & first() const noexcept
Access the first element.
Definition Pair.H:137
const T & second() const noexcept
Access the second element.
Definition Pair.H:147
static void broadcasts(const int communicator, Type &value, Args &&... values)
Broadcast multiple items to all communicator ranks. Does nothing in non-parallel.
Sub-ranges of a string with a structure similar to std::match_results, but without the underlying reg...
Definition SubStrings.H:49
SubList< T > slice(const label pos, label len=-1)
Return SubList slice (non-const access) - no range checking.
Definition SubList.H:258
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
Inter-processor communications stream.
Definition UPstream.H:69
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
Definition UPstream.H:1669
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition UPstream.H:1069
@ broadcast
broadcast [MPI]
Definition UPstream.H:189
static bool & parRun() noexcept
Test if this a parallel run.
Definition UPstream.H:1681
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
static StringType expand_mask(const StringType &input, const label index)
Replace the '*' mask chars with zero-padded integer value.
static const char * elemNames[nTypes]
The ensight 'Face' element type names.
A variant of IFstream with specialised handling for Ensight reading of strings, integers and floats (...
bool seekTime(const label timeIndex)
Transient single-file: seek to the file position corresponding to the given time index.
void skip(label n=1)
Read and discard specified number of elements.
void readPoints(const label nPoints, List< floatVector > &points)
Component-wise reading of points/coordinates. Read all x components, y components and z components.
virtual Istream & read(char *buf, std::streamsize count) override
Binary read.
Ensight format surface reader.
static bool readLine(ISstream &is, std::string &line)
Helper function to read an ascii line from file, skipping blank lines and comments.
virtual instantList times() const
Return a list of the available times.
static void checkSection(const word &expected, const string &buffer, const ISstream &is)
Check a section header.
Pair< idTypes > readGeometryHeader(ensightReadFile &is) const
Read (and discard) geometry file header.
label timeIncrement_
Time increment.
virtual tmp< Field< scalar > > field(const label timeIndex, const label fieldIndex, const scalar &refValue=pTraits< scalar >::zero) const
Return a scalar field at a given time.
labelList fileNumbers_
Numbers for files.
bool masterOnly_
Read on master and broadcast (in parallel).
labelPair meshTimeset_
The timeset/fileset (if any) associated with the mesh.
@ GIVEN
Use "given" values (not supported).
void readCase(ISstream &is)
Read the case file.
static void debugSection(const word &expected, ISstream &is)
Read and check a section header.
fileName baseDir_
Base directory.
List< word > fieldNames_
Field names.
autoPtr< meshedSurface > surfPtr_
Pointer to the surface.
List< labelPair > fieldTimesets_
The timeset/fileset (if any) associated with fields.
meshedSurface readGeometry(const fileName &geometryFile, const label timeIndex=0)
Read and return surface geometry. Updates faceTypeInfo_.
virtual const meshedSurface & geometry(const label timeIndex)
Return a reference to the surface geometry.
label timeStartIndex_
Start time index.
IOstreamOption::streamFormat readFormat_
Format flag.
List< faceInfoTuple > faceTypeInfo_
List of face-type/count tuples.
List< string > fieldFileNames_
Field file names.
ensightSurfaceReader(const ensightSurfaceReader &)=delete
No copy construct.
fileName meshFileName_
Name of mesh file, including any subdirectory.
virtual wordList fieldNames(const label timeIndex) const
Return a list of the available fields at a given time.
static void readFrom(const std::string &buffer, Type &value)
Helper function to return Type from string.
tmp< Field< Type > > readField(const fileName &dataFile, const word &fieldName, const label timeIndex=0) const
Helper function to return a field.
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
A class for handling file names.
Definition fileName.H:75
A line primitive.
Definition line.H:180
static std::string::size_type length(const char *s)
Length of the character sequence (with nullptr protection).
Definition string.H:259
bool contains(char c) const noexcept
True if string contains given character (cf. C++23).
Definition string.H:412
bool starts_with(char c) const
True if string starts with given character (cf. C++20).
Definition string.H:436
Abstract base class for surface readers with fields.
surfaceReader(const fileName &fName)
Construct from fileName.
A class for managing temporary objects.
Definition tmp.H:75
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
static bool split(const std::string &line, std::string &key, std::string &val)
Definition cpuInfo.C:32
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
const pointField & points
label nPoints
#define DebugInfo
Report an information message using Foam::Info.
#define WarningInFunction
Report a warning using Foam::Warning.
#define DebugInFunction
Report an information message using Foam::Info.
Namespace for handling debugging switches.
Definition debug.C:45
Foam::SubStrings splitSpace(const std::string &str, std::string::size_type pos=0)
Split string into sub-strings at whitespace (TAB, NL, VT, FF, CR, SPC).
void inplaceTrimRight(std::string &s)
Trim trailing whitespace inplace.
Namespace for OpenFOAM.
dimensionedScalar pos(const dimensionedScalar &ds)
Pair< label > labelPair
A pair of labels.
Definition Pair.H:54
List< word > wordList
List of word.
Definition fileName.H:60
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition HashSet.H:85
static labelPair extractTimeset(const SubStrings &split, const std::size_t minElements)
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition label.H:63
List< face > faceList
List of faces.
Definition faceListFwd.H:41
List< instant > instantList
List of instants.
Definition instantList.H:41
Tensor< scalar > tensor
Definition symmTensor.H:57
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
MeshedSurface< face > meshedSurface
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition FlatOutput.H:217
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
vectorField pointField
pointField is a vectorField.
Vector< scalar > vector
Definition vector.H:57
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
SphericalTensor< scalar > sphericalTensor
SphericalTensor of scalars, i.e. SphericalTensor<scalar>.
SymmTensor< scalar > symmTensor
SymmTensor of scalars, i.e. SymmTensor<scalar>.
Definition symmTensor.H:55
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
label timeIndex
labelList f(nPoints)