45 namespace functionObjects
63 { regionTypes::stFaceZone,
"faceZone" },
64 { regionTypes::stPatch,
"patch" },
65 { regionTypes::stObject,
"functionObjectSurface" },
66 { regionTypes::stSampled,
"sampledSurface" },
77 { operationType::opNone,
"none" },
78 { operationType::opMin,
"min" },
79 { operationType::opMax,
"max" },
80 { operationType::opSum,
"sum" },
81 { operationType::opSumMag,
"sumMag" },
82 { operationType::opSumDirection,
"sumDirection" },
83 { operationType::opSumDirectionBalance,
"sumDirectionBalance" },
84 { operationType::opAverage,
"average" },
85 { operationType::opAreaAverage,
"areaAverage" },
86 { operationType::opAreaIntegrate,
"areaIntegrate" },
87 { operationType::opCoV,
"CoV" },
88 { operationType::opAreaNormalAverage,
"areaNormalAverage" },
89 { operationType::opAreaNormalIntegrate,
"areaNormalIntegrate" },
90 { operationType::opUniformity,
"uniformity" },
93 { operationType::opWeightedSum,
"weightedSum" },
94 { operationType::opWeightedAverage,
"weightedAverage" },
95 { operationType::opWeightedAreaAverage,
"weightedAreaAverage" },
96 { operationType::opWeightedAreaIntegrate,
"weightedAreaIntegrate" },
97 { operationType::opWeightedUniformity,
"weightedUniformity" },
100 { operationType::opAbsWeightedSum,
"absWeightedSum" },
101 { operationType::opAbsWeightedAverage,
"absWeightedAverage" },
102 { operationType::opAbsWeightedAreaAverage,
"absWeightedAreaAverage" },
103 { operationType::opAbsWeightedAreaIntegrate,
"absWeightedAreaIntegrate" },
104 { operationType::opAbsWeightedUniformity,
"absWeightedUniformity" },
113 { postOperationType::postOpNone,
"none" },
114 { postOperationType::postOpMag,
"mag" },
115 { postOperationType::postOpSqrt,
"sqrt" },
133 void Foam::functionObjects::fieldValues::surfaceFieldValue::setFaceZoneFaces()
138 mesh_.faceZones().indices(selectionNames_)
143 for (
const label zoneId : zoneIds)
145 numFaces += mesh_.faceZones()[zoneId].
size();
148 faceId_.resize_nocopy(numFaces);
149 facePatchId_.resize_nocopy(numFaces);
150 faceFlip_.resize_nocopy(numFaces);
154 for (
const label zoneId : zoneIds)
156 const faceZone& fZone = mesh_.faceZones()[zoneId];
160 const label meshFacei = fZone[i];
161 const bool isFlip = fZone.flipMap()[i];
165 label facePatchId = -1;
168 if (!mesh_.isInternalFace(meshFacei))
170 facePatchId = mesh_.boundaryMesh().whichPatch(meshFacei);
171 const polyPatch&
pp = mesh_.boundaryMesh()[facePatchId];
173 if (isA<emptyPolyPatch>(
pp))
178 const auto* cpp = isA<coupledPolyPatch>(
pp);
180 if (cpp && !cpp->owner())
190 faceId_[numFaces] =
faceId;
191 facePatchId_[numFaces] = facePatchId;
192 faceFlip_[numFaces] = isFlip;
200 faceId_.resize(numFaces);
201 facePatchId_.resize(numFaces);
202 faceFlip_.resize(numFaces);
213 switch (emptySurfaceError_)
242 << regionTypeNames_[regionType_]
243 <<
'(' << regionName_ <<
"):" <<
nl;
248 <<
" No matching face zones: " 250 <<
" Known face zones: " 256 <<
" The face zones: " 258 <<
" resulted in 0 faces" <<
nl;
268 <<
"... suppressing further warnings." <<
nl;
275 void Foam::functionObjects::fieldValues::surfaceFieldValue::setPatchFaces()
285 mesh_.boundaryMesh().indices(selectionNames_,
true)
288 DynamicList<label> bad;
289 for (
const label patchi : selected)
291 const polyPatch&
pp = mesh_.boundaryMesh()[patchi];
293 if (isA<emptyPolyPatch>(
pp))
299 numFaces +=
pp.size();
305 label nGood = (selected.size() - bad.size());
309 os <<
"Cannot sample an empty patch" <<
nl;
311 for (
const label patchi : bad)
314 << mesh_.boundaryMesh()[patchi].name() <<
nl;
319 os <<
"No non-empty patches selected" <<
endl 324 os <<
"Selected " << nGood <<
" non-empty patches" <<
nl;
329 for (
const label patchi : selected)
331 if (!bad.contains(patchi))
343 faceId_.resize_nocopy(numFaces);
344 facePatchId_.resize_nocopy(numFaces);
345 faceFlip_.resize_nocopy(numFaces);
351 const polyPatch&
pp = mesh_.boundaryMesh()[patchi];
352 const label len =
pp.size();
354 SubList<label>(faceId_, len, numFaces) =
identity(len);
355 SubList<label>(facePatchId_, len, numFaces) = patchi;
356 SubList<bool>(faceFlip_, len, numFaces) =
false;
369 switch (emptySurfaceError_)
398 << regionTypeNames_[regionType_]
399 <<
'(' << regionName_ <<
"):" <<
nl;
404 <<
" No matching patches: " 406 <<
" Known patch names:" <<
nl 407 << mesh_.boundaryMesh().names() <<
nl;
414 <<
" resulted in 0 faces" <<
nl;
424 <<
"... suppressing further warnings." <<
nl;
431 void Foam::functionObjects::fieldValues::surfaceFieldValue::combineMeshGeometry
442 const label patchi = facePatchId_[i];
445 whichFaces[i] += mesh_.boundaryMesh()[patchi].start();
451 IndirectList<face>(mesh_.faces(), std::move(whichFaces)),
461 autoPtr<globalIndex> globalPoints;
462 autoPtr<globalIndex> globalFaces;
471 uniqueMeshPointLabels,
481 faces =
pp.localFaces();
487 void Foam::functionObjects::fieldValues::surfaceFieldValue::
488 combineSurfaceGeometry
494 if (stObject == regionType_)
496 const auto&
s = refCast<const polySurface>(obr());
501 const scalar mergeDim = 1
e-10*boundBox(
s.points(),
true).
mag();
517 else if (sampledPtr_)
519 const sampledSurface&
s = *sampledPtr_;
524 const scalar mergeDim = 1
e-10*mesh_.bounds().mag();
544 Foam::functionObjects::fieldValues::surfaceFieldValue::totalArea()
const 546 scalar totalArea = 0;
548 if (stObject == regionType_)
550 const auto&
s = refCast<const polySurface>(obr());
552 totalArea =
gSum(
s.magSf());
554 else if (sampledPtr_)
556 totalArea =
gSum(sampledPtr_->magSf());
560 totalArea =
gSum(filterField(mesh_.magSf()));
593 sampledPtr_->update();
604 bool checkEmptyFaces =
true;
612 checkEmptyFaces =
false;
619 checkEmptyFaces =
false;
625 const auto&
s = refCast<const polySurface>(obr());
631 nFaces_ =
returnReduce(sampledPtr_->faces().size(), sumOp<label>());
641 needsUpdate_ =
false;
642 totalArea_ = totalArea();
645 else if (checkEmptyFaces)
653 switch (emptySurfaceError_)
682 << regionTypeNames_[regionType_]
683 <<
'(' << regionName_ <<
"):" <<
nl 684 <<
" Region has no faces" <<
endl;
693 <<
"... suppressing further warnings." <<
nl;
698 Log <<
" total faces = " << nFaces_ <<
nl 699 <<
" total area = " << totalArea_ <<
nl 705 writeFileHeader(file());
717 if (canWriteHeader() && (operation_ != opNone))
719 writeCommented(
os,
"Region type : ");
720 os << regionTypeNames_[regionType_] <<
' ' << regionName_ <<
nl;
722 writeHeaderValue(
os,
"Faces", nFaces_);
723 writeHeaderValue(
os,
"Area", totalArea_);
724 writeHeaderValue(
os,
"Scale factor", scaleFactor_);
726 if (weightFieldNames_.size())
736 writeCommented(
os,
"Time");
744 for (
const word& fieldName : fields_)
746 os <<
tab << operationTypeNames_[operation_]
747 <<
'(' << fieldName <<
')';
753 writtenHeader_ =
true;
773 case opSumDirectionBalance:
782 case opWeightedUniformity:
783 case opAbsWeightedUniformity:
785 const scalar areaTotal =
gSum(
mag(Sf));
790 if (is_weightedOp() && canWeight(weightField))
796 weightingFactor(weightField, is_magOp())
800 mean =
gSum(weight()*areaVal()) / areaTotal;
803 numer =
gSum(
mag(weight*areaVal - (mean *
mag(Sf))));
810 mean =
gSum(areaVal()) / areaTotal;
813 numer =
gSum(
mag(areaVal - (mean *
mag(Sf))));
817 const scalar ui = 1 - numer/(2*
mag(mean*areaTotal) + ROOTVSMALL);
825 return processSameTypeValues(
values, Sf, weightField);
849 case opSumDirectionBalance:
856 case opAreaNormalAverage:
861 case opAreaNormalIntegrate:
868 case opWeightedUniformity:
869 case opAbsWeightedUniformity:
871 const scalar areaTotal =
gSum(
mag(Sf));
872 tmp<scalarField> areaVal(
values & Sf);
876 if (is_weightedOp() && canWeight(weightField))
880 tmp<scalarField> weight
882 weightingFactor(weightField, is_magOp())
886 mean =
gSum(weight()*areaVal()) / areaTotal;
889 numer =
gSum(
mag(weight*areaVal - (mean *
mag(Sf))));
896 mean =
gSum(areaVal()) / areaTotal;
899 numer =
gSum(
mag(areaVal - (mean *
mag(Sf))));
903 const scalar ui = 1 - numer/(2*
mag(mean*areaTotal) + ROOTVSMALL);
911 return processSameTypeValues(
values, Sf, weightField);
929 return mag(weightField);
957 return mag(weightField);
985 return mag(weightField *
mag(Sf));
988 return (weightField *
mag(Sf));
1010 const label len = weightField.
size();
1013 auto& result = tresult.ref();
1015 for (label facei=0; facei < len; ++facei)
1018 result[facei] = (weightField[facei] & unitNormal);
1023 for (scalar& val : result)
1053 return mag(weightField & Sf);
1056 return (weightField & Sf);
1070 regionType_(regionTypeNames_.
get(
"regionType",
dict)),
1071 operation_(operationTypeNames_.
get(
"operation",
dict)),
1074 postOperationTypeNames_.getOrDefault
1078 postOperationType::postOpNone,
1084 emptySurfaceError_(
error::handlerTypes::DEFAULT),
1086 weightFieldNames_(),
1106 regionType_(regionTypeNames_.
get(
"regionType",
dict)),
1107 operation_(operationTypeNames_.
get(
"operation",
dict)),
1110 postOperationTypeNames_.getOrDefault
1114 postOperationType::postOpNone,
1120 emptySurfaceError_(
error::handlerTypes::DEFAULT),
1122 weightFieldNames_(),
1150 needsUpdate_ =
true;
1151 writeArea_ =
dict.getOrDefault(
"writeArea",
false);
1160 weightFieldNames_.clear();
1168 facePatchId_.clear();
1170 sampledPtr_.reset(
nullptr);
1171 surfaceWriterPtr_.reset(
nullptr);
1178 regionName_.clear();
1179 selectionNames_.clear();
1182 dict.readIfPresent(
"names", selectionNames_);
1184 for (
const auto& item : selectionNames_)
1186 if (item.isLiteral())
1207 if (selectionNames_.empty())
1209 selectionNames_.resize(1);
1210 selectionNames_.first() = regionName_;
1217 if (stSampled == regionType_)
1223 dict.subDict(
"sampledSurfaceDict")
1227 sampledPtr_->isPointData(
false);
1233 if (postOperation_ != postOpNone)
1235 Info<< postOperationTypeNames_[postOperation_] <<
'(' 1236 << operationTypeNames_[operation_] <<
')' <<
nl;
1240 Info<< operationTypeNames_[operation_] <<
nl;
1243 if (is_weightedOp())
1247 bool missing =
true;
1248 if (
dict.readIfPresent(
"weightFields", weightFieldNames_))
1254 weightFieldNames_.resize(1);
1256 if (
dict.readIfPresent(
"weightField", weightFieldNames_.first()))
1259 if (
"none" == weightFieldNames_.first())
1262 weightFieldNames_.clear();
1271 <<
"The '" << operationTypeNames_[operation_]
1272 <<
"' operation is missing a weightField." <<
nl 1273 <<
"Either provide the weightField, " 1274 <<
"use weightField 'none' to suppress weighting," <<
nl 1275 <<
"or use a different operation." 1279 Info<<
" weight field = ";
1280 if (weightFieldNames_.empty())
1290 if (stSampled == regionType_ && sampledPtr_)
1292 Info<<
" sampled surface: ";
1293 sampledPtr_->print(
Info, 0);
1299 const word writerType =
dict.get<word>(
"surfaceFormat");
1301 surfaceWriterPtr_.reset
1311 surfaceWriterPtr_->nFields(fields_.size());
1315 surfaceWriterPtr_->verbose(
true);
1318 if (surfaceWriterPtr_->enabled())
1320 Info<<
" surfaceFormat = " << writerType <<
nl;
1324 surfaceWriterPtr_->clear();
1336 if (needsUpdate_ || operation_ != opNone)
1343 if (operation_ != opNone)
1345 writeCurrentTime(file());
1353 if (operation_ != opNone)
1359 Log <<
" total area = " << totalArea_ <<
endl;
1360 file() <<
tab << totalArea_;
1363 file() <<
tab <<
"NaN";
1377 totalArea_ = totalArea();
1378 Log <<
" total area = " << totalArea_ <<
endl;
1382 file() <<
tab << totalArea_;
1390 if (stObject == regionType_)
1392 const auto&
s = refCast<const polySurface>(obr());
1395 else if (sampledPtr_)
1397 Sf = sampledPtr_->Sf();
1401 Sf = filterField(mesh_.Sf());
1409 if (surfaceWriterPtr_)
1411 if (withTopologicalMerge())
1413 combineMeshGeometry(faces,
points);
1417 combineSurfaceGeometry(faces,
points);
1431 for (
const word& weightName : weightFieldNames_)
1433 if (validField<scalar>(weightName))
1435 tmp<scalarField> tfld = getFieldValues<scalar>(weightName,
true);
1437 if (scalarWeights.empty())
1439 scalarWeights = tfld;
1443 scalarWeights *= tfld;
1446 else if (validField<vector>(weightName))
1448 tmp<vectorField> tfld = getFieldValues<vector>(weightName,
true);
1450 if (vectorWeights.empty())
1452 vectorWeights = tfld;
1457 <<
"weightField " << weightName
1458 <<
" - only one vector weight field allowed. " <<
nl 1463 else if (weightName !=
"none")
1471 <<
"weightField " << weightName
1472 <<
" not found or an unsupported type" <<
nl 1481 if (scalarWeights.size())
1483 vectorWeights *= scalarWeights;
1486 writeAll(Sf, vectorWeights,
points, faces);
1490 writeAll(Sf, scalarWeights,
points, faces);
1494 if (operation_ != opNone)
1510 needsUpdate_ =
true;
1519 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.
Default behaviour (local meaning)
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.
EnumType getOrDefault(const word &key, const dictionary &dict, const EnumType deflt, const bool warnOnly=false) const
Find the key in the dictionary and return the corresponding enumeration element based on its name...
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.
Class to handle errors and exceptions in a simple, consistent stream-based manner.
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 expressions::valueTypeCode::INVALID.
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...
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)
Ignore on errors/problems.
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 constexpr const unsigned maxWarnings
static autoPtr< surfaceWriter > New(const word &writeType)
Select construct a surfaceWriter.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
dimensionSet clamp(const dimensionSet &a, const dimensionSet &range)
virtual bool write()
Write.
static const Enum< handlerTypes > handlerNames
Names of the error handler types.
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 ...