43 namespace functionObjects
61 { regionTypes::stFaceZone,
"faceZone" },
62 { regionTypes::stPatch,
"patch" },
63 { regionTypes::stObject,
"functionObjectSurface" },
64 { regionTypes::stSampled,
"sampledSurface" },
75 { operationType::opNone,
"none" },
76 { operationType::opMin,
"min" },
77 { operationType::opMax,
"max" },
78 { operationType::opSum,
"sum" },
79 { operationType::opSumMag,
"sumMag" },
80 { operationType::opSumDirection,
"sumDirection" },
81 { operationType::opSumDirectionBalance,
"sumDirectionBalance" },
82 { operationType::opAverage,
"average" },
83 { operationType::opAreaAverage,
"areaAverage" },
84 { operationType::opAreaIntegrate,
"areaIntegrate" },
85 { operationType::opCoV,
"CoV" },
86 { operationType::opAreaNormalAverage,
"areaNormalAverage" },
87 { operationType::opAreaNormalIntegrate,
"areaNormalIntegrate" },
88 { operationType::opUniformity,
"uniformity" },
91 { operationType::opWeightedSum,
"weightedSum" },
92 { operationType::opWeightedAverage,
"weightedAverage" },
93 { operationType::opWeightedAreaAverage,
"weightedAreaAverage" },
94 { operationType::opWeightedAreaIntegrate,
"weightedAreaIntegrate" },
95 { operationType::opWeightedUniformity,
"weightedUniformity" },
98 { operationType::opAbsWeightedSum,
"absWeightedSum" },
99 { operationType::opAbsWeightedAverage,
"absWeightedAverage" },
100 { operationType::opAbsWeightedAreaAverage,
"absWeightedAreaAverage" },
101 { operationType::opAbsWeightedAreaIntegrate,
"absWeightedAreaIntegrate" },
102 { operationType::opAbsWeightedUniformity,
"absWeightedUniformity" },
111 { postOperationType::postOpNone,
"none" },
112 { postOperationType::postOpMag,
"mag" },
113 { postOperationType::postOpSqrt,
"sqrt" },
131 void Foam::functionObjects::fieldValues::surfaceFieldValue::setFaceZoneFaces()
133 const label zoneId = mesh_.faceZones().findZoneID(regionName_);
139 << regionTypeNames_[regionType_] <<
'(' << regionName_ <<
"):" <<
nl
140 <<
" Unknown face zone name: " << regionName_
141 <<
". Valid face zones are: " << mesh_.faceZones().names()
145 const faceZone& fZone = mesh_.faceZones()[zoneId];
153 const label facei = fZone[i];
156 label facePatchId = -1;
157 if (mesh_.isInternalFace(facei))
164 facePatchId = mesh_.boundaryMesh().whichPatch(facei);
166 if (isA<coupledPolyPatch>(pp))
168 if (refCast<const coupledPolyPatch>(pp).owner())
177 else if (!isA<emptyPolyPatch>(pp))
191 facePatchIds.append(facePatchId);
192 faceFlip.append(fZone.
flipMap()[i] ? true :
false);
196 faceId_.transfer(faceIds);
197 facePatchId_.transfer(facePatchIds);
198 faceFlip_.transfer(faceFlip);
203 Pout<<
"Original face zone size = " << fZone.size()
204 <<
", new size = " << faceId_.size() <<
endl;
209 void Foam::functionObjects::fieldValues::surfaceFieldValue::setPatchFaces()
211 const label patchid = mesh_.boundaryMesh().findPatchID(regionName_);
217 << regionTypeNames_[regionType_] <<
'(' << regionName_ <<
"):" <<
nl
218 <<
" Unknown patch name: " << regionName_
219 <<
". Valid patch names are: "
220 << mesh_.boundaryMesh().names() <<
nl
226 label nFaces = pp.size();
227 if (isA<emptyPolyPatch>(pp))
233 facePatchId_.setSize(nFaces);
234 faceFlip_.setSize(nFaces);
239 faceId_[facei] = facei;
240 facePatchId_[facei] = patchid;
241 faceFlip_[facei] =
false;
246 void Foam::functionObjects::fieldValues::surfaceFieldValue::combineMeshGeometry
258 if (facePatchId_[i] != -1)
260 const label patchi = facePatchId_[i];
261 globalFacesIs[i] += mesh_.boundaryMesh()[patchi].start();
268 IndirectList<face>(mesh_.faces(), globalFacesIs),
282 nFaces += allFaces[proci].size();
286 faces.setSize(nFaces);
295 for (
const face&
f : fcs)
297 face& newF = faces[nFaces++];
306 for (
const point& pt : pts)
317 const faceList& fcs = allFaces[proci];
318 for (
const face&
f : fcs)
320 face& newF = faces[nFaces++];
329 for (
const point& pt : pts)
353 <<
" down to " << newPoints.size() <<
" points" <<
endl;
356 points.transfer(newPoints);
357 for (face&
f : faces)
365 void Foam::functionObjects::fieldValues::surfaceFieldValue::
366 combineSurfaceGeometry
372 if (stObject == regionType_)
374 const polySurface&
s = dynamicCast<const polySurface>(obr());
379 const scalar mergeDim = 1
e-10*boundBox(
s.points(),
true).
mag();
388 SubList<face>(
s.faces(),
s.faces().size()),
402 else if (sampledPtr_.valid())
404 const sampledSurface&
s = sampledPtr_();
409 const scalar mergeDim = 1
e-10*mesh_.bounds().mag();
418 SubList<face>(
s.faces(),
s.faces().size()),
436 Foam::functionObjects::fieldValues::surfaceFieldValue::totalArea()
const
438 scalar totalArea = 0;
440 if (stObject == regionType_)
442 const polySurface&
s = dynamicCast<const polySurface>(obr());
444 totalArea =
gSum(
s.magSf());
446 else if (sampledPtr_.valid())
448 totalArea =
gSum(sampledPtr_().magSf());
452 totalArea =
gSum(filterField(mesh_.magSf()));
485 if (sampledPtr_.valid())
487 sampledPtr_->update();
509 const polySurface&
s = dynamicCast<const polySurface>(obr());
526 << regionTypeNames_[regionType_] <<
'(' << regionName_ <<
"):" <<
nl
530 totalArea_ = totalArea();
532 Log <<
" total faces = " << nFaces_ <<
nl
533 <<
" total area = " << totalArea_ <<
nl
536 writeFileHeader(file());
538 needsUpdate_ =
false;
548 if (canWriteHeader() && (operation_ != opNone))
550 writeCommented(os,
"Region type : ");
551 os << regionTypeNames_[regionType_] <<
" " << regionName_ <<
endl;
553 writeHeaderValue(os,
"Faces", nFaces_);
554 writeHeaderValue(os,
"Area", totalArea_);
555 writeHeaderValue(os,
"Scale factor", scaleFactor_);
557 if (weightFieldName_ !=
"none")
559 writeHeaderValue(os,
"Weight field", weightFieldName_);
562 writeCommented(os,
"Time");
570 for (
const word& fieldName : fields_)
572 os <<
tab << operationTypeNames_[operation_]
573 <<
"(" << fieldName <<
")";
579 writtenHeader_ =
true;
599 case opSumDirectionBalance:
608 case opWeightedUniformity:
609 case opAbsWeightedUniformity:
611 const scalar areaTotal =
gSum(
mag(Sf));
616 if (canWeight(weightField))
623 mean =
gSum(weight()*areaVal()) / areaTotal;
626 numer =
gSum(
mag(weight*areaVal - (mean *
mag(Sf))));
633 mean =
gSum(areaVal()) / areaTotal;
636 numer =
gSum(
mag(areaVal - (mean *
mag(Sf))));
640 const scalar ui = 1 - numer/(2*
mag(mean*areaTotal) + ROOTVSMALL);
642 return min(
max(ui, 0), 1);
648 return processSameTypeValues(
values, Sf, weightField);
672 case opSumDirectionBalance:
679 case opAreaNormalAverage:
684 case opAreaNormalIntegrate:
691 case opWeightedUniformity:
692 case opAbsWeightedUniformity:
694 const scalar areaTotal =
gSum(
mag(Sf));
699 if (canWeight(weightField))
706 mean =
gSum(weight()*areaVal()) / areaTotal;
709 numer =
gSum(
mag(weight*areaVal - (mean *
mag(Sf))));
716 mean =
gSum(areaVal()) / areaTotal;
719 numer =
gSum(
mag(areaVal - (mean *
mag(Sf))));
723 const scalar ui = 1 - numer/(2*
mag(mean*areaTotal) + ROOTVSMALL);
731 return processSameTypeValues(
values, Sf, weightField);
746 return mag(weightField);
771 return mag(weightField *
mag(Sf));
774 return (weightField *
mag(Sf));
795 return mag(weightField & Sf);
798 return (weightField & Sf);
812 regionType_(regionTypeNames_.get(
"regionType",
dict)),
813 operation_(operationTypeNames_.get(
"operation",
dict)),
816 postOperationTypeNames_.getOrDefault
820 postOperationType::postOpNone,
824 weightFieldName_(
"none"),
845 regionType_(regionTypeNames_.get(
"regionType",
dict)),
846 operation_(operationTypeNames_.get(
"operation",
dict)),
849 postOperationTypeNames_.getOrDefault
853 postOperationType::postOpNone,
857 weightFieldName_(
"none"),
879 weightFieldName_ =
"none";
881 writeArea_ =
dict.getOrDefault(
"writeArea",
false);
885 facePatchId_.clear();
888 surfaceWriterPtr_.clear();
890 dict.readEntry(
"name", regionName_);
894 if (stSampled == regionType_)
900 dict.subDict(
"sampledSurfaceDict")
907 if (postOperation_ != postOpNone)
909 Info<< postOperationTypeNames_[postOperation_] <<
'('
910 << operationTypeNames_[operation_] <<
')' <<
nl;
914 Info<< operationTypeNames_[operation_] <<
nl;
919 if (stSampled == regionType_)
922 <<
"Cannot use weighted operation '"
923 << operationTypeNames_[operation_]
924 <<
"' for sampledSurface"
928 if (
dict.readIfPresent(
"weightField", weightFieldName_))
930 Info<<
" weight field = " << weightFieldName_ <<
nl;
936 <<
"The '" << operationTypeNames_[operation_]
937 <<
"' operation is missing a weightField." <<
nl
938 <<
"Either provide the weightField, "
939 <<
"use weightField 'none' to suppress weighting," <<
nl
940 <<
"or use a different operation."
947 if (
dict.readIfPresent(
"orientedFields", orientedFields))
949 fields_.
append(orientedFields);
952 <<
"The 'orientedFields' option is deprecated. These fields can "
953 <<
"and have been added to the standard 'fields' list."
961 surfaceWriterPtr_.reset
966 dict.subOrEmptyDict(
"formatOptions").subOrEmptyDict(formatName)
972 surfaceWriterPtr_->verbose() =
true;
975 if (surfaceWriterPtr_->enabled())
977 Info<<
" surfaceFormat = " << formatName <<
nl;
981 surfaceWriterPtr_->clear();
993 if (needsUpdate_ || operation_ != opNone)
1000 if (operation_ != opNone)
1002 writeCurrentTime(file());
1007 totalArea_ = totalArea();
1008 Log <<
" total area = " << totalArea_ <<
endl;
1012 file() <<
tab << totalArea_;
1020 if (stObject == regionType_)
1022 const polySurface&
s = dynamicCast<const polySurface>(obr());
1025 else if (sampledPtr_.valid())
1027 Sf = sampledPtr_().Sf();
1031 Sf = filterField(mesh_.Sf());
1039 if (surfaceWriterPtr_.valid())
1041 if (withTopologicalMerge())
1043 combineMeshGeometry(faces,
points);
1047 combineSurfaceGeometry(faces,
points);
1052 if (weightFieldName_ !=
"none")
1054 if (validField<scalar>(weightFieldName_))
1058 getFieldValues<scalar>(weightFieldName_,
true)
1062 writeAll(Sf, weightField,
points, faces);
1064 else if (validField<vector>(weightFieldName_))
1068 getFieldValues<vector>(weightFieldName_,
true)
1072 writeAll(Sf, weightField,
points, faces);
1077 <<
"weightField " << weightFieldName_
1078 <<
" not found or an unsupported type"
1088 writeAll(Sf, weightField,
points, faces);
1091 if (operation_ != opNone)
1107 needsUpdate_ =
true;
1116 needsUpdate_ =
true;