externalCoupled.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-2022 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
28#include "externalCoupled.H"
29#include "stringListOps.H"
31#include "OSspecific.H"
32#include "Fstream.H"
33#include "volFields.H"
34#include "globalIndex.H"
35#include "fvMesh.H"
36#include "DynamicField.H"
37
38// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39
40namespace Foam
41{
42namespace functionObjects
43{
46}
47}
48
50
51
52namespace Foam
53{
55//- Write list content with size, bracket, content, bracket one-per-line.
56// This makes for consistent for parsing, regardless of the list length.
57template <class T>
58static void writeList(Ostream& os, const string& header, const UList<T>& L)
59{
60 // Header string
61 os << header.c_str() << nl;
62
63 // Write size and start delimiter
64 os << L.size() << nl
66
67 // Write contents
68 forAll(L, i)
69 {
70 os << L[i] << nl;
71 }
72
73 // Write end delimiter
74 os << token::END_LIST << nl << endl;
75}
77
78} // End namespace Foam
79
80
81// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
82
83Foam::fileName Foam::functionObjects::externalCoupled::groupDir
84(
85 const fileName& commsDir,
86 const word& regionGroupName,
87 const wordRe& groupName
88)
89{
90 fileName result
91 (
92 commsDir
93 / regionGroupName
94 / word::validate(groupName)
95 );
96 result.clean(); // Remove unneeded ".."
97
98 return result;
99}
100
101
102void Foam::functionObjects::externalCoupled::readColumns
103(
104 const label nRows,
105 const label nColumns,
106 autoPtr<IFstream>& masterFilePtr,
107 List<scalarField>& data
108) const
109{
110 // Get sizes for all processors
111 const globalIndex globalFaces(nRows, globalIndex::gatherOnly{});
112
113 PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
114
115 if (Pstream::master())
116 {
117 string line;
118
119 // Read data from file and send to destination processor
120
121 for (const int proci : Pstream::allProcs())
122 {
123 // Temporary storage
124 List<scalarField> values(nColumns);
125
126 // Number of rows to read for processor proci
127 const label procNRows = globalFaces.localSize(proci);
128
129 forAll(values, columni)
130 {
131 values[columni].setSize(procNRows);
132 }
133
134 for (label rowi = 0; rowi < procNRows; ++rowi)
135 {
136 // Get a line
137 do
138 {
139 if (!masterFilePtr().good())
140 {
141 FatalIOErrorInFunction(masterFilePtr())
142 << "Trying to read data for processor " << proci
143 << " row " << rowi
144 << ". Does your file have as many rows as there are"
145 << " patch faces (" << globalFaces.totalSize()
146 << ") ?" << exit(FatalIOError);
147 }
148
149 masterFilePtr().getLine(line);
150 }
151 while (line.empty() || line[0] == '#');
152
153 IStringStream lineStr(line);
154
155 for (label columni = 0; columni < nColumns; ++columni)
156 {
157 lineStr >> values[columni][rowi];
158 }
159 }
160
161 // Send to proci
162 UOPstream toProc(proci, pBufs);
163 toProc << values;
164 }
165 }
166 pBufs.finishedScatters();
167
168 // Get scattered data from PstreamBuffers
169 UIPstream fromMaster(UPstream::masterNo(), pBufs);
170 fromMaster >> data;
171}
172
173
174void Foam::functionObjects::externalCoupled::readLines
175(
176 const label nRows,
177 autoPtr<IFstream>& masterFilePtr,
178 OStringStream& lines
179) const
180{
181 // Get sizes for all processors
182 const globalIndex globalFaces(nRows, globalIndex::gatherOnly{});
183
184 PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
185
186 if (Pstream::master())
187 {
188 string line;
189
190 // Read line from file and send to destination processor
191
192 for (const int proci : Pstream::allProcs())
193 {
194 // Number of rows to read for processor proci
195 const label procNRows = globalFaces.localSize(proci);
196
197 UOPstream toProc(proci, pBufs);
198
199 for (label rowi = 0; rowi < procNRows; ++rowi)
200 {
201 // Get a line
202 do
203 {
204 if (!masterFilePtr().good())
205 {
206 FatalIOErrorInFunction(masterFilePtr())
207 << "Trying to read data for processor " << proci
208 << " row " << rowi
209 << ". Does your file have as many rows as there are"
210 << " patch faces (" << globalFaces.totalSize()
211 << ") ?" << exit(FatalIOError);
212 }
213
214 masterFilePtr().getLine(line);
215 }
216 while (line.empty() || line[0] == '#');
217
218 // Send line to the destination processor
219 toProc << line;
220 }
221 }
222 }
223
224 pBufs.finishedScatters();
225
226 // Get scattered data from PstreamBuffers
227 UIPstream fromMaster(UPstream::masterNo(), pBufs);
228 for (label rowi = 0; rowi < nRows; ++rowi)
229 {
230 string line(fromMaster);
231 lines << line.c_str() << nl;
232 }
233}
234
235
237(
239 const fileName& commsDir,
240 const wordRe& groupName
241)
242{
244 forAll(meshes, i)
245 {
246 regionNames[i] = meshes[i].dbDir();
247 }
248
249 // Make sure meshes are provided in sorted order
250 checkOrder(regionNames);
251
252 fileName dir(groupDir(commsDir, compositeName(regionNames), groupName));
253
254 autoPtr<OFstream> osPointsPtr;
255 autoPtr<OFstream> osFacesPtr;
256 if (Pstream::master())
257 {
258 mkDir(dir);
259 osPointsPtr.reset(new OFstream(dir/"patchPoints"));
260 osFacesPtr.reset(new OFstream(dir/"patchFaces"));
261
262 osPointsPtr() << "// Group: " << groupName << endl;
263 osFacesPtr() << "// Group: " << groupName << endl;
264
265 Info<< typeName << ": writing geometry to " << dir << endl;
266 }
267
268 // Individual region/patch entries
269
270 DynamicList<face> allFaces;
271 DynamicField<point> allPoints;
272
273 labelList pointToGlobal;
274 labelList uniquePointIDs;
275 for (const fvMesh& mesh : meshes)
276 {
277 const labelList patchIDs
278 (
279 mesh.boundaryMesh().patchSet
280 (
281 wordRes(one{}, groupName)
282 ).sortedToc()
283 );
284
285 for (const label patchi : patchIDs)
286 {
287 const polyPatch& p = mesh.boundaryMesh()[patchi];
288
289 mesh.globalData().mergePoints
290 (
291 p.meshPoints(),
292 p.meshPointMap(),
293 pointToGlobal,
294 uniquePointIDs
295 );
296
297 label proci = Pstream::myProcNo();
298
299 List<pointField> collectedPoints(Pstream::nProcs());
300 collectedPoints[proci] = pointField(mesh.points(), uniquePointIDs);
301 Pstream::gatherList(collectedPoints);
302
303 List<faceList> collectedFaces(Pstream::nProcs());
304 faceList& patchFaces = collectedFaces[proci];
305 patchFaces = p.localFaces();
306 forAll(patchFaces, facei)
307 {
308 inplaceRenumber(pointToGlobal, patchFaces[facei]);
309 }
310 Pstream::gatherList(collectedFaces);
311
312 if (Pstream::master())
313 {
314 allPoints.clear();
315 allFaces.clear();
316
317 for (const int proci : Pstream::allProcs())
318 {
319 allPoints.append(collectedPoints[proci]);
320 allFaces.append(collectedFaces[proci]);
321 }
322
323 Info<< typeName << ": mesh " << mesh.name()
324 << ", patch " << p.name()
325 << ": writing " << allPoints.size() << " points to "
326 << osPointsPtr().name() << nl
327 << typeName << ": mesh " << mesh.name()
328 << ", patch " << p.name()
329 << ": writing " << allFaces.size() << " faces to "
330 << osFacesPtr().name() << endl;
331
332 // The entry name (region / patch)
333 const string entryHeader =
334 patchKey + ' ' + mesh.name() + ' ' + p.name();
335
336 writeList(osPointsPtr(), entryHeader, allPoints);
337 writeList(osFacesPtr(), entryHeader, allFaces);
338 }
339 }
340 }
341}
342
343
345(
346 const wordList& regionNames
347)
348{
349 if (regionNames.size() == 0)
350 {
352 << "Empty regionNames" << abort(FatalError);
353 return word::null;
354 }
355 else if (regionNames.size() == 1)
356 {
358 {
359 // For compatibility with single region cases
360 // - suppress single region name
361 return word::null;
362 }
363 else
364 {
365 return regionNames[0];
366 }
367 }
368
369 // Enforce lexical ordering
370 checkOrder(regionNames);
371
372 word composite(regionNames[0]);
373 for (label i = 1; i < regionNames.size(); ++i)
374 {
375 composite += "_" + regionNames[i];
376 }
377
378 return composite;
379}
380
381
383(
384 const wordList& regionNames
385)
386{
388 if (order != identity(regionNames.size()))
389 {
391 << "regionNames " << regionNames << " not in alphabetical order :"
392 << order << exit(FatalError);
393 }
394}
395
396
397void Foam::functionObjects::externalCoupled::initCoupling()
398{
399 if (initialisedCoupling_)
400 {
401 return;
402 }
403
404 // Write the geometry if not already there
405 forAll(regionGroupNames_, regioni)
406 {
407 const word& compName = regionGroupNames_[regioni];
408 const wordList& regionNames = regionGroupRegions_[regioni];
409
410 // Get the meshes for the region-group
411 UPtrList<const fvMesh> meshes(regionNames.size());
412 forAll(regionNames, regi)
413 {
414 meshes.set(regi, time_.findObject<fvMesh>(regionNames[regi]));
415 }
416
417 const labelList& groups = regionToGroups_[compName];
418
419 for (const label groupi : groups)
420 {
421 const wordRe& groupName = groupNames_[groupi];
422
423 bool geomExists = false;
424 if (Pstream::master())
425 {
426 fileName dir(groupDir(commDirectory(), compName, groupName));
427
428 geomExists =
429 isFile(dir/"patchPoints")
430 || isFile(dir/"patchFaces");
431 }
432
433 Pstream::scatter(geomExists);
434
435 if (!geomExists)
436 {
437 writeGeometry(meshes, commDirectory(), groupName);
438 }
439 }
440 }
441
442 if (slaveFirst())
443 {
444 // Wait for initial data to be made available
445 waitForSlave();
446
447 // Read data passed back from external source
448 readDataMaster();
449 }
450
451 initialisedCoupling_ = true;
452}
453
454
455void Foam::functionObjects::externalCoupled::performCoupling()
456{
457 // Ensure coupling has been initialised
458 initCoupling();
459
460 // Write data for external source
461 writeDataMaster();
462
463 // Signal external source to execute (by removing lock file)
464 // - Wait for slave to provide data
465 useSlave();
466
467 // Wait for response - and catch any abort information sent from slave
468 const auto action = waitForSlave();
469
470 // Remove old data files from OpenFOAM
471 removeDataMaster();
472
473 // Read data passed back from external source
474 readDataMaster();
475
476 // Signal external source to wait (by creating the lock file)
477 useMaster();
478
479 // Update information about last triggering
480 lastTrigger_ = time_.timeIndex();
481
482 // Process any abort information sent from slave
483 if
484 (
485 action != time_.stopAt()
487 )
488 {
489 Info<< type() << ": slave requested action "
490 << Time::stopAtControlNames[action] << endl;
491
492 time_.stopAt(action);
493 }
494}
495
496
497// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
498
500(
501 const word& name,
502 const Time& runTime,
503 const dictionary& dict
504)
505:
508 calcFrequency_(-1),
509 lastTrigger_(-1),
510 initialisedCoupling_(false)
511{
512 read(dict);
513
514 if (!slaveFirst())
515 {
516 useMaster();
517 }
518}
519
520
521// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
522
524{
525 // Not initialized or overdue
526 if
527 (
528 !initialisedCoupling_
529 || (time_.timeIndex() >= lastTrigger_ + calcFrequency_)
530 )
531 {
532 performCoupling();
533 }
534
535 return false;
536}
537
538
540{
541 performCoupling();
542
543 return true;
544}
545
546
548{
550
551 // Remove old data files
552 removeDataMaster();
553 removeDataSlave();
554 shutdown();
555
556 return true;
557}
558
559
561{
563 externalFileCoupler::readDict(dict);
564
565 calcFrequency_ =
566 dict.getCheckOrDefault("calcFrequency", 1, labelMinMax::ge(1));
567
568 // Leave trigger intact
569
570 // Get names of all fvMeshes (and derived types)
571 wordList allRegionNames(time_.lookupClass<fvMesh>().sortedToc());
572
573 const dictionary& allRegionsDict = dict.subDict("regions");
574 for (const entry& dEntry : allRegionsDict)
575 {
576 if (!dEntry.isDict())
577 {
578 FatalIOErrorInFunction(allRegionsDict)
579 << "Regions must be specified in dictionary format"
580 << exit(FatalIOError);
581 }
582
583 const wordRe regionGroupName(dEntry.keyword());
584 const dictionary& regionDict = dEntry.dict();
585
586 labelList regionIDs = findStrings(regionGroupName, allRegionNames);
587
588 const wordList regionNames(allRegionNames, regionIDs);
589
590 regionGroupNames_.append(compositeName(regionNames));
591 regionGroupRegions_.append(regionNames);
592
593 for (const entry& dEntry : regionDict)
594 {
595 if (!dEntry.isDict())
596 {
597 FatalIOErrorInFunction(regionDict)
598 << "Regions must be specified in dictionary format"
599 << exit(FatalIOError);
600 }
601
602 const wordRe groupName(dEntry.keyword());
603 const dictionary& groupDict = dEntry.dict();
604
605 const label nGroups = groupNames_.size();
606 const wordList readFields(groupDict.get<wordList>("readFields"));
607 const wordList writeFields(groupDict.get<wordList>("writeFields"));
608
609 auto fnd = regionToGroups_.find(regionGroupNames_.last());
610 if (fnd.found())
611 {
612 fnd().append(nGroups);
613 }
614 else
615 {
616 regionToGroups_.insert
617 (
618 regionGroupNames_.last(),
619 labelList(one{}, nGroups)
620 );
621 }
622 groupNames_.append(groupName);
623 groupReadFields_.append(readFields);
624 groupWriteFields_.append(writeFields);
625 }
626 }
627
628
629 Info<< type() << ": Communicating with regions:" << endl;
630 for (const word& compName : regionGroupNames_)
631 {
632 Info<< "Region: " << compName << nl << incrIndent;
633 const labelList& groups = regionToGroups_[compName];
634 for (const label groupi : groups)
635 {
636 const wordRe& groupName = groupNames_[groupi];
637
638 Info<< indent << "patchGroup: " << groupName << "\t"
639 << nl
640 << incrIndent
641 << indent << "Reading fields: "
642 << groupReadFields_[groupi]
643 << nl
644 << indent << "Writing fields: "
645 << groupWriteFields_[groupi]
646 << nl
647 << decrIndent;
648 }
650 }
651 Info<< endl;
652
653
654 // Note: we should not have to make directories since the geometry
655 // should already be written - but just make sure
656 if (Pstream::master())
657 {
658 for (const word& compName : regionGroupNames_)
659 {
660 const labelList& groups = regionToGroups_[compName];
661 for (const label groupi : groups)
662 {
663 const wordRe& groupName = groupNames_[groupi];
664
665 fileName dir(groupDir(commDirectory(), compName, groupName));
666
667 if (!isDir(dir))
668 {
669 Log << type() << ": creating communications directory "
670 << dir << endl;
671 mkDir(dir);
672 }
673 }
674 }
675 }
676
677 return true;
678}
679
680
682{
683 forAll(regionGroupNames_, regioni)
684 {
685 const word& compName = regionGroupNames_[regioni];
686 const wordList& regionNames = regionGroupRegions_[regioni];
687
688 // Get the meshes for the region-group
690 forAll(regionNames, regi)
691 {
692 meshes.set(regi, time_.findObject<fvMesh>(regionNames[regi]));
693 }
694
695 const labelList& groups = regionToGroups_[compName];
696
697 for (const label groupi : groups)
698 {
699 const wordRe& groupName = groupNames_[groupi];
700 const wordList& fieldNames = groupReadFields_[groupi];
701
702 for (const word& fieldName : fieldNames)
703 {
704 const bool ok =
705 (
706 readData<scalar>(meshes, groupName, fieldName)
707 || readData<vector>(meshes, groupName, fieldName)
708 || readData<sphericalTensor>(meshes, groupName, fieldName)
709 || readData<symmTensor>(meshes, groupName, fieldName)
710 || readData<tensor>(meshes, groupName, fieldName)
711 );
712
713 if (!ok)
714 {
716 << "Field " << fieldName << " in regions " << compName
717 << " was not found." << endl;
718 }
719 }
720 }
721 }
722}
723
724
726{
727 forAll(regionGroupNames_, regioni)
728 {
729 const word& compName = regionGroupNames_[regioni];
730 const wordList& regionNames = regionGroupRegions_[regioni];
731
732 // Get the meshes for the region-group
734 forAll(regionNames, regi)
735 {
736 meshes.set(regi, time_.findObject<fvMesh>(regionNames[regi]));
737 }
738
739 const labelList& groups = regionToGroups_[compName];
740
741 for (const label groupi : groups)
742 {
743 const wordRe& groupName = groupNames_[groupi];
744 const wordList& fieldNames = groupWriteFields_[groupi];
745
746 for (const word& fieldName : fieldNames)
747 {
748 const bool ok =
749 (
750 writeData<scalar>(meshes, groupName, fieldName)
751 || writeData<vector>(meshes, groupName, fieldName)
752 || writeData<sphericalTensor>(meshes, groupName, fieldName)
753 || writeData<symmTensor>(meshes, groupName, fieldName)
754 || writeData<tensor>(meshes, groupName, fieldName)
755 );
756
757 if (!ok)
758 {
760 << "Field " << fieldName << " in regions " << compName
761 << " was not found." << endl;
762 }
763 }
764 }
765 }
766}
767
768
770{
771 if (!Pstream::master())
772 {
773 return;
774 }
775
776 Log << type() << ": removing data files written by master" << nl;
777
778 for (const word& compName : regionGroupNames_)
779 {
780 const labelList& groups = regionToGroups_[compName];
781 for (const label groupi : groups)
782 {
783 const wordRe& groupName = groupNames_[groupi];
784 const wordList& fieldNames = groupReadFields_[groupi];
785
786 for (const word& fieldName : fieldNames)
787 {
789 (
790 groupDir(commDirectory(), compName, groupName)
791 / fieldName + ".out"
792 );
793 }
794 }
795 }
796}
797
798
800{
801 if (!Pstream::master())
802 {
803 return;
804 }
805
806 Log << type() << ": removing data files written by slave" << nl;
807
808 for (const word& compName : regionGroupNames_)
809 {
810 const labelList& groups = regionToGroups_[compName];
811 for (const label groupi : groups)
812 {
813 const wordRe& groupName = groupNames_[groupi];
814 const wordList& fieldNames = groupReadFields_[groupi];
815
816 for (const word& fieldName : fieldNames)
817 {
819 (
820 groupDir(commDirectory(), compName, groupName)
821 / fieldName + ".in"
822 );
823 }
824 }
825 }
826}
827
828
830{
831 return true;
832}
833
834
835// ************************************************************************* //
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
#define Log
Definition: PDRblock.C:35
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
writer writeGeometry()
Dynamically sized Field.
Definition: DynamicField.H:65
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:391
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:503
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:137
static MinMax< T > ge(const T &minVal)
A semi-infinite range from minVal to the type max.
Definition: MinMaxI.H:31
Output to file stream, using an OSstream.
Definition: OFstream.H:57
UPstream::rangeType allProcs() const noexcept
Range of ranks indices associated with PstreamBuffers.
label nProcs() const noexcept
Number of ranks associated with PstreamBuffers.
static void gatherList(const List< commsStruct > &comms, List< T > &values, const int tag, const label comm)
static void scatter(const List< commsStruct > &comms, T &value, const int tag, const label comm)
Broadcast data: Distribute without modification.
const T * set(const label i) const
Definition: PtrList.H:138
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 const Enum< stopAtControls > stopAtControlNames
Names for stopAtControls.
Definition: Time.H:119
@ saUnknown
Dummy no-op. Do not change current value.
Definition: Time.H:103
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
@ nonBlocking
"nonBlocking"
static constexpr int masterNo() noexcept
Process index of the master (always 0)
Definition: UPstream.H:451
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: UPtrList.H:71
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:106
static constexpr direction size() noexcept
The number of elements in the VectorSpace = Ncmpts.
Definition: VectorSpace.H:176
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
void reset(autoPtr< T > &&other) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:117
void writeGeometry()
Write the mesh.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:70
Encapsulates the logic for coordinating between OpenFOAM and an external application.
enum Time::stopAtControls useMaster(const bool wait=false) const
Create lock file to indicate that OpenFOAM is in charge.
bool slaveFirst() const
External application provides initial values.
A class for handling file names.
Definition: fileName.H:76
Abstract base-class for Time/database function objects.
virtual bool end()
Called when Time::run() determines that the time-loop exits.
Watches for presence of the named trigger file in the case directory and signals a simulation stop (o...
Definition: abort.H:128
Provides a simple file-based communication interface for explicit coupling with an external applicati...
virtual void writeDataMaster() const
Write data files (all regions, all fields) from master (OpenFOAM)
virtual void removeDataSlave() const
Remove data files written by slave (external code)
static string patchKey
Name of patch key, e.g. '// Patch:' when looking for start of patch data.
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
virtual void readDataMaster()
Read data files (all regions, all fields) on master (OpenFOAM)
virtual void removeDataMaster() const
Remove data files written by master (OpenFOAM)
virtual bool execute()
Called at each ++ or += of the time-loop.
virtual bool write()
Write, currently a no-op.
virtual bool end()
Called when Time::run() determines that the time-loop exits.
static word compositeName(const wordList &)
Reads fields from the time directories and adds them to the mesh database for further post-processing...
Definition: readFields.H:158
Virtual base class for function objects with a reference to Time.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:91
virtual void validate()
Validate the turbulence fields after construction.
Definition: kkLOmega.C:597
void checkOrder() const
Deprecated(2019-08) check list is monotonically increasing.
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:62
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:321
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:75
int myProcNo() const noexcept
Return processor number.
splitCell * master() const
Definition: splitCell.H:113
A class for handling character strings derived from std::string.
Definition: string.H:79
@ BEGIN_LIST
Begin list [isseparator].
Definition: token.H:155
@ END_LIST
End list [isseparator].
Definition: token.H:156
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
Definition: wordRe.H:83
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:54
A class for handling words, derived from Foam::string.
Definition: word.H:68
static const word null
An empty word.
Definition: word.H:80
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
volScalarField & p
dynamicFvMesh & mesh
engineTime & runTime
Foam::PtrList< Foam::fvMesh > meshes(regionNames.size())
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
wordList regionNames
#define WarningInFunction
Report a warning using Foam::Warning.
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:149
Namespace for OpenFOAM.
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: MSwindows.C:1012
List< word > wordList
A List of words.
Definition: fileName.H:63
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Definition: labelList.C:38
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
List< label > labelList
A List of labels.
Definition: List.H:66
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
messageStream Info
Information stream (stdout output on master, null elsewhere)
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:598
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:349
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:342
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
IOerror FatalIOError
void writeFields(const fvMesh &mesh, const wordHashSet &selectedFields, const bool writeFaceFields)
bool isFile(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist as a FILE in the file system?
Definition: MSwindows.C:666
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
labelList findStrings(const regExp &matcher, const UList< StringType > &input, const bool invert=false)
Return list indices for strings matching the regular expression.
Definition: stringListOps.H:87
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:356
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: MSwindows.C:651
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
Operations on lists of strings.
const vector L(dict.get< vector >("L"))