sampledSets.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) 2011 OpenFOAM Foundation
9 Copyright (C) 2015-2022 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "sampledSets.H"
30#include "dictionary.H"
31#include "Time.H"
32#include "globalIndex.H"
33#include "volFields.H"
34#include "mapPolyMesh.H"
35#include "IOmanip.H"
36#include "IOobjectList.H"
37#include "IndirectList.H"
38#include "ListOps.H"
40
41// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42
43namespace Foam
44{
46
48 (
52 );
53}
54
55#include "sampledSetsImpl.C"
56
57// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
58
59Foam::autoPtr<Foam::coordSetWriter> Foam::sampledSets::newWriter
60(
61 word writeType,
62 const dictionary& formatOptions,
63 const dictionary& setDict
64)
65{
66 // Per-set adjustment
67 setDict.readIfPresent<word>("setFormat", writeType);
68
69 dictionary options = formatOptions.subOrEmptyDict(writeType);
70
71 options.merge
72 (
73 setDict.subOrEmptyDict("formatOptions").subOrEmptyDict(writeType)
74 );
75
76 return coordSetWriter::New(writeType, options);
77}
78
79
80Foam::OFstream* Foam::sampledSets::createProbeFile(const word& fieldName)
81{
82 // Open new output stream
83
84 OFstream* osptr = probeFilePtrs_.lookup(fieldName, nullptr);
85
86 if (!osptr && Pstream::master())
87 {
88 // Put in undecomposed case
89 // (Note: gives problems for distributed data running)
90
91 fileName probeDir
92 (
93 mesh_.time().globalPath()
95 / name()/mesh_.regionName()
96 // Use startTime as the instance for output files
97 / mesh_.time().timeName(mesh_.time().startTime().value())
98 );
99 probeDir.clean(); // Remove unneeded ".."
100
101 // Create directory if needed
102 Foam::mkDir(probeDir);
103
104 probeFilePtrs_.insert
105 (
106 fieldName,
107 autoPtr<OFstream>::New(probeDir/fieldName)
108 );
109 osptr = probeFilePtrs_.lookup(fieldName, nullptr);
110
111 if (osptr)
112 {
113 auto& os = *osptr;
114
115 DebugInfo<< "open probe stream: " << os.name() << endl;
116
117 const unsigned int width(IOstream::defaultPrecision() + 7);
118
119 label nPoints = 0;
120 forAll(*this, seti)
121 {
122 const coordSet& s = gatheredSets_[seti];
123
124 const pointField& pts = static_cast<const pointField&>(s);
125
126 for (const point& p : pts)
127 {
128 os << "# Probe " << nPoints++ << ' ' << p << nl;
129 }
130 }
131
132 os << '#' << setw(IOstream::defaultPrecision() + 6)
133 << "Probe";
134
135 for (label probei = 0; probei < nPoints; ++probei)
136 {
137 os << ' ' << setw(width) << probei;
138 }
139 os << nl;
140
141 os << '#' << setw(IOstream::defaultPrecision() + 6)
142 << "Time" << endl;
143 }
144 }
145
146 return osptr;
147}
148
149
150void Foam::sampledSets::gatherAllSets()
151{
152 // Any writer references will become invalid
153 for (auto& writer : writers_)
154 {
155 writer.expire();
156 }
157
158 const PtrList<sampledSet>& localSets = *this;
159
160 gatheredSets_.clear();
161 gatheredSets_.resize(localSets.size());
162 gatheredSorting_.resize_nocopy(localSets.size());
163 globalIndices_.resize_nocopy(localSets.size());
164
165 forAll(localSets, seti)
166 {
167 const coordSet& coords = localSets[seti];
168
169 globalIndices_[seti].reset(coords.size(), globalIndex::gatherOnly{});
170 gatheredSets_.set(seti, coords.gatherSort(gatheredSorting_[seti]));
171 }
172}
173
174
175Foam::IOobjectList Foam::sampledSets::preCheckFields(unsigned request)
176{
177 wordList allFields; // Just needed for warnings
178 HashTable<wordHashSet> selected;
179
180 IOobjectList objects(0);
181
182 if (loadFromFiles_)
183 {
184 // Check files for a particular time
185 objects = IOobjectList(mesh_, mesh_.time().timeName());
186
187 allFields = objects.names();
188 selected = objects.classes(fieldSelection_);
189 }
190 else
191 {
192 // Check currently available fields
193 allFields = mesh_.names();
194 selected = mesh_.classes(fieldSelection_);
195 }
196
197 // Parallel consistency (no-op in serial)
198 // Probably not needed...
200
201
202 DynamicList<label> missed(fieldSelection_.size());
203
204 // Detect missing fields
205 forAll(fieldSelection_, i)
206 {
207 if
208 (
209 fieldSelection_[i].isLiteral()
210 && !ListOps::found(allFields, fieldSelection_[i])
211 )
212 {
213 missed.append(i);
214 }
215 }
216
217 if (missed.size() && (request != ACTION_NONE))
218 {
220 << nl
221 << "Cannot find "
222 << (loadFromFiles_ ? "field file" : "registered field")
223 << " matching "
224 << UIndirectList<wordRe>(fieldSelection_, missed) << endl;
225 }
226
227
228 // The selected field names, ordered by (scalar, vector, ...)
229 // with internal sorting
230
231 selectedFieldNames_.clear();
232
233 do
234 {
235 #undef doLocalCode
236 #define doLocalCode(InputType) \
237 { \
238 const auto iter = selected.find(InputType::typeName); \
239 if (iter.found()) \
240 { \
241 selectedFieldNames_.append(iter.val().sortedToc()); \
242 } \
243 }
244
250 #undef doLocalCode
251 }
252 while (false);
253
254
255 // Now propagate field counts (per surface)
256 // - can update writer even when not writing without problem
257
258 const label nFields = selectedFieldNames_.size();
259
260 if (writeAsProbes_)
261 {
262 // Close streams for fields that no longer exist
263 forAllIters(probeFilePtrs_, iter)
264 {
265 if (!selectedFieldNames_.found(iter.key()))
266 {
268 << "close probe stream: "
269 << iter()->name() << endl;
270
271 probeFilePtrs_.remove(iter);
272 }
273 }
274 }
275 else if ((request & ACTION_WRITE) != 0)
276 {
277 forAll(writers_, seti)
278 {
279 coordSetWriter& writer = writers_[seti];
280
281 writer.nFields(nFields);
282 }
283 }
284
285 return objects;
286}
287
288
289void Foam::sampledSets::initDict(const dictionary& dict, const bool initial)
290{
292 if (initial)
293 {
294 writers_.clear();
295 }
296
297 const entry* eptr = dict.findEntry("sets");
298
299 if (eptr && eptr->isDict())
300 {
301 PtrList<sampledSet> sampSets(eptr->dict().size());
302 if (initial && !writeAsProbes_)
303 {
304 writers_.resize(sampSets.size());
305 }
306
307 label seti = 0;
308
309 for (const entry& dEntry : eptr->dict())
310 {
311 if (!dEntry.isDict())
312 {
313 continue;
314 }
315
316 const dictionary& subDict = dEntry.dict();
317
318 autoPtr<sampledSet> sampSet =
320 (
321 dEntry.keyword(),
322 mesh_,
323 searchEngine_,
324 subDict
325 );
326
327 // if (!sampSet || !sampSet->enabled())
328 // {
329 // continue;
330 // }
331
332 // Define the set
333 sampSets.set(seti, sampSet);
334
335 // Define writer, but do not attached
336 if (initial && !writeAsProbes_)
337 {
338 writers_.set
339 (
340 seti,
341 newWriter(writeFormat_, writeFormatOptions_, subDict)
342 );
343
344 // Use outputDir/TIME/set-name
345 writers_[seti].useTimeDir(true);
346 writers_[seti].verbose(verbose_);
347 }
348 ++seti;
349 }
350
351 sampSets.resize(seti);
352 if (initial && !writeAsProbes_)
353 {
354 writers_.resize(seti);
355 }
356 static_cast<PtrList<sampledSet>&>(*this).transfer(sampSets);
357 }
358 else if (eptr)
359 {
360 // This is slightly trickier.
361 // We want access to the individual dictionaries used for construction
362
363 DynamicList<dictionary> capture;
364
365 PtrList<sampledSet> input
366 (
367 eptr->stream(),
368 sampledSet::iNewCapture(mesh_, searchEngine_, capture)
369 );
370
371 PtrList<sampledSet> sampSets(input.size());
372 if (initial && !writeAsProbes_)
373 {
374 writers_.resize(sampSets.size());
375 }
376
377 label seti = 0;
378
379 forAll(input, inputi)
380 {
381 const dictionary& subDict = capture[inputi];
382
383 autoPtr<sampledSet> sampSet = input.release(inputi);
384
385 // if (!sampSet || !sampSet->enabled())
386 // {
387 // continue;
388 // }
389
390 // Define the set
391 sampSets.set(seti, sampSet);
392
393 // Define writer, but do not attached
394 if (initial && !writeAsProbes_)
395 {
396 writers_.set
397 (
398 seti,
399 newWriter(writeFormat_, writeFormatOptions_, subDict)
400 );
401
402 // Use outputDir/TIME/set-name
403 writers_[seti].useTimeDir(true);
404 writers_[seti].verbose(verbose_);
405 }
406 ++seti;
407 }
408
409 sampSets.resize(seti);
410 if (initial && !writeAsProbes_)
411 {
412 writers_.resize(seti);
413 }
414
415 static_cast<PtrList<sampledSet>&>(*this).transfer(sampSets);
416 }
417
418 gatherAllSets();
419
420 needsCorrect_ = false;
421}
422
423
424// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
425
427(
428 const word& name,
429 const Time& runTime,
430 const dictionary& dict
431)
432:
433 functionObjects::fvMeshFunctionObject(name, runTime, dict),
435 dict_(dict),
436 loadFromFiles_(false),
437 verbose_(false),
438 onExecute_(false),
439 needsCorrect_(false),
440 writeAsProbes_(false),
441 outputPath_
442 (
443 time_.globalPath()/functionObject::outputPrefix
444 / name/mesh_.regionName()
445 ),
446 searchEngine_(mesh_),
447 samplePointScheme_(),
448 writeFormat_(),
449 writeFormatOptions_(dict.subOrEmptyDict("formatOptions")),
450 selectedFieldNames_(),
451 writers_(),
452 probeFilePtrs_(),
453 gatheredSets_(),
454 gatheredSorting_(),
455 globalIndices_()
456{
457 outputPath_.clean(); // Remove unneeded ".."
458
459 read(dict);
460}
461
462
464(
465 const word& name,
466 const objectRegistry& obr,
467 const dictionary& dict,
468 const bool loadFromFiles
469)
470:
471 functionObjects::fvMeshFunctionObject(name, obr, dict),
473 dict_(dict),
474 loadFromFiles_(loadFromFiles),
475 verbose_(false),
476 onExecute_(false),
477 needsCorrect_(false),
478 writeAsProbes_(false),
479 outputPath_
480 (
481 time_.globalPath()/functionObject::outputPrefix
482 / name/mesh_.regionName()
483 ),
484 searchEngine_(mesh_),
485 samplePointScheme_(),
486 writeFormat_(),
487 writeFormatOptions_(dict.subOrEmptyDict("formatOptions")),
488 selectedFieldNames_(),
489 writers_(),
490 probeFilePtrs_(),
491 gatheredSets_(),
492 gatheredSorting_(),
493 globalIndices_()
494{
495 outputPath_.clean(); // Remove unneeded ".."
496
497 read(dict);
498}
499
500
501// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
502
503bool Foam::sampledSets::verbose(const bool on) noexcept
504{
505 bool old(verbose_);
506 verbose_ = on;
507 return old;
508}
509
510
512{
513 if (&dict_ != &dict)
514 {
515 // Update local copy of dictionary
516 dict_ = dict;
517 }
518
519 fvMeshFunctionObject::read(dict);
520
522 writers_.clear();
523 fieldSelection_.clear();
524 selectedFieldNames_.clear();
525
526 gatheredSets_.clear();
527 gatheredSorting_.clear();
528 globalIndices_.clear();
529
530 verbose_ = dict.getOrDefault("verbose", false);
531 onExecute_ = dict.getOrDefault("sampleOnExecute", false);
532
533 samplePointScheme_ =
534 dict.getOrDefault<word>("interpolationScheme", "cellPoint");
535
536 const entry* eptr = dict.findEntry("sets");
537
538 if (eptr)
539 {
540 dict.readEntry("setFormat", writeFormat_);
541 }
542
543 // Hard-coded handling of ensemble 'probes' writer
544 writeAsProbes_ = ("probes" == writeFormat_);
545 if (!writeAsProbes_)
546 {
547 // Close all streams
548 probeFilePtrs_.clear();
549 }
550
551 // const dictionary formatOptions(dict.subOrEmptyDict("formatOptions"));
552 // Writer type and format options
553 // const word writerType =
554 // (eptr ? dict.get<word>("setFormat") : word::null);
555 // writerType_ = (eptr ? dict.get<word>("setFormat") : word::null);
556
557 initDict(dict, true);
558
559 // Have some sets, so sort out which fields are needed and report
560
561 if (this->size())
562 {
563 dict_.readEntry("fields", fieldSelection_);
564 fieldSelection_.uniq();
565
566 // Report
567 if (writeAsProbes_)
568 {
569 Info<< "Sampled set as probes ensemble:" << nl;
570
571 forAll(*this, seti)
572 {
573 const sampledSet& s = (*this)[seti];
574 Info<< " " << s.name();
575 }
576 Info<< nl;
577 }
578 else
579 {
580 Info<< "Sampled set:" << nl;
581
582 forAll(*this, seti)
583 {
584 const sampledSet& s = (*this)[seti];
585
586 Info<< " " << s.name() << " -> "
587 << writers_[seti].type() << nl;
588 }
589 }
590
591 Info<< endl;
592 }
593
594 if (debug && Pstream::master())
595 {
596 Pout<< "sample fields:" << flatOutput(fieldSelection_) << nl
597 << "sample sets:" << nl << '(' << nl;
598
599 for
600 (
601 const sampledSet& s
602 : static_cast<const PtrList<sampledSet>&>(*this)
603 )
604 {
605 Pout<< " " << s << endl;
606 }
607 Pout<< ')' << endl;
608 }
609
610 if (writeAsProbes_)
611 {
612 (void) preCheckFields(ACTION_NONE);
613 }
614
615 // FUTURE:
616 // Ensure all sets and merge information are expired
617 // expire(true);
618
619 return true;
620}
621
622
623bool Foam::sampledSets::performAction(unsigned request)
624{
625 if (empty())
626 {
627 // Nothing to do
628 return true;
629 }
630 else if (needsCorrect_)
631 {
632 searchEngine_.correct();
633 initDict(dict_, false);
634 }
635
636 // FUTURE:
637 // Update sets and store
638 // ...
639
640 // Determine availability of fields.
641 // Count number of fields (only seems to be needed for VTK legacy)
642
643 IOobjectList objects = preCheckFields(request);
644
645 const label nFields = selectedFieldNames_.size();
646
647 if (!nFields)
648 {
649 // Nothing to do
650 return true;
651 }
652
653 // Update writers
654 if (!writeAsProbes_)
655 {
656 forAll(*this, seti)
657 {
658 const coordSet& s = gatheredSets_[seti];
659
660 if ((request & ACTION_WRITE) != 0)
661 {
662 coordSetWriter& writer = writers_[seti];
663
664 if (writer.needsUpdate())
665 {
666 writer.setCoordinates(s);
667 }
668
669 if (writer.buffering())
670 {
672 (
673 outputPath_
674 / word
675 (
676 s.name()
677 + coordSetWriter::suffix(selectedFieldNames_)
678 )
679 );
680 }
681 else
682 {
683 writer.open(outputPath_/s.name());
684 }
685
686 writer.beginTime(mesh_.time());
687 }
688 }
689 }
690
691 // Sample fields
692
693 performAction<VolumeField<scalar>>(objects, request);
694 performAction<VolumeField<vector>>(objects, request);
695 performAction<VolumeField<sphericalTensor>>(objects, request);
696 performAction<VolumeField<symmTensor>>(objects, request);
697 performAction<VolumeField<tensor>>(objects, request);
698
699
700 // Finish this time step
701 if (!writeAsProbes_)
702 {
703 forAll(writers_, seti)
704 {
705 // Write geometry if no fields were written so that we still
706 // can have something to look at
707
708 if ((request & ACTION_WRITE) != 0)
709 {
714
715 writers_[seti].endTime();
716 }
717 }
718 }
719
720 return true;
721}
722
723
725{
726 if (onExecute_)
727 {
728 return performAction(ACTION_ALL & ~ACTION_WRITE);
729 }
730
731 return true;
732}
733
734
736{
737 return performAction(ACTION_ALL);
738}
739
740
742{
743 needsCorrect_ = true;
744}
745
746
748{
749 if (&mpm.mesh() == &mesh_)
750 {
751 correct();
752 }
753}
754
755
757{
758 if (&mesh == &mesh_)
759 {
760 correct();
761 }
762}
763
764
766{
767 if (state != polyMesh::UNCHANGED)
768 {
769 correct();
770 }
771}
772
773
774// ************************************************************************* //
Istream and Ostream manipulators taking arguments.
Various functions to operate on Lists.
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
vtk::internalMeshWriter writer(topoMesh, topoCells, vtk::formatType::INLINE_ASCII, runTime.path()/"blockTopology")
List of IOobjects with searching and retrieving facilities.
Definition: IOobjectList.H:59
static unsigned int defaultPrecision() noexcept
Return the default precision.
Definition: IOstream.H:342
Output to file stream, using an OSstream.
Definition: OFstream.H:57
virtual const fileName & name() const
Read/write access to the name of the stream.
Definition: OSstream.H:107
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: PtrList.H:73
void clear()
Clear the PtrList. Delete allocated entries and set size to zero.
Definition: PtrListI.H:97
virtual bool read()
Re-read model coefficients if they have changed.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
static word suffix(const word &fldName, const word &fileExt=word::null)
Name suffix based on fieldName (underscore separator)
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
dictionary subOrEmptyDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX, const bool mandatory=false) const
Definition: dictionary.C:540
bool merge(const dictionary &dict)
Merge entries from the given dictionary.
Definition: dictionary.C:812
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
entry * findEntry(const word &keyword, enum keyType::option matchOpt=keyType::REGEX)
Find for an entry (non-const access) with the given keyword.
Definition: dictionaryI.H:97
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
int verbose() const noexcept
Output verbosity level.
Definition: ensightMesh.C:125
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:70
static bool clean(std::string &str)
Definition: fileName.C:199
Abstract base-class for Time/database function objects.
static word outputPrefix
Directory prefix.
virtual readUpdateState readUpdate()
Update the mesh based on the mesh files saved in time.
Definition: fvMesh.C:675
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:162
const polyMesh & mesh() const
Return polyMesh.
Definition: mapPolyMesh.H:363
void movePoints()
Update for new mesh geometry.
void updateMesh()
Update for new mesh topology.
Registry of regIOobjects.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:91
Holds list of sampling points which is filled at construction time. Various implementations of this b...
Definition: sampledSet.H:86
Set of sets to sample.
Definition: sampledSets.H:196
void correct()
Correct for mesh changes.
Definition: sampledSets.C:741
virtual bool execute()
Execute, currently does nothing.
Definition: sampledSets.C:724
virtual bool write()
Sample and write.
Definition: sampledSets.C:735
virtual bool read(const dictionary &)
Read the sampledSets.
Definition: sampledSets.C:511
splitCell * master() const
Definition: splitCell.H:113
virtual bool open(const fileName &file, bool parallel=Pstream::parRun())
Open file for writing (creates parent directory).
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
volScalarField & p
thermo correct()
dynamicFvMesh & mesh
engineTime & runTime
Foam::word regionName(Foam::polyMesh::defaultRegion)
OBJstream os(runTime.globalPath()/outputName)
label nPoints
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
#define DebugInfo
Report an information message using Foam::Info.
#define WarningInFunction
Report a warning using Foam::Warning.
bool found(const ListType &input, const UnaryPredicate &pred, const label start=0)
Same as found_if.
Definition: ListOps.H:679
Namespace for OpenFOAM.
List< word > wordList
A List of words.
Definition: fileName.H:63
GeometricField< vector, fvPatchField, volMesh > volVectorField
Definition: volFieldsFwd.H:83
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: MSwindows.C:515
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:55
GeometricField< scalar, fvPatchField, volMesh > volScalarField
Definition: volFieldsFwd.H:82
messageStream Info
Information stream (stdout output on master, null elsewhere)
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
vector point
Point is a vector.
Definition: point.H:43
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
GeometricField< tensor, fvPatchField, volMesh > volTensorField
Definition: volFieldsFwd.H:87
GeometricField< sphericalTensor, fvPatchField, volMesh > volSphericalTensorField
Definition: volFieldsFwd.H:85
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:215
GeometricField< symmTensor, fvPatchField, volMesh > volSymmTensorField
Definition: volFieldsFwd.H:86
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:260
const dictionary formatOptions(propsDict.subOrEmptyDict("formatOptions", keyType::LITERAL))
#define doLocalCode(GeoField)