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.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  }
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:38
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.
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:748
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
List< face > faceList
A List of faces.
Definition: faceListFwd.H:41
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)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:688
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:413
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:813
virtual bool end()
Called when Time::run() determines that the time-loop exits.
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:752
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator) is 1 for serial run.
Definition: UPstream.H:656
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:567
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
Process index of the master (always 0)
Definition: UPstream.H:664
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:99
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:163
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:830
List< word > wordList
A List of words.
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)
Am I the master rank.
Definition: UPstream.H:672
#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:57
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: POSIX.C:1357
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...