59 Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypes
61Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypeNames_
63 { regionTypes::stFaceZone,
"faceZone" },
64 { regionTypes::stPatch,
"patch" },
65 { regionTypes::stObject,
"functionObjectSurface" },
66 { regionTypes::stSampled,
"sampledSurface" },
72 Foam::functionObjects::fieldValues::surfaceFieldValue::operationType
74Foam::functionObjects::fieldValues::surfaceFieldValue::operationTypeNames_
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" },
109 Foam::functionObjects::fieldValues::surfaceFieldValue::postOperationType
111Foam::functionObjects::fieldValues::surfaceFieldValue::postOperationTypeNames_
113 { postOperationType::postOpNone,
"none" },
114 { postOperationType::postOpMag,
"mag" },
115 { postOperationType::postOpSqrt,
"sqrt" },
122Foam::functionObjects::fieldValues::surfaceFieldValue::obr()
const
124 if (stObject == regionType_)
126 return storedObjects().lookupObject<polySurface>(regionName_);
133void 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_)
215 case error::handlerTypes::IGNORE:
220 case error::handlerTypes::WARN:
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;
275void 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_)
371 case error::handlerTypes::IGNORE:
376 case error::handlerTypes::WARN:
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;
431void 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)),
456 if (Pstream::parRun())
461 autoPtr<globalIndex> globalPoints;
462 autoPtr<globalIndex> globalFaces;
471 uniqueMeshPointLabels,
481 faces =
pp.localFaces();
487void Foam::functionObjects::fieldValues::surfaceFieldValue::
488combineSurfaceGeometry
494 if (stObject == regionType_)
496 const auto&
s = refCast<const polySurface>(obr());
498 if (Pstream::parRun())
501 const scalar mergeDim = 1
e-10*boundBox(
s.points(),
true).mag();
517 else if (sampledPtr_)
519 const sampledSurface&
s = *sampledPtr_;
521 if (Pstream::parRun())
524 const scalar mergeDim = 1
e-10*mesh_.bounds().mag();
544Foam::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()));
569bool Foam::functionObjects::fieldValues::surfaceFieldValue::usesSf()
589bool Foam::functionObjects::fieldValues::surfaceFieldValue::update()
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_)
655 case error::handlerTypes::IGNORE:
660 case error::handlerTypes::WARN:
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());
712void Foam::functionObjects::fieldValues::surfaceFieldValue::writeFileHeader
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())
732 flatOutput(weightFieldNames_, FlatOutput::BareComma{})
736 writeCommented(
os,
"Time");
744 for (
const word& fieldName : fields_)
746 os <<
tab << operationTypeNames_[operation_]
747 <<
'(' << fieldName <<
')';
753 writtenHeader_ =
true;
759Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
761 const Field<scalar>& values,
762 const vectorField& Sf,
763 const scalarField& weightField
773 case opSumDirectionBalance:
782 case opWeightedUniformity:
783 case opAbsWeightedUniformity:
785 const scalar areaTotal =
gSum(
mag(Sf));
786 tmp<scalarField> areaVal(values *
mag(Sf));
790 if (is_weightedOp() && canWeight(weightField))
794 tmp<scalarField> weight
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);
819 return clamp(ui, zero_one{});
825 return processSameTypeValues(values, Sf, weightField);
833Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
835 const Field<vector>& values,
836 const vectorField& Sf,
837 const scalarField& weightField
849 case opSumDirectionBalance:
856 case opAreaNormalAverage:
858 const scalar val =
gSum(values & Sf)/
gSum(
mag(Sf));
861 case opAreaNormalIntegrate:
863 const scalar val =
gSum(values & Sf);
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);
921Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
923 const Field<scalar>& weightField,
929 return mag(weightField);
939Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
941 const Field<scalar>& weightField,
942 const vectorField& Sf,
957 return mag(weightField);
967Foam::functionObjects::fieldValues::surfaceFieldValue::areaWeightingFactor
969 const Field<scalar>& weightField,
970 const vectorField& Sf,
985 return mag(weightField *
mag(Sf));
988 return (weightField *
mag(Sf));
994Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
996 const Field<vector>& weightField,
997 const vectorField& Sf,
1010 const label len = weightField.size();
1012 auto tresult = tmp<scalarField>::New(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)
1035Foam::functionObjects::fieldValues::surfaceFieldValue::areaWeightingFactor
1037 const Field<vector>& weightField,
1038 const vectorField& Sf,
1053 return mag(weightField & Sf);
1056 return (weightField & Sf);
1062Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
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_(),
1098Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
1101 const objectRegistry& obr,
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_(),
1137Foam::functionObjects::fieldValues::surfaceFieldValue::~surfaceFieldValue()
1143bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
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();
1334bool Foam::functionObjects::fieldValues::surfaceFieldValue::write()
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_)
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)
1505void Foam::functionObjects::fieldValues::surfaceFieldValue::updateMesh
1507 const mapPolyMesh& mpm
1510 needsUpdate_ =
true;
1514void Foam::functionObjects::fieldValues::surfaceFieldValue::movePoints
1516 const polyMesh&
mesh
1519 needsUpdate_ =
true;
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
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.
@ READ_IF_PRESENT
Reading is optional [identical to LAZY_READ].
@ MUST_READ
Reading required.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
@ WARN
Warn on errors/problems.
@ DEFAULT
Default behaviour (local meaning).
static const Enum< handlerTypes > handlerNames
Names of the error handler types.
Abstract base-class for Time/database function objects.
Intermediate class for handling field value-based function objects.
virtual bool read(const dictionary &dict)
Read the function-object dictionary.
virtual bool write()
Write the function-object results.
Registry of regIOobjects.
static autoPtr< sampledSurface > New(const word &name, const polyMesh &mesh, const dictionary &dict)
Return a reference to the selected surface.
static autoPtr< surfaceWriter > New(const word &writeType)
Select construct a surfaceWriter.
static dictionary formatOptions(const dictionary &dict, const word &formatName, const word &entryName="formatOptions")
Same as fileFormats::getFormatOptions.
A class for managing temporary objects.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
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))
return returnReduce(nRefine-oldNRefine, sumOp< label >())
#define WarningInFunction
Report a warning using Foam::Warning.
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
Function objects are OpenFOAM utilities to ease workflow configurations and enhance workflows.
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
Type gSum(const FieldField< Field, Type > &f)
bool read(const char *buf, int32_t &val)
Same as readInt32.
dimensionedScalar pos0(const dimensionedScalar &ds)
List< label > labelList
A List of labels.
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
messageStream Info
Information stream (stdout output on master, null elsewhere).
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
dimensionSet clamp(const dimensionSet &a, const dimensionSet &range)
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.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
A PrimitivePatch with an IndirectList for the faces, const reference for the point field.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
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)
Field< vector > vectorField
Specialisation of Field<T> for vector.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
dimensionedScalar neg(const dimensionedScalar &ds)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
vectorField pointField
pointField is a vectorField.
errorManipArg< error, int > exit(error &err, const int errNo=1)
constexpr char nl
The newline '\n' character (0x0a).
constexpr char tab
The tab '\t' character(0x09).
#define forAll(list, i)
Loop across all elements in list.
static constexpr const unsigned maxWarnings