Go to the documentation of this file.
46 namespace functionObjects
59 { modeType::mdFaceZone ,
"faceZone" },
60 { modeType::mdFaceZoneAndDirection,
"faceZoneAndDirection" },
61 { modeType::mdCellZoneAndDirection,
"cellZoneAndDirection" },
62 { modeType::mdSurface,
"functionObjectSurface" },
63 { modeType::mdSurface,
"surface" },
64 { modeType::mdSurfaceAndDirection,
"surfaceAndDirection" },
97 <<
"Unsupported flux field " << fieldName <<
" with dimensions "
99 <<
". Expected either mass flow or volumetric flow rate."
108 const word& surfName,
120 <<
"Unable to find surface " << surfName
121 <<
". Valid surfaces: "
134 const word& surfName,
147 <<
"Unable to find surface " << surfName
148 <<
". Valid surfaces: "
153 const auto&
s = *surfptr;
154 const vector refDir = dir/(
mag(dir) + ROOTVSMALL);
160 boolList& flips = faceFlip[faceFlip.size()-1];
166 const vector&
n =
s.faceNormals()[i];
168 if ((
n & refDir) > tolerance_)
182 const word& faceZoneName,
190 label zonei = mesh_.faceZones().findZoneID(faceZoneName);
194 <<
"Unable to find faceZone " << faceZoneName
196 << mesh_.faceZones().sortedNames() <<
nl
199 const faceZone& fZone = mesh_.faceZones()[zonei];
201 names.
append(faceZoneName);
210 label facei = fZone[i];
213 label facePatchID = -1;
214 if (mesh_.isInternalFace(facei))
221 facePatchID = mesh_.boundaryMesh().whichPatch(facei);
223 if (isA<coupledPolyPatch>(pp))
225 if (refCast<const coupledPolyPatch>(pp).owner())
234 else if (!isA<emptyPolyPatch>(pp))
236 faceID = facei - pp.
start();
257 faceIDs.append(faceID);
258 facePatchIDs.append(facePatchID);
264 facePatchID.
append(facePatchIDs);
271 const word& faceZoneName,
280 const vector refDir = dir/(
mag(dir) + ROOTVSMALL);
282 label zonei = mesh_.faceZones().findZoneID(faceZoneName);
286 <<
"Unable to find faceZone " << faceZoneName
288 << mesh_.faceZones().sortedNames() <<
nl
291 const faceZone& fZone = mesh_.faceZones()[zonei];
293 names.
append(faceZoneName);
307 label facei = fZone[i];
310 label facePatchID = -1;
311 if (mesh_.isInternalFace(facei))
318 facePatchID = mesh_.boundaryMesh().whichPatch(facei);
320 if (isA<coupledPolyPatch>(pp))
322 if (refCast<const coupledPolyPatch>(pp).owner())
331 else if (!isA<emptyPolyPatch>(pp))
333 faceID = facei - pp.
start();
345 if (facePatchID != -1)
347 n = Sf.boundaryField()[facePatchID][faceID]
352 n = Sf[faceID]/(magSf[faceID] + ROOTVSMALL);
355 if ((
n & refDir) > tolerance_)
364 faceIDs.append(faceID);
365 facePatchIDs.append(facePatchID);
371 facePatchID.
append(facePatchIDs);
378 const word& cellZoneName,
387 const vector refDir = dir/(
mag(dir) + ROOTVSMALL);
389 const label cellZonei = mesh_.cellZones().findZoneID(cellZoneName);
393 <<
"Unable to find cellZone " << cellZoneName
395 << mesh_.cellZones().sortedNames() <<
nl
399 const label nInternalFaces = mesh_.nInternalFaces();
403 const labelList& cellIDs = mesh_.cellZones()[cellZonei];
405 labelList nbrFaceCellAddr(mesh_.nFaces() - nInternalFaces, -1);
415 label facei = pp.
start() + i;
416 label nbrFacei = facei - nInternalFaces;
417 label own = mesh_.faceOwner()[facei];
418 nbrFaceCellAddr[nbrFacei] = cellAddr[own];
433 for (label facei = 0; facei < nInternalFaces; facei++)
435 const label own = cellAddr[mesh_.faceOwner()[facei]];
436 const label nbr = cellAddr[mesh_.faceNeighbour()[facei]];
438 if (((own != -1) && (nbr == -1)) || ((own == -1) && (nbr != -1)))
440 vector n = mesh_.faces()[facei].unitNormal(mesh_.points());
442 if ((
n & refDir) > tolerance_)
445 faceLocalPatchIDs.append(facei);
446 facePatchIDs.append(-1);
449 else if ((
n & -refDir) > tolerance_)
452 faceLocalPatchIDs.append(facei);
453 facePatchIDs.append(-1);
466 const label facei = pp.
start() + localFacei;
467 const label own = cellAddr[mesh_.faceOwner()[facei]];
468 const label nbr = nbrFaceCellAddr[facei - nInternalFaces];
470 if ((own != -1) && (nbr == -1))
472 vector n = mesh_.faces()[facei].unitNormal(mesh_.points());
474 if ((
n & refDir) > tolerance_)
477 faceLocalPatchIDs.append(localFacei);
478 facePatchIDs.append(patchi);
481 else if ((
n & -refDir) > tolerance_)
484 faceLocalPatchIDs.append(localFacei);
485 facePatchIDs.append(patchi);
501 OBJstream os(mesh_.time().path()/
"patch.obj");
503 os.
write(faces, mesh_.points(),
false);
514 <<
"initialiseCellZoneAndDirection: "
515 <<
"Starting walk to split patch into faceZones"
524 bool dummyData{
false};
532 for (; oldFaceID <
patch.size(); oldFaceID++)
534 if (!allFaceInfo[oldFaceID].valid<bool>(dummyData))
536 seedFacei = globalFaces.toGlobal(oldFaceID);
547 if (globalFaces.isLocal(seedFacei))
549 const label localFacei = globalFaces.toLocal(seedFacei);
552 for (
const label edgei : fEdges)
554 if (allEdgeInfo[edgei].valid<bool>(dummyData))
557 <<
"Problem in edge face wave: attempted to assign a "
558 <<
"value to an edge that has already been visited. "
559 <<
"Edge info: " << allEdgeInfo[edgei]
563 changedEdges.
append(edgei);
594 forAll(allFaceInfo, facei)
596 if (allFaceInfo[facei].
data() == regioni)
602 Info<<
"*** region:" << regioni
611 const label nRegion = regioni;
618 <<
"Region split failed" <<
nl
627 forAll(allFaceInfo, facei)
629 regioni = allFaceInfo[facei].data();
631 regionFaceIDs[regioni].
append(faceLocalPatchIDs[facei]);
632 regionFacePatchIDs[regioni].
append(facePatchIDs[facei]);
633 regionFaceFlips[regioni].
append(flips[facei]);
637 forAll(regionFaceIDs, regioni)
639 const word zoneName = cellZoneName +
":faceZone" +
Foam::name(regioni);
642 faceID.
append(regionFaceIDs[regioni]);
643 facePatchID.
append(regionFacePatchIDs[regioni]);
644 faceFlip.
append(regionFaceFlips[regioni]);
649 OBJstream os(mesh_.time().path()/zoneName +
".obj");
650 faceList faces(mesh_.faces(), regionFaceIDs[regioni]);
651 os.
write(faces, mesh_.points(),
false);
658 <<
" Created " << faceID.size()
659 <<
" separate face zones from cell zone " << cellZoneName <<
nl;
664 Info<<
" " << names[i] <<
": "
665 << nFaces <<
" faces" <<
nl;
683 storedObjects().lookupObject<
polySurface>(zoneNames_[idx]);
685 sumMagSf =
sum(
s.magSf());
692 const labelList& facePatchIDs = facePatchID_[idx];
696 label facei = faceIDs[i];
698 if (facePatchIDs[i] == -1)
700 sumMagSf += magSf[facei];
704 label patchi = facePatchIDs[i];
716 for (
const word& surfName : zoneNames_)
719 storedObjects().lookupObject<
polySurface>(surfName);
724 << checkFlowType(
phi.dimensions(),
phi.name()) <<
" write:" <<
nl;
731 storedObjects().lookupObject<
polySurface>(zoneNames_[surfi]);
735 checkFlowType(
phi.dimensions(),
phi.name());
737 const boolList& flips = faceFlip_[surfi];
747 scalar phif =
phis[i];
766 phiPos *= scaleFactor_;
767 phiNeg *= scaleFactor_;
769 scalar netFlux = phiPos + phiNeg;
770 scalar absoluteFlux = phiPos - phiNeg;
772 Log <<
" surface " << zoneNames_[surfi] <<
':' <<
nl
773 <<
" positive : " << phiPos <<
nl
774 <<
" negative : " << phiNeg <<
nl
775 <<
" net : " << netFlux <<
nl
776 <<
" absolute : " << absoluteFlux
829 case mdFaceZoneAndDirection:
833 initialiseFaceZoneAndDirection
836 zoneDirections_[zonei],
846 case mdCellZoneAndDirection:
850 initialiseCellZoneAndDirection
853 zoneDirections_[zonei],
877 case mdSurfaceAndDirection:
881 initialiseSurfaceAndDirection
884 zoneDirections_[zonei],
896 zoneNames_.transfer(faceZoneName);
897 faceID_.transfer(faceID);
898 facePatchID_.transfer(facePatchID);
899 faceFlip_.transfer(faceFlips);
907 const word& zoneName = zoneNames_[zonei];
908 areas[zonei] = totalArea(zonei);
912 Info<<
" Surface: " << zoneName
913 <<
", area: " << areas[zonei] <<
nl;
917 Info<<
" Zone: " << zoneName
918 <<
", area: " << areas[zonei] <<
nl;
925 filePtrs_.resize(zoneNames_.size());
929 const word& zoneName = zoneNames_[zonei];
930 filePtrs_.set(zonei, createFile(zoneName));
943 needsUpdate_ =
false;
984 mode_ = modeTypeNames_.get(
"mode",
dict);
985 phiName_ =
dict.getOrDefault<
word>(
"phi",
"phi");
986 scaleFactor_ =
dict.getOrDefault<scalar>(
"scaleFactor", 1);
987 tolerance_ =
dict.getOrDefault<scalar>(
"tolerance", 0.8);
990 zoneDirections_.clear();
998 dict.readEntry(
"faceZones", zoneNames_);
1001 case mdFaceZoneAndDirection:
1003 dict.readEntry(
"faceZoneAndDirection", nameAndDirection);
1006 case mdCellZoneAndDirection:
1008 dict.readEntry(
"cellZoneAndDirection", nameAndDirection);
1013 dict.readEntry(
"surfaces", zoneNames_);
1016 case mdSurfaceAndDirection:
1018 dict.readEntry(
"surfaceAndDirection", nameAndDirection);
1024 <<
"unhandled enumeration " << modeTypeNames_[mode_]
1031 if (nameAndDirection.size())
1033 zoneNames_.resize(nameAndDirection.size());
1034 zoneDirections_.resize(nameAndDirection.size());
1040 zoneNames_[zonei] = nameDirn.first();
1041 zoneDirections_[zonei] = nameDirn.second();
1045 nameAndDirection.clear();
1050 << modeTypeNames_[mode_] <<
") with selection:\n "
1053 return !zoneNames_.empty();
1059 const word& zoneName,
1066 if (isSurfaceMode())
1068 writeHeaderValue(os,
"Surface", zoneName);
1072 writeHeaderValue(os,
"Face zone", zoneName);
1074 writeHeaderValue(os,
"Total area",
area);
1078 case mdFaceZoneAndDirection:
1079 case mdCellZoneAndDirection:
1080 case mdSurfaceAndDirection:
1082 writeHeaderValue(os,
"Reference direction", refDir);
1089 writeHeaderValue(os,
"Scale factor", scaleFactor_);
1091 writeCommented(os,
"Time");
1092 os <<
tab <<
"positive"
1093 <<
tab <<
"negative"
1095 <<
tab <<
"absolute"
1110 if (isSurfaceMode())
1112 return surfaceModeWrite();
1118 << checkFlowType(
phi.dimensions(),
phi.name()) <<
" write:" <<
nl;
1120 forAll(zoneNames_, zonei)
1122 const labelList& faceID = faceID_[zonei];
1123 const labelList& facePatchID = facePatchID_[zonei];
1124 const boolList& faceFlips = faceFlip_[zonei];
1132 label facei = faceID[i];
1133 label patchi = facePatchID[i];
1137 phif =
phi.boundaryField()[patchi][facei];
1162 phiPos *= scaleFactor_;
1163 phiNeg *= scaleFactor_;
1165 scalar netFlux = phiPos + phiNeg;
1166 scalar absoluteFlux = phiPos - phiNeg;
1168 Log <<
" faceZone " << zoneNames_[zonei] <<
':' <<
nl
1169 <<
" positive : " << phiPos <<
nl
1170 <<
" negative : " << phiNeg <<
nl
1171 <<
" net : " << netFlux <<
nl
1172 <<
" absolute : " << absoluteFlux
int debug
Static debugging option.
void initialiseCellZoneAndDirection(const word &cellZoneName, const vector &refDir, DynamicList< word > &names, DynamicList< vector > &dir, DynamicList< labelList > &faceID, DynamicList< labelList > &facePatchID, DynamicList< boolList > &faceFlip) const
Initialise face set from cell zone and direction.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
A class for handling words, derived from Foam::string.
void initialiseFaceZoneAndDirection(const word &faceZoneName, const vector &refDir, DynamicList< word > &names, DynamicList< vector > &dir, DynamicList< labelList > &faceID, DynamicList< labelList > &facePatchID, DynamicList< boolList > &faceFlip) const
Initialise face set from face zone and direction.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
OFstream that keeps track of vertices.
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
A class for managing temporary objects.
static constexpr const zero Zero
Global zero (0)
bool surfaceModeWrite()
Specialized write for surfaces.
bool isSurfaceMode() const
Check if surface mode instead of zone mode.
Wave propagation of information along patch. Every iteration information goes through one layer of fa...
bool read(const char *buf, int32_t &val)
Same as readInt32.
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
A functionObject surface.
List< bool > boolList
A List of bools.
void append(const T &val)
Append an element at the end of the list.
Ostream & endl(Ostream &os)
Add newline and flush stream.
word checkFlowType(const dimensionSet &fieldDims, const word &fieldName) const
Check flowType (mass or volume)
static void writeHeader(Ostream &os, const word &fieldName)
Dimension set for the base types.
Set of directions for each cell in the mesh. Either uniform and size=1 or one set of directions per c...
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
virtual bool execute()
Execute, currently does nothing.
scalar totalArea(const label idx) const
Calculate the total area for the surface or derived faceZone.
static const Enum< modeType > modeTypeNames_
Face mode names.
#define forAll(list, i)
Loop across all elements in list.
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
virtual bool read(const dictionary &dict)
Read.
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
A surface mesh consisting of general polygon faces and capable of holding fields.
virtual void writeFileHeader(const word &zoneName, const scalar area, const vector &refDir, Ostream &os) const
Output file header information.
const dimensionSet dimArea(sqr(dimLength))
const polyBoundaryMesh & boundaryMesh() const
Return boundaryMesh reference.
A subset of mesh faces organised as a primitive patch.
messageStream Info
Information stream (uses stdout - output is on the master only)
A patch is a list of labels that address the faces in the global face list.
word name(const complex &c)
Return string representation of complex.
fluxSummary(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
void initialiseSurface(const word &surfName, DynamicList< word > &names, DynamicList< vector > &dir, DynamicList< boolList > &faceFlip) const
Initialise for given surface name.
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
void initialiseFaceZone(const word &faceZoneName, DynamicList< word > &names, DynamicList< vector > &dir, DynamicList< labelList > &faceID, DynamicList< labelList > &facePatchID, DynamicList< boolList > &faceFlip) const
Initialise face set from face zone.
A List with indirect addressing.
For use with PatchEdgeFaceWave. Determines topological distance to starting edges....
A surface with prescribed direction.
modeType mode_
Mode for face determination/to generate faces to test.
virtual bool write()
Write the fluxSummary.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
virtual bool read(const dictionary &dict)
Read optional controls.
void initialiseSurfaceAndDirection(const word &surfName, const vector &refDir, DynamicList< word > &names, DynamicList< vector > &dir, DynamicList< boolList > &faceFlip) const
Initialise for given surface name and direction.
Macros for easy insertion into run-time selection tables.
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
errorManip< error > abort(error &err)
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
label start() const
Return start label of this patch in the polyMesh face list.
errorManipArg< error, int > exit(error &err, const int errNo=1)
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
A PrimitivePatch with an IndirectList for the faces, const reference for the point field.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
#define DebugInfo
Report an information message using Foam::Info.
label whichFace(const label l) const
Return label of face in patch from global face label.
const Type * cfindObject(const word &name, const bool recursive=false) const
Return const pointer to the object of the given Type.
addToRunTimeSelectionTable(functionObject, ObukhovLength, dictionary)
const std::string patch
OpenFOAM patch number as a std::string.
virtual bool read(const dictionary &dict)
Read the field fluxSummary data.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
defineTypeNameAndDebug(ObukhovLength, 0)
static const word null
An empty word.
const wordList area
Standard area field types (scalar, vector, tensor, etc)
Computes the natural logarithm of an input volScalarField.
Base class for writing single files from the function objects.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
const dimensionSet dimVolume(pow3(dimLength))
void setSize(const label newSize)
Alias for resize(const label)
const boolList & flipMap() const
Return face flip map.
bool update()
Initialise - after read(), before write()
#define WarningInFunction
Report a warning using Foam::Warning.
Database for solution data, solver performance and other reduced data.
edgeScalarField phis(IOobject("phis", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE), linearEdgeInterpolate(Us) &aMesh.Le())
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
A list of faces which address into the list of points.
UIndirectList< label > labelUIndList
UIndirectList of labels.