/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see .
\*---------------------------------------------------------------------------*/
#include "surfaceFieldValue.H"
#include "fvMesh.H"
#include "emptyPolyPatch.H"
#include "coupledPolyPatch.H"
#include "sampledSurface.H"
#include "mergePoints.H"
#include "uindirectPrimitivePatch.H"
#include "PatchTools.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
namespace fieldValues
{
defineTypeNameAndDebug(surfaceFieldValue, 0);
addToRunTimeSelectionTable(fieldValue, surfaceFieldValue, dictionary);
addToRunTimeSelectionTable(functionObject, surfaceFieldValue, dictionary);
}
}
}
const Foam::Enum
<
Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypes
>
Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypeNames_
({
{ regionTypes::stFaceZone, "faceZone" },
{ regionTypes::stPatch, "patch" },
{ regionTypes::stObject, "functionObjectSurface" },
{ regionTypes::stSampled, "sampledSurface" },
});
const Foam::Enum
<
Foam::functionObjects::fieldValues::surfaceFieldValue::operationType
>
Foam::functionObjects::fieldValues::surfaceFieldValue::operationTypeNames_
({
// Normal operations
{ operationType::opNone, "none" },
{ operationType::opMin, "min" },
{ operationType::opMax, "max" },
{ operationType::opSum, "sum" },
{ operationType::opSumMag, "sumMag" },
{ operationType::opSumDirection, "sumDirection" },
{ operationType::opSumDirectionBalance, "sumDirectionBalance" },
{ operationType::opAverage, "average" },
{ operationType::opAreaAverage, "areaAverage" },
{ operationType::opAreaIntegrate, "areaIntegrate" },
{ operationType::opCoV, "CoV" },
{ operationType::opAreaNormalAverage, "areaNormalAverage" },
{ operationType::opAreaNormalIntegrate, "areaNormalIntegrate" },
{ operationType::opUniformity, "uniformity" },
// Using weighting
{ operationType::opWeightedSum, "weightedSum" },
{ operationType::opWeightedAverage, "weightedAverage" },
{ operationType::opWeightedAreaAverage, "weightedAreaAverage" },
{ operationType::opWeightedAreaIntegrate, "weightedAreaIntegrate" },
{ operationType::opWeightedUniformity, "weightedUniformity" },
// Using absolute weighting
{ operationType::opAbsWeightedSum, "absWeightedSum" },
{ operationType::opAbsWeightedAverage, "absWeightedAverage" },
{ operationType::opAbsWeightedAreaAverage, "absWeightedAreaAverage" },
{ operationType::opAbsWeightedAreaIntegrate, "absWeightedAreaIntegrate" },
{ operationType::opAbsWeightedUniformity, "absWeightedUniformity" },
});
const Foam::Enum
<
Foam::functionObjects::fieldValues::surfaceFieldValue::postOperationType
>
Foam::functionObjects::fieldValues::surfaceFieldValue::postOperationTypeNames_
({
{ postOperationType::postOpNone, "none" },
{ postOperationType::postOpMag, "mag" },
{ postOperationType::postOpSqrt, "sqrt" },
});
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
const Foam::objectRegistry&
Foam::functionObjects::fieldValues::surfaceFieldValue::obr() const
{
if (stObject == regionType_)
{
return storedObjects().lookupObject(regionName_);
}
return mesh_;
}
void Foam::functionObjects::fieldValues::surfaceFieldValue::setFaceZoneFaces()
{
// Indices for all matches, already sorted
const labelList zoneIds
(
mesh_.faceZones().indices(selectionNames_)
);
// Total number of faces selected
label numFaces = 0;
for (const label zoneId : zoneIds)
{
numFaces += mesh_.faceZones()[zoneId].size();
}
if (zoneIds.empty())
{
FatalErrorInFunction
<< type() << ' ' << name() << ": "
<< regionTypeNames_[regionType_] << '(' << regionName_ << "):" << nl
<< " No matching face zone(s): "
<< flatOutput(selectionNames_) << nl
<< " Known face zones: "
<< flatOutput(mesh_.faceZones().names()) << nl
<< exit(FatalError);
}
// Could also check this
#if 0
if (!returnReduce(bool(numFaces), orOp()))
{
WarningInFunction
<< type() << ' ' << name() << ": "
<< regionTypeNames_[regionType_] << '(' << regionName_ << "):" << nl
<< " The faceZone specification: "
<< flatOutput(selectionNames_) << nl
<< " resulted in 0 faces" << nl
<< exit(FatalError);
}
#endif
faceId_.resize(numFaces);
facePatchId_.resize(numFaces);
faceFlip_.resize(numFaces);
numFaces = 0;
for (const label zoneId : zoneIds)
{
const faceZone& fZone = mesh_.faceZones()[zoneId];
forAll(fZone, i)
{
const label meshFacei = fZone[i];
const bool isFlip = fZone.flipMap()[i];
// Internal faces
label faceId = meshFacei;
label facePatchId = -1;
// Boundary faces
if (!mesh_.isInternalFace(meshFacei))
{
facePatchId = mesh_.boundaryMesh().whichPatch(meshFacei);
const polyPatch& pp = mesh_.boundaryMesh()[facePatchId];
if (isA(pp))
{
if (refCast(pp).owner())
{
faceId = pp.whichFace(meshFacei);
}
else
{
faceId = -1;
}
}
else if (!isA(pp))
{
faceId = meshFacei - pp.start();
}
else
{
faceId = -1;
facePatchId = -1;
}
}
if (faceId >= 0)
{
faceId_[numFaces] = faceId;
facePatchId_[numFaces] = facePatchId;
faceFlip_[numFaces] = isFlip;
++numFaces;
}
}
}
// Shrink to size used
faceId_.resize(numFaces);
facePatchId_.resize(numFaces);
faceFlip_.resize(numFaces);
nFaces_ = returnReduce(faceId_.size(), sumOp