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-2023 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
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 
40 namespace Foam
41 {
42 namespace functionObjects
43 {
44  defineTypeNameAndDebug(externalCoupled, 0);
45  addToRunTimeSelectionTable(functionObject, externalCoupled, dictionary);
46 }
47 }
48 
50 
51 
52 namespace 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.
57 template <class T>
58 static 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
65  << token::BEGIN_LIST << 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 
83 Foam::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 
102 void 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(globalIndex::gatherOnly{}, nRows);
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 
174 void 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(globalIndex::gatherOnly{}, nRows);
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  {
357  // For compatibility with single region cases
358  // - suppress single region name
360  }
361 
362  // Enforce lexical ordering
363  checkOrder(regionNames);
364 
365  word composite(regionNames[0]);
366  for (label i = 1; i < regionNames.size(); ++i)
367  {
368  composite += "_" + regionNames[i];
369  }
370 
371  return composite;
372 }
373 
374 
375 void Foam::functionObjects::externalCoupled::checkOrder
376 (
377  const wordList& regionNames
378 )
379 {
381  if (order != identity(regionNames.size()))
382  {
384  << "regionNames " << regionNames << " not in alphabetical order :"
385  << order << exit(FatalError);
386  }
387 }
388 
389 
390 void Foam::functionObjects::externalCoupled::initCoupling()
391 {
392  if (initialisedCoupling_)
393  {
394  return;
395  }
396 
397  // Write the geometry if not already there
398  forAll(regionGroupNames_, regioni)
399  {
400  const word& compName = regionGroupNames_[regioni];
401  const wordList& regionNames = regionGroupRegions_[regioni];
402 
403  // Get the meshes for the region-group
404  UPtrList<const fvMesh> meshes(regionNames.size());
405  forAll(regionNames, regi)
406  {
407  meshes.set(regi, time_.findObject<fvMesh>(regionNames[regi]));
408  }
409 
410  const labelList& groups = regionToGroups_[compName];
411 
412  for (const label groupi : groups)
413  {
414  const wordRe& groupName = groupNames_[groupi];
415 
416  bool geomExists = false;
417  if (Pstream::master())
418  {
419  fileName dir(groupDir(commDirectory(), compName, groupName));
420 
421  geomExists =
422  isFile(dir/"patchPoints")
423  || isFile(dir/"patchFaces");
424  }
425 
426  Pstream::broadcast(geomExists);
427 
428  if (!geomExists)
429  {
430  writeGeometry(meshes, commDirectory(), groupName);
431  }
432  }
433  }
434 
435  if (slaveFirst())
436  {
437  // Wait for initial data to be made available
438  waitForSlave();
439 
440  // Read data passed back from external source
441  readDataMaster();
442  }
443 
444  initialisedCoupling_ = true;
445 }
446 
447 
448 void Foam::functionObjects::externalCoupled::performCoupling()
449 {
450  // Ensure coupling has been initialised
451  initCoupling();
452 
453  // Write data for external source
454  writeDataMaster();
455 
456  // Signal external source to execute (by removing lock file)
457  // - Wait for slave to provide data
458  useSlave();
459 
460  // Wait for response - and catch any abort information sent from slave
461  const auto action = waitForSlave();
462 
463  // Remove old data files from OpenFOAM
464  removeDataMaster();
465 
466  // Read data passed back from external source
467  readDataMaster();
468 
469  // Signal external source to wait (by creating the lock file)
470  useMaster();
471 
472  // Update information about last triggering
473  lastTrigger_ = time_.timeIndex();
474 
475  // Process any abort information sent from slave
476  if
477  (
478  action != time_.stopAt()
479  && action != Time::stopAtControls::saUnknown
480  )
481  {
482  Info<< type() << ": slave requested action "
483  << Time::stopAtControlNames[action] << endl;
484 
485  time_.stopAt(action);
486  }
487 }
488 
490 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
491 
493 (
494  const word& name,
495  const Time& runTime,
496  const dictionary& dict
497 )
498 :
501  calcFrequency_(-1),
502  lastTrigger_(-1),
503  initialisedCoupling_(false)
504 {
505  read(dict);
506 
507  if (!slaveFirst())
508  {
509  useMaster();
510  }
511 }
513 
514 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
515 
517 {
518  // Not initialized or overdue
519  if
520  (
521  !initialisedCoupling_
522  || (time_.timeIndex() >= lastTrigger_ + calcFrequency_)
523  )
524  {
525  performCoupling();
526  }
527 
528  return false;
529 }
530 
531 
532 bool Foam::functionObjects::externalCoupled::execute(const label subIndex)
533 {
534  performCoupling();
535 
536  return true;
537 }
538 
539 
541 {
543 
544  // Remove old data files
545  removeDataMaster();
546  removeDataSlave();
547  shutdown();
548 
549  return true;
550 }
551 
552 
554 {
557 
558  calcFrequency_ =
559  dict.getCheckOrDefault("calcFrequency", 1, labelMinMax::ge(1));
560 
561  // Leave trigger intact
562 
563  // Get names of all fvMeshes (and derived types)
564  wordList allRegionNames(time_.sortedNames<fvMesh>());
565 
566  const dictionary& allRegionsDict = dict.subDict("regions");
567  for (const entry& dEntry : allRegionsDict)
568  {
569  if (!dEntry.isDict())
570  {
571  FatalIOErrorInFunction(allRegionsDict)
572  << "Regions must be specified in dictionary format"
573  << exit(FatalIOError);
574  }
575 
576  const wordRe regionGroupName(dEntry.keyword());
577  const dictionary& regionDict = dEntry.dict();
578 
579  labelList regionIDs = findStrings(regionGroupName, allRegionNames);
580 
581  const wordList regionNames(allRegionNames, regionIDs);
582 
583  regionGroupNames_.append(compositeName(regionNames));
584  regionGroupRegions_.append(regionNames);
585 
586  for (const entry& dEntry : regionDict)
587  {
588  if (!dEntry.isDict())
589  {
590  FatalIOErrorInFunction(regionDict)
591  << "Regions must be specified in dictionary format"
592  << exit(FatalIOError);
593  }
594 
595  const wordRe groupName(dEntry.keyword());
596  const dictionary& groupDict = dEntry.dict();
597 
598  const label nGroups = groupNames_.size();
599  const wordList readFields(groupDict.get<wordList>("readFields"));
600  const wordList writeFields(groupDict.get<wordList>("writeFields"));
601 
602  auto fnd = regionToGroups_.find(regionGroupNames_.last());
603  if (fnd.good())
604  {
605  fnd().append(nGroups);
606  }
607  else
608  {
609  regionToGroups_.insert
610  (
611  regionGroupNames_.last(),
612  labelList(one{}, nGroups)
613  );
614  }
615  groupNames_.append(groupName);
616  groupReadFields_.append(readFields);
617  groupWriteFields_.append(writeFields);
618  }
619  }
620 
621 
622  Info<< type() << ": Communicating with regions:" << endl;
623  for (const word& compName : regionGroupNames_)
624  {
625  Info<< "Region: " << compName << nl << incrIndent;
626  const labelList& groups = regionToGroups_[compName];
627  for (const label groupi : groups)
628  {
629  const wordRe& groupName = groupNames_[groupi];
630 
631  Info<< indent << "patchGroup: " << groupName << "\t"
632  << nl
633  << incrIndent
634  << indent << "Reading fields: "
635  << groupReadFields_[groupi]
636  << nl
637  << indent << "Writing fields: "
638  << groupWriteFields_[groupi]
639  << nl
640  << decrIndent;
641  }
642  Info<< decrIndent;
643  }
644  Info<< endl;
645 
646 
647  // Note: we should not have to make directories since the geometry
648  // should already be written - but just make sure
649  if (Pstream::master())
650  {
651  for (const word& compName : regionGroupNames_)
652  {
653  const labelList& groups = regionToGroups_[compName];
654  for (const label groupi : groups)
655  {
656  const wordRe& groupName = groupNames_[groupi];
657 
658  fileName dir(groupDir(commDirectory(), compName, groupName));
659 
660  if (!isDir(dir))
661  {
662  Log << type() << ": creating communications directory "
663  << dir << endl;
664  mkDir(dir);
665  }
666  }
667  }
668  }
669 
670  return true;
671 }
672 
673 
675 {
676  forAll(regionGroupNames_, regioni)
677  {
678  const word& compName = regionGroupNames_[regioni];
679  const wordList& regionNames = regionGroupRegions_[regioni];
680 
681  // Get the meshes for the region-group
683  forAll(regionNames, regi)
684  {
685  meshes.set(regi, time_.findObject<fvMesh>(regionNames[regi]));
686  }
687 
688  const labelList& groups = regionToGroups_[compName];
689 
690  for (const label groupi : groups)
691  {
692  const wordRe& groupName = groupNames_[groupi];
693  const wordList& fieldNames = groupReadFields_[groupi];
694 
695  for (const word& fieldName : fieldNames)
696  {
697  const bool ok =
698  (
699  readData<scalar>(meshes, groupName, fieldName)
700  || readData<vector>(meshes, groupName, fieldName)
701  || readData<sphericalTensor>(meshes, groupName, fieldName)
702  || readData<symmTensor>(meshes, groupName, fieldName)
703  || readData<tensor>(meshes, groupName, fieldName)
704  );
705 
706  if (!ok)
707  {
709  << "Field " << fieldName << " in regions " << compName
710  << " was not found." << endl;
711  }
712  }
713  }
714  }
715 }
716 
717 
719 {
720  forAll(regionGroupNames_, regioni)
721  {
722  const word& compName = regionGroupNames_[regioni];
723  const wordList& regionNames = regionGroupRegions_[regioni];
724 
725  // Get the meshes for the region-group
727  forAll(regionNames, regi)
728  {
729  meshes.set(regi, time_.findObject<fvMesh>(regionNames[regi]));
730  }
731 
732  const labelList& groups = regionToGroups_[compName];
733 
734  for (const label groupi : groups)
735  {
736  const wordRe& groupName = groupNames_[groupi];
737  const wordList& fieldNames = groupWriteFields_[groupi];
738 
739  for (const word& fieldName : fieldNames)
740  {
741  const bool ok =
742  (
743  writeData<scalar>(meshes, groupName, fieldName)
744  || writeData<vector>(meshes, groupName, fieldName)
745  || writeData<sphericalTensor>(meshes, groupName, fieldName)
746  || writeData<symmTensor>(meshes, groupName, fieldName)
747  || writeData<tensor>(meshes, groupName, fieldName)
748  );
749 
750  if (!ok)
751  {
753  << "Field " << fieldName << " in regions " << compName
754  << " was not found." << endl;
755  }
756  }
757  }
758  }
759 }
760 
761 
763 {
764  if (!Pstream::master())
765  {
766  return;
767  }
768 
769  Log << type() << ": removing data files written by master" << nl;
770 
771  for (const word& compName : regionGroupNames_)
772  {
773  const labelList& groups = regionToGroups_[compName];
774  for (const label groupi : groups)
775  {
776  const wordRe& groupName = groupNames_[groupi];
777  const wordList& fieldNames = groupReadFields_[groupi];
778 
779  for (const word& fieldName : fieldNames)
780  {
781  Foam::rm
782  (
783  groupDir(commDirectory(), compName, groupName)
784  / fieldName + ".out"
785  );
786  }
787  }
788  }
789 }
790 
791 
793 {
794  if (!Pstream::master())
795  {
796  return;
797  }
798 
799  Log << type() << ": removing data files written by slave" << nl;
800 
801  for (const word& compName : regionGroupNames_)
802  {
803  const labelList& groups = regionToGroups_[compName];
804  for (const label groupi : groups)
805  {
806  const wordRe& groupName = groupNames_[groupi];
807  const wordList& fieldNames = groupReadFields_[groupi];
808 
809  for (const word& fieldName : fieldNames)
810  {
811  Foam::rm
812  (
813  groupDir(commDirectory(), compName, groupName)
814  / fieldName + ".in"
815  );
816  }
817  }
818  }
819 }
820 
821 
823 {
824  return true;
825 }
826 
827 
828 // ************************************************************************* //
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
Definition: word.C:39
virtual bool end()
Called when Time::run() determines that the time-loop exits.
const labelList patchIDs(pbm.indices(polyPatchNames, true))
dictionary dict
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
defineTypeNameAndDebug(ObukhovLength, 0)
Encapsulates the logic for coordinating between OpenFOAM and an external application.
virtual bool write()
Write, currently a no-op.
A class for handling file names.
Definition: fileName.H:72
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:493
virtual bool execute()
Called at each ++ or += of the time-loop.
bool slaveFirst() const
External application provides initial values.
writer writeGeometry()
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
const vector L(dict.get< vector >("L"))
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
const word & regionName() const
The mesh region name or word::null if polyMesh::defaultRegion.
Definition: polyMesh.C:847
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
Definition: UPstream.H:1176
Output to file stream, using an OSstream.
Definition: OFstream.H:49
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
static string patchKey
Name of patch key, e.g. &#39;// Patch:&#39; when looking for start of patch data.
Begin list [isseparator].
Definition: token.H:161
static void writeGeometry(const UPtrList< const fvMesh > &meshes, const fileName &commsDir, const wordRe &groupName)
Write geometry for the group as region/patch.
static const Enum< stopAtControls > stopAtControlNames
Names for stopAtControls.
Definition: Time.H:114
wordList regionNames
Operations on lists of strings.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
virtual void removeDataSlave() const
Remove data files written by slave (external code)
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
Macros for easy insertion into run-time selection tables.
externalCoupled(const word &name, const Time &runTime, const dictionary &dict)
Construct given time and dictionary.
static void broadcast(Type &value, const label comm=UPstream::worldComm)
Broadcast content (contiguous or non-contiguous) to all communicator ranks. Does nothing in non-paral...
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:37
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:860
virtual bool end()
Called when Time::run() determines that the time-loop exits.
List< face > faceList
List of faces.
Definition: faceListFwd.H:39
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
Definition: UPstream.H:1065
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
static void gatherList(const List< commsStruct > &comms, List< T > &values, const int tag, const label comm)
Gather data, but keep individual values separate. Uses the specified communication schedule...
dynamicFvMesh & mesh
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:614
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Definition: labelLists.C:44
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const NameMatchPredicate &selectedFields, DynamicList< regIOobject *> &storedObjects)
Read the selected GeometricFields of the templated type and store on the objectRegistry.
A class for handling words, derived from Foam::string.
Definition: word.H:63
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
Definition: UPstream.H:1059
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
static MinMax< T > ge(const T &minVal)
A semi-infinite range from minVal to the type max.
Definition: MinMaxI.H:24
Foam::PtrList< Foam::fvMesh > meshes(regionNames.size())
static const word null
An empty word.
Definition: word.H:84
enum Time::stopAtControls useMaster(const bool wait=false) const
Create lock file to indicate that OpenFOAM is in charge.
End list [isseparator].
Definition: token.H:162
virtual void removeDataMaster() const
Remove data files written by master (OpenFOAM)
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Definition: HashTable.H:106
errorManip< error > abort(error &err)
Definition: errorManip.H:139
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
Definition: PtrList.H:159
virtual void writeDataMaster() const
Write data files (all regions, all fields) from master (OpenFOAM)
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings...
Definition: wordRe.H:78
void writeFields(const fvMesh &mesh, const wordHashSet &selectedFields, const bool writeFaceFields)
bool readDict(const dictionary &dict)
Read communication settings from dictionary.
void writeList(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
Reads fields from the time directories and adds them to the mesh database for further post-processing...
Definition: readFields.H:151
OBJstream os(runTime.globalPath()/outputName)
addToRunTimeSelectionTable(functionObject, ObukhovLength, dictionary)
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
Definition: Ostream.H:511
virtual void readDataMaster()
Read data files (all regions, all fields) on master (OpenFOAM)
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: POSIX.C:877
List< word > wordList
List of word.
Definition: fileName.H:59
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values (not the indices) of a list.
static word compositeName(const wordList &)
Create single name by appending words (in sorted order), separated by &#39;_&#39;.
#define WarningInFunction
Report a warning using Foam::Warning.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
#define Log
Definition: PDRblock.C:28
"nonBlocking" : (MPI_Isend, MPI_Irecv)
messageStream Info
Information stream (stdout output on master, null elsewhere)
tmp< pointField > allPoints(const Triangulation &t)
Extract all points in vertex-index order.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:502
A class for handling character strings derived from std::string.
Definition: string.H:72
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:92
Virtual base class for function objects with a reference to Time.
Namespace for OpenFOAM.
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:63
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:56
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: POSIX.C:1404
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...