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 -------------------------------------------------------------------------------
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  {
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 
382 void Foam::functionObjects::externalCoupled::checkOrder
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 
397 void 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::broadcast(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 
455 void 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()
486  && action != Time::stopAtControls::saUnknown
487  )
488  {
489  Info<< type() << ": slave requested action "
490  << Time::stopAtControlNames[action] << endl;
491 
492  time_.stopAt(action);
493  }
494 }
495 
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 }
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 
539 bool Foam::functionObjects::externalCoupled::execute(const label subIndex)
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 {
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.good())
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  }
649  Info<< decrIndent;
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  {
788  Foam::rm
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  {
818  Foam::rm
819  (
820  groupDir(commDirectory(), compName, groupName)
821  / fieldName + ".in"
822  );
823  }
824  }
825  }
826 }
827 
828 
830 {
831  return true;
832 }
833 
834 
835 // ************************************************************************* //
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.
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.
const labelList patchIDs(pbm.patchSet(polyPatchNames, false, true).sortedToc())
virtual bool write()
Write, currently a no-op.
A class for handling file names.
Definition: fileName.H:71
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:449
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:120
const vector L(dict.get< vector >("L"))
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
Definition: UPstream.H:1131
Output to file stream, using an OSstream.
Definition: OFstream.H:49
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
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:158
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:125
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:1029
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 processes in communicator.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:414
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:1020
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 INVALID.
Definition: exprTraits.C:52
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Definition: labelList.C:31
A class for handling words, derived from Foam::string.
Definition: word.H:63
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:397
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
Definition: UPstream.H:1014
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:113
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:159
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:100
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:467
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:58
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:607
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:79
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:130
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1037
#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
void readFields(const typename GeoFieldType::Mesh &mesh, const IOobjectList &objects, const wordHashSet &selectedFields, LIFOStack< regIOobject *> &storedObjects)
Read the selected GeometricFields of the templated type.
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
Ostream & incrIndent(Ostream &os)
Increment the indent level.
Definition: Ostream.H:458
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 ...