62 os << header.c_str() <<
nl;
86 const fileName& commsDir,
87 const word& regionGroupName,
88 const wordRe& groupName
103void Foam::functionObjects::externalCoupled::readColumns
106 const label nColumns,
107 autoPtr<IFstream>& masterFilePtr,
108 List<scalarField>& data
112 const globalIndex globalFaces(globalIndex::gatherOnly{}, nRows);
114 PstreamBuffers pBufs;
119 auto& ifile = masterFilePtr();
125 List<scalarField>
values(nColumns);
128 const label procNRows = globalFaces.localSize(proci);
132 values[columni].setSize(procNRows);
135 for (label rowi = 0; rowi < procNRows; ++rowi)
143 <<
"Trying to read data for processor " << proci
145 <<
". Does your file have as many rows as there are"
146 <<
" patch faces (" << globalFaces.totalSize()
152 while (line.empty() || line[0] ==
'#');
154 ISpanStream isstr(line);
156 for (label columni = 0; columni < nColumns; ++columni)
158 isstr >>
values[columni][rowi];
163 UOPstream toProc(proci, pBufs);
167 pBufs.finishedScatters();
175void Foam::functionObjects::externalCoupled::readLines
178 autoPtr<IFstream>& masterFilePtr,
183 const globalIndex globalFaces(globalIndex::gatherOnly{}, nRows);
185 PstreamBuffers pBufs;
190 auto& ifile = masterFilePtr();
196 const label procNRows = globalFaces.localSize(proci);
198 UOPstream toProc(proci, pBufs);
200 for (label rowi = 0; rowi < procNRows; ++rowi)
208 <<
"Trying to read data for processor " << proci
210 <<
". Does your file have as many rows as there are"
211 <<
" patch faces (" << globalFaces.totalSize()
217 while (line.empty() || line[0] ==
'#');
225 pBufs.finishedScatters();
232 for (label rowi = 0; rowi < nRows; ++rowi)
234 string line(fromMaster);
257 fileName dir(groupDir(commsDir, compositeName(
regionNames), groupName));
259 autoPtr<OFstream> osPointsPtr;
260 autoPtr<OFstream> osFacesPtr;
264 osPointsPtr.reset(
new OFstream(dir/
"patchPoints"));
265 osFacesPtr.reset(
new OFstream(dir/
"patchFaces"));
267 osPointsPtr() <<
"// Group: " << groupName <<
endl;
268 osFacesPtr() <<
"// Group: " << groupName <<
endl;
275 DynamicList<face> allFaces;
284 mesh.boundaryMesh().patchSet
286 wordRes(Foam::one{}, groupName)
292 const polyPatch&
p =
mesh.boundaryMesh()[patchi];
294 mesh.globalData().mergePoints
305 collectedPoints[proci] =
pointField(
mesh.points(), uniquePointIDs);
309 faceList& patchFaces = collectedFaces[proci];
310 patchFaces =
p.localFaces();
311 for (
auto&
f : patchFaces)
324 allPoints.append(collectedPoints[proci]);
325 allFaces.append(collectedFaces[proci]);
329 <<
", patch " <<
p.name()
330 <<
": writing " <<
allPoints.size() <<
" points to "
331 << osPointsPtr().name() <<
nl
333 <<
", patch " <<
p.name()
334 <<
": writing " << allFaces.size() <<
" faces to "
335 << osFacesPtr().name() <<
endl;
338 const string entryHeader =
341 writeList(osPointsPtr(), entryHeader, allPoints);
342 writeList(osFacesPtr(), entryHeader, allFaces);
380void Foam::functionObjects::externalCoupled::checkOrder
389 <<
"regionNames " <<
regionNames <<
" not in alphabetical order :"
395void Foam::functionObjects::externalCoupled::initCoupling()
397 if (initialisedCoupling_)
403 forAll(regionGroupNames_, regioni)
405 const word& compName = regionGroupNames_[regioni];
415 const labelList& groups = regionToGroups_[compName];
417 for (
const label groupi : groups)
419 const wordRe& groupName = groupNames_[groupi];
421 bool geomExists =
false;
424 fileName dir(groupDir(commDirectory(), compName, groupName));
428 ||
isFile(dir/
"patchFaces");
449 initialisedCoupling_ =
true;
453void Foam::functionObjects::externalCoupled::performCoupling()
466 const auto action = waitForSlave();
478 lastTrigger_ = time_.timeIndex();
483 action != time_.stopAt()
487 Info<<
type() <<
": slave requested action "
490 time_.stopAt(action);
505 externalFileCoupler(),
508 initialisedCoupling_(false)
526 !initialisedCoupling_
527 || (
time_.timeIndex() >= lastTrigger_ + calcFrequency_)
572 for (
const entry& dEntry : allRegionsDict)
574 if (!dEntry.isDict())
577 <<
"Regions must be specified in dictionary format"
581 const wordRe regionGroupName(dEntry.keyword());
591 regionGroupNames_.append(compositeName(
regionNames));
594 for (
const entry& dEntry : regionDict)
596 if (!dEntry.isDict())
599 <<
"Regions must be specified in dictionary format"
603 const wordRe groupName(dEntry.keyword());
606 const label nGroups = groupNames_.
size();
610 auto fnd = regionToGroups_.find(regionGroupNames_.last());
613 fnd().append(nGroups);
617 regionToGroups_.insert
619 regionGroupNames_.last(),
623 groupNames_.append(groupName);
630 Info<<
type() <<
": Communicating with regions:" <<
endl;
631 for (
const word& compName : regionGroupNames_)
634 const labelList& groups = regionToGroups_[compName];
635 for (
const label groupi : groups)
637 const wordRe& groupName = groupNames_[groupi];
639 Info<<
indent <<
"patchGroup: " << groupName <<
"\t"
642 <<
indent <<
"Reading fields: "
643 << groupReadFields_[groupi]
645 <<
indent <<
"Writing fields: "
646 << groupWriteFields_[groupi]
659 for (
const word& compName : regionGroupNames_)
661 const labelList& groups = regionToGroups_[compName];
662 for (
const label groupi : groups)
664 const wordRe& groupName = groupNames_[groupi];
666 fileName dir(groupDir(commDirectory(), compName, groupName));
670 Log <<
type() <<
": creating communications directory "
684 forAll(regionGroupNames_, regioni)
686 const word& compName = regionGroupNames_[regioni];
696 const labelList& groups = regionToGroups_[compName];
698 for (
const label groupi : groups)
700 const wordRe& groupName = groupNames_[groupi];
701 const wordList& fieldNames = groupReadFields_[groupi];
703 for (
const word& fieldName : fieldNames)
707 readData<scalar>(
meshes, groupName, fieldName)
708 || readData<vector>(
meshes, groupName, fieldName)
709 || readData<sphericalTensor>(
meshes, groupName, fieldName)
710 || readData<symmTensor>(
meshes, groupName, fieldName)
711 || readData<tensor>(
meshes, groupName, fieldName)
717 <<
"Field " << fieldName <<
" in regions " << compName
718 <<
" was not found." <<
endl;
728 forAll(regionGroupNames_, regioni)
730 const word& compName = regionGroupNames_[regioni];
740 const labelList& groups = regionToGroups_[compName];
742 for (
const label groupi : groups)
744 const wordRe& groupName = groupNames_[groupi];
745 const wordList& fieldNames = groupWriteFields_[groupi];
747 for (
const word& fieldName : fieldNames)
761 <<
"Field " << fieldName <<
" in regions " << compName
762 <<
" was not found." <<
endl;
777 Log <<
type() <<
": removing data files written by master" <<
nl;
779 for (
const word& compName : regionGroupNames_)
781 const labelList& groups = regionToGroups_[compName];
782 for (
const label groupi : groups)
784 const wordRe& groupName = groupNames_[groupi];
785 const wordList& fieldNames = groupReadFields_[groupi];
787 for (
const word& fieldName : fieldNames)
791 groupDir(commDirectory(), compName, groupName)
807 Log <<
type() <<
": removing data files written by slave" <<
nl;
809 for (
const word& compName : regionGroupNames_)
811 const labelList& groups = regionToGroups_[compName];
812 for (
const label groupi : groups)
814 const wordRe& groupName = groupNames_[groupi];
815 const wordList& fieldNames = groupReadFields_[groupi];
817 for (
const word& fieldName : fieldNames)
821 groupDir(commDirectory(), compName, groupName)
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
Input/output streams with (internal or external) character storage.
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
label size() const noexcept
The number of elements in list.
Dynamically sized Field. Similar to DynamicList, but inheriting from a Field instead of a List.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
void append(const T &val)
Copy append an element to the end of this list.
virtual const fileName & name() const
The name of the stream.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
static MinMax< label > ge(const label &minVal)
Output to file stream as an OSstream, normally using std::ofstream for the actual output.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
static const Enum< stopAtControls > stopAtControlNames
Names for stopAtControls.
@ saUnknown
Dummy no-op. Do not change current value.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
void size(const label n)
Older name for setAddressableSize.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
@ gatherList
gatherList [manual algorithm]
@ broadcast
broadcast [MPI]
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
A keyword and a list of tokens is an 'entry'.
const fileName & commDirectory() const
Return the file path to the base communications directory.
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.
bool readDict(const dictionary &dict)
Read communication settings from dictionary.
void shutdown() const
Generate status=done in lock (only when run-state = master).
A class for handling file names.
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Abstract base-class for Time/database function objects.
const word & name() const noexcept
Return the name of this functionObject.
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
virtual bool end()
Called when Time::run() determines that the time-loop exits.
Provides a simple file-based communication interface for explicit coupling with an external applicati...
static void writeGeometry(const UPtrList< const fvMesh > &meshes, const fileName &commsDir, const wordRe &groupName)
Write geometry for the group as region/patch.
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).
externalCoupled(const word &name, const Time &runTime, const dictionary &dict)
Construct given time and dictionary.
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 &)
Create single name by appending words (in sorted order), separated by '_'.
Reads fields from the time directories and adds them to the mesh database for further post-processing...
const Time & time_
Reference to the time database.
timeFunctionObject(const timeFunctionObject &)=delete
No copy construct.
Mesh data needed to do the Finite Volume discretisation.
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
const word & regionName() const
The mesh region name or word::null if polyMesh::defaultRegion.
A patch is a list of labels that address the faces in the global face list.
A class for handling character strings derived from std::string.
@ BEGIN_LIST
Begin list [isseparator].
@ END_LIST
End list [isseparator].
A wordRe is a Foam::word, but can contain a regular expression for matching words or strings.
A List of wordRe with additional matching capabilities.
static labelList matching(const wordRe &select, const UList< StringType > &input, const bool invert=false)
Determine the list indices for all matches.
A class for handling words, derived from Foam::string.
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
static const word null
An empty word.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Foam::PtrList< Foam::fvMesh > meshes(regionNames.size())
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
#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.
Function objects are OpenFOAM utilities to ease workflow configurations and enhance workflows.
void writeList(vtk::formatter &fmt, const UList< uint8_t > &values)
Write a list of uint8_t values.
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
List< word > wordList
List of word.
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values within a list.
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.
List< label > labelList
A List of labels.
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
messageStream Info
Information stream (stdout output on master, null elsewhere).
List< face > faceList
List of faces.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
Ostream & endl(Ostream &os)
Add newline and flush stream.
Ostream & indent(Ostream &os)
Indent stream.
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
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...
errorManip< error > abort(error &err)
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
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?
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
vectorField pointField
pointField is a vectorField.
static void writeData(Ostream &os, const Type &val)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
constexpr char nl
The newline '\n' character (0x0a).
#define forAll(list, i)
Loop across all elements in list.
Operations on lists of strings.
const vector L(dict.get< vector >("L"))