42 namespace functionObjects
60 { regionTypes::stFaceZone,
"faceZone" },
61 { regionTypes::stPatch,
"patch" },
62 { regionTypes::stObject,
"functionObjectSurface" },
63 { regionTypes::stSampled,
"sampledSurface" },
74 { operationType::opNone,
"none" },
75 { operationType::opMin,
"min" },
76 { operationType::opMax,
"max" },
77 { operationType::opSum,
"sum" },
78 { operationType::opSumMag,
"sumMag" },
79 { operationType::opSumDirection,
"sumDirection" },
80 { operationType::opSumDirectionBalance,
"sumDirectionBalance" },
81 { operationType::opAverage,
"average" },
82 { operationType::opAreaAverage,
"areaAverage" },
83 { operationType::opAreaIntegrate,
"areaIntegrate" },
84 { operationType::opCoV,
"CoV" },
85 { operationType::opAreaNormalAverage,
"areaNormalAverage" },
86 { operationType::opAreaNormalIntegrate,
"areaNormalIntegrate" },
87 { operationType::opUniformity,
"uniformity" },
90 { operationType::opWeightedSum,
"weightedSum" },
91 { operationType::opWeightedAverage,
"weightedAverage" },
92 { operationType::opWeightedAreaAverage,
"weightedAreaAverage" },
93 { operationType::opWeightedAreaIntegrate,
"weightedAreaIntegrate" },
94 { operationType::opWeightedUniformity,
"weightedUniformity" },
97 { operationType::opAbsWeightedSum,
"absWeightedSum" },
98 { operationType::opAbsWeightedAverage,
"absWeightedAverage" },
99 { operationType::opAbsWeightedAreaAverage,
"absWeightedAreaAverage" },
100 { operationType::opAbsWeightedAreaIntegrate,
"absWeightedAreaIntegrate" },
101 { operationType::opAbsWeightedUniformity,
"absWeightedUniformity" },
110 { postOperationType::postOpNone,
"none" },
111 { postOperationType::postOpMag,
"mag" },
112 { postOperationType::postOpSqrt,
"sqrt" },
130 void Foam::functionObjects::fieldValues::surfaceFieldValue::setFaceZoneFaces()
135 mesh_.faceZones().indices(selectionNames_)
140 for (
const label zoneId : zoneIds)
142 numFaces += mesh_.faceZones()[zoneId].
size();
149 << regionTypeNames_[regionType_] <<
'(' << regionName_ <<
"):" <<
nl 150 <<
" No matching face zone(s): " 152 <<
" Known face zones: " 163 << regionTypeNames_[regionType_] <<
'(' << regionName_ <<
"):" <<
nl 164 <<
" The faceZone specification: " 166 <<
" resulted in 0 faces" <<
nl 171 faceId_.resize_nocopy(numFaces);
172 facePatchId_.resize_nocopy(numFaces);
173 faceFlip_.resize_nocopy(numFaces);
177 for (
const label zoneId : zoneIds)
179 const faceZone& fZone = mesh_.faceZones()[zoneId];
183 const label meshFacei = fZone[i];
184 const bool isFlip = fZone.flipMap()[i];
188 label facePatchId = -1;
191 if (!mesh_.isInternalFace(meshFacei))
193 facePatchId = mesh_.boundaryMesh().whichPatch(meshFacei);
194 const polyPatch&
pp = mesh_.boundaryMesh()[facePatchId];
196 if (isA<emptyPolyPatch>(
pp))
201 const auto* cpp = isA<coupledPolyPatch>(
pp);
203 if (cpp && !cpp->owner())
213 faceId_[numFaces] =
faceId;
214 facePatchId_[numFaces] = facePatchId;
215 faceFlip_[numFaces] = isFlip;
223 faceId_.resize(numFaces);
224 facePatchId_.resize(numFaces);
225 faceFlip_.resize(numFaces);
230 void Foam::functionObjects::fieldValues::surfaceFieldValue::setPatchFaces()
240 mesh_.boundaryMesh().patchSet
247 DynamicList<label> bad;
248 for (
const label patchi : selected)
250 const polyPatch&
pp = mesh_.boundaryMesh()[patchi];
252 if (isA<emptyPolyPatch>(
pp))
258 numFaces +=
pp.size();
264 label nGood = (selected.size() - bad.size());
268 os <<
"Cannot sample an empty patch" <<
nl;
270 for (
const label patchi : bad)
273 << mesh_.boundaryMesh()[patchi].name() <<
nl;
278 os <<
"No non-empty patches selected" <<
endl 283 os <<
"Selected " << nGood <<
" non-empty patches" <<
nl;
288 for (
const label patchi : selected)
290 if (!bad.found(patchi))
306 << regionTypeNames_[regionType_] <<
'(' << regionName_ <<
"):" <<
nl 307 <<
" No matching patch name(s): " 309 <<
" Known patch names:" <<
nl 310 << mesh_.boundaryMesh().names() <<
nl 320 << regionTypeNames_[regionType_] <<
'(' << regionName_ <<
"):" <<
nl 321 <<
" The patch specification: " 323 <<
" resulted in 0 faces" <<
nl 328 faceId_.resize(numFaces);
329 facePatchId_.resize(numFaces);
330 faceFlip_.resize(numFaces);
336 const polyPatch&
pp = mesh_.boundaryMesh()[patchi];
337 const label len =
pp.size();
339 SubList<label>(faceId_, len, numFaces) =
identity(len);
340 SubList<label>(facePatchId_, len, numFaces) = patchi;
341 SubList<bool>(faceFlip_, len, numFaces) =
false;
348 void Foam::functionObjects::fieldValues::surfaceFieldValue::combineMeshGeometry
359 const label patchi = facePatchId_[i];
362 whichFaces[i] += mesh_.boundaryMesh()[patchi].start();
368 IndirectList<face>(mesh_.faces(), std::move(whichFaces)),
378 autoPtr<globalIndex> globalPoints;
379 autoPtr<globalIndex> globalFaces;
388 uniqueMeshPointLabels,
398 faces =
pp.localFaces();
404 void Foam::functionObjects::fieldValues::surfaceFieldValue::
405 combineSurfaceGeometry
411 if (stObject == regionType_)
413 const auto&
s = refCast<const polySurface>(obr());
418 const scalar mergeDim = 1
e-10*boundBox(
s.points(),
true).
mag();
434 else if (sampledPtr_)
436 const sampledSurface&
s = *sampledPtr_;
441 const scalar mergeDim = 1
e-10*mesh_.bounds().mag();
461 Foam::functionObjects::fieldValues::surfaceFieldValue::totalArea()
const 463 scalar totalArea = 0;
465 if (stObject == regionType_)
467 const auto&
s = refCast<const polySurface>(obr());
469 totalArea =
gSum(
s.magSf());
471 else if (sampledPtr_)
473 totalArea =
gSum(sampledPtr_->magSf());
477 totalArea =
gSum(filterField(mesh_.magSf()));
510 sampledPtr_->update();
532 const auto&
s = refCast<const polySurface>(obr());
538 nFaces_ =
returnReduce(sampledPtr_->faces().size(), sumOp<label>());
549 << regionTypeNames_[regionType_] <<
'(' << regionName_ <<
"):" <<
nl 553 totalArea_ = totalArea();
555 Log <<
" total faces = " << nFaces_ <<
nl 556 <<
" total area = " << totalArea_ <<
nl 559 writeFileHeader(file());
561 needsUpdate_ =
false;
571 if (canWriteHeader() && (operation_ != opNone))
573 writeCommented(
os,
"Region type : ");
574 os << regionTypeNames_[regionType_] <<
' ' << regionName_ <<
nl;
576 writeHeaderValue(
os,
"Faces", nFaces_);
577 writeHeaderValue(
os,
"Area", totalArea_);
578 writeHeaderValue(
os,
"Scale factor", scaleFactor_);
580 if (weightFieldNames_.size())
590 writeCommented(
os,
"Time");
598 for (
const word& fieldName : fields_)
600 os <<
tab << operationTypeNames_[operation_]
601 <<
'(' << fieldName <<
')';
607 writtenHeader_ =
true;
627 case opSumDirectionBalance:
636 case opWeightedUniformity:
637 case opAbsWeightedUniformity:
639 const scalar areaTotal =
gSum(
mag(Sf));
644 if (is_weightedOp() && canWeight(weightField))
650 weightingFactor(weightField, is_magOp())
654 mean =
gSum(weight()*areaVal()) / areaTotal;
657 numer =
gSum(
mag(weight*areaVal - (mean *
mag(Sf))));
664 mean =
gSum(areaVal()) / areaTotal;
667 numer =
gSum(
mag(areaVal - (mean *
mag(Sf))));
671 const scalar ui = 1 - numer/(2*
mag(mean*areaTotal) + ROOTVSMALL);
679 return processSameTypeValues(
values, Sf, weightField);
703 case opSumDirectionBalance:
710 case opAreaNormalAverage:
715 case opAreaNormalIntegrate:
722 case opWeightedUniformity:
723 case opAbsWeightedUniformity:
725 const scalar areaTotal =
gSum(
mag(Sf));
726 tmp<scalarField> areaVal(
values & Sf);
730 if (is_weightedOp() && canWeight(weightField))
734 tmp<scalarField> weight
736 weightingFactor(weightField, is_magOp())
740 mean =
gSum(weight()*areaVal()) / areaTotal;
743 numer =
gSum(
mag(weight*areaVal - (mean *
mag(Sf))));
750 mean =
gSum(areaVal()) / areaTotal;
753 numer =
gSum(
mag(areaVal - (mean *
mag(Sf))));
757 const scalar ui = 1 - numer/(2*
mag(mean*areaTotal) + ROOTVSMALL);
765 return processSameTypeValues(
values, Sf, weightField);
783 return mag(weightField);
811 return mag(weightField);
839 return mag(weightField *
mag(Sf));
842 return (weightField *
mag(Sf));
864 const label len = weightField.
size();
867 auto& result = tresult.ref();
869 for (label facei=0; facei < len; ++facei)
872 result[facei] = (weightField[facei] & unitNormal);
877 for (scalar& val : result)
907 return mag(weightField & Sf);
910 return (weightField & Sf);
924 regionType_(regionTypeNames_.
get(
"regionType",
dict)),
925 operation_(operationTypeNames_.
get(
"operation",
dict)),
928 postOperationTypeNames_.getOrDefault
932 postOperationType::postOpNone,
958 regionType_(regionTypeNames_.
get(
"regionType",
dict)),
959 operation_(operationTypeNames_.
get(
"operation",
dict)),
962 postOperationTypeNames_.getOrDefault
966 postOperationType::postOpNone,
1000 needsUpdate_ =
true;
1001 writeArea_ =
dict.getOrDefault(
"writeArea",
false);
1002 weightFieldNames_.clear();
1009 facePatchId_.clear();
1011 sampledPtr_.reset(
nullptr);
1012 surfaceWriterPtr_.reset(
nullptr);
1019 regionName_.clear();
1020 selectionNames_.clear();
1023 dict.readIfPresent(
"names", selectionNames_);
1025 for (
const auto& item : selectionNames_)
1027 if (item.isLiteral())
1048 if (selectionNames_.empty())
1050 selectionNames_.resize(1);
1051 selectionNames_.first() = regionName_;
1058 if (stSampled == regionType_)
1064 dict.subDict(
"sampledSurfaceDict")
1068 sampledPtr_->isPointData(
false);
1074 if (postOperation_ != postOpNone)
1076 Info<< postOperationTypeNames_[postOperation_] <<
'(' 1077 << operationTypeNames_[operation_] <<
')' <<
nl;
1081 Info<< operationTypeNames_[operation_] <<
nl;
1084 if (is_weightedOp())
1088 bool missing =
true;
1089 if (
dict.readIfPresent(
"weightFields", weightFieldNames_))
1095 weightFieldNames_.resize(1);
1097 if (
dict.readIfPresent(
"weightField", weightFieldNames_.first()))
1100 if (
"none" == weightFieldNames_.first())
1103 weightFieldNames_.clear();
1112 <<
"The '" << operationTypeNames_[operation_]
1113 <<
"' operation is missing a weightField." <<
nl 1114 <<
"Either provide the weightField, " 1115 <<
"use weightField 'none' to suppress weighting," <<
nl 1116 <<
"or use a different operation." 1120 Info<<
" weight field = ";
1121 if (weightFieldNames_.empty())
1131 if (stSampled == regionType_ && sampledPtr_)
1133 Info<<
" sampled surface: ";
1134 sampledPtr_->print(
Info, 0);
1140 const word writerType =
dict.get<word>(
"surfaceFormat");
1142 surfaceWriterPtr_.reset
1152 surfaceWriterPtr_->nFields(fields_.size());
1156 surfaceWriterPtr_->verbose(
true);
1159 if (surfaceWriterPtr_->enabled())
1161 Info<<
" surfaceFormat = " << writerType <<
nl;
1165 surfaceWriterPtr_->clear();
1177 if (needsUpdate_ || operation_ != opNone)
1184 if (operation_ != opNone)
1186 writeCurrentTime(file());
1191 totalArea_ = totalArea();
1192 Log <<
" total area = " << totalArea_ <<
endl;
1196 file() <<
tab << totalArea_;
1204 if (stObject == regionType_)
1206 const auto&
s = refCast<const polySurface>(obr());
1209 else if (sampledPtr_)
1211 Sf = sampledPtr_->Sf();
1215 Sf = filterField(mesh_.Sf());
1223 if (surfaceWriterPtr_)
1225 if (withTopologicalMerge())
1227 combineMeshGeometry(faces,
points);
1231 combineSurfaceGeometry(faces,
points);
1245 for (
const word& weightName : weightFieldNames_)
1247 if (validField<scalar>(weightName))
1249 tmp<scalarField> tfld = getFieldValues<scalar>(weightName,
true);
1251 if (scalarWeights.empty())
1253 scalarWeights = tfld;
1257 scalarWeights *= tfld;
1260 else if (validField<vector>(weightName))
1262 tmp<vectorField> tfld = getFieldValues<vector>(weightName,
true);
1264 if (vectorWeights.empty())
1266 vectorWeights = tfld;
1271 <<
"weightField " << weightName
1272 <<
" - only one vector weight field allowed. " <<
nl 1277 else if (weightName !=
"none")
1285 <<
"weightField " << weightName
1286 <<
" not found or an unsupported type" <<
nl 1295 if (scalarWeights.size())
1297 vectorWeights *= scalarWeights;
1300 writeAll(Sf, vectorWeights,
points, faces);
1304 writeAll(Sf, scalarWeights,
points, faces);
1308 if (operation_ != opNone)
1324 needsUpdate_ =
true;
1333 needsUpdate_ =
true;
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
A surface mesh consisting of general polygon faces and capable of holding fields. ...
static const Enum< regionTypes > regionTypeNames_
Region type names.
void size(const label n)
Older name for setAddressableSize.
const Type & lookupObject(const word &name, const bool recursive=false) const
Lookup and return const reference to the object of the given Type. Fatal if not found or the wrong ty...
virtual ~surfaceFieldValue()
Destructor.
surfaceFieldValue(const word &name, const Time &runTime, const dictionary &dict)
Construct from name, Time and dictionary.
objectRegistry & storedObjects()
Write access to the output objects ("functionObjectObjects") registered on Time.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
virtual bool write()
Calculate and write.
Calculate with function object surface.
constexpr char nl
The newline '\n' character (0x0a)
static const Enum< postOperationType > postOperationTypeNames_
Operation type names.
Ostream & endl(Ostream &os)
Add newline and flush stream.
virtual bool read(const dictionary &dict)
Read from dictionary.
Surround with '\0' and '\0' separate with ','.
static bool & parRun() noexcept
Test if this a parallel run.
regionTypes
Region type enumeration.
A face regionType variant of the fieldValues function object.
constexpr char tab
The tab '\t' character(0x09)
bool update()
Update the surface and surface information as required.
virtual bool read(const dictionary &dict)
Read from dictionary.
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
Abstract base-class for Time/database function objects.
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
A PrimitivePatch with an IndirectList for the faces, const reference for the point field...
static dictionary formatOptions(const dictionary &dict, const word &formatName, const word &entryName="formatOptions")
Same as fileFormats::getFormatOptions.
static autoPtr< sampledSurface > New(const word &name, const polyMesh &mesh, const dictionary &dict)
Return a reference to the selected surface.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
dimensionedScalar neg(const dimensionedScalar &ds)
virtual void updateMesh(const mapPolyMesh &mpm)
Update for changes of mesh.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Macros for easy insertion into run-time selection tables.
const dictionary & dict() const noexcept
Return the reference to the construction dictionary.
bool read(const char *buf, int32_t &val)
Same as readInt32.
#define forAll(list, i)
Loop across all elements in list.
operationType
Operation type enumeration.
postOperationType
Post-operation type enumeration.
List< face > faceList
List of faces.
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
Type gSum(const FieldField< Field, Type > &f)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
regionTypes regionType_
Region type.
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
addToRunTimeSelectionTable(fieldValue, surfaceFieldValue, runTime)
Reading is optional [identical to LAZY_READ].
virtual void writeFileHeader(Ostream &os)
Output file header information.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
static const Enum< operationType > operationTypeNames_
Operation type names.
errorManip< error > abort(error &err)
An Ostream is an abstract base class for all output systems (streams, files, token lists...
dimensionedScalar pos0(const dimensionedScalar &ds)
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field...
Represents 0/1 range or concept. Used for tagged dispatch or clamping.
static tmp< scalarField > areaWeightingFactor(const Field< WeightType > &weightField, const vectorField &Sf, const bool useMag)
Weighting factor, weight field with area factor.
word regionName_
Name of region (patch, zone, etc.)
#define WarningInFunction
Report a warning using Foam::Warning.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
const objectRegistry & obr() const
The volume mesh or surface registry being used.
Type processValues(const Field< Type > &values, const vectorField &Sf, const Field< WeightType > &weightField) const
Apply the 'operation' to the values. Wrapper around.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
static tmp< scalarField > weightingFactor(const Field< WeightType > &weightField, const bool useMag)
Weighting factor.
messageStream Info
Information stream (stdout output on master, null elsewhere)
defineTypeNameAndDebug(surfaceFieldValue, 0)
bool usesSf() const noexcept
True if the operation needs a surface Sf.
Intermediate class for handling field value-based function objects.
Field< vector > vectorField
Specialisation of Field<T> for vector.
Mesh consisting of general polyhedral cells.
List< label > labelList
A List of labels.
A class for managing temporary objects.
Registry of regIOobjects.
virtual void movePoints(const polyMesh &mesh)
Update for changes of mesh.
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))
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
const fvMesh & mesh_
Reference to the fvMesh.
static autoPtr< surfaceWriter > New(const word &writeType)
Return a reference to the selected surfaceWriter.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
dimensionSet clamp(const dimensionSet &a, const dimensionSet &range)
virtual bool write()
Write.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...