mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: support operations on surfFields in surfaceFieldValue
- this makes it possible to perform additional operations on surface values that have been previously sampled. - support vectorField for weighting operations. - reduce overhead by avoiding creation of weight fields, Sf fields and combined surface geometries unless they are actually required. - extend some similar concepts and operations to volFieldValue
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -31,6 +31,7 @@ License
|
||||
#include "mergePoints.H"
|
||||
#include "indirectPrimitivePatch.H"
|
||||
#include "PatchTools.H"
|
||||
#include "meshedSurfRef.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
@ -52,11 +53,12 @@ template<>
|
||||
const char* Foam::NamedEnum
|
||||
<
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypes,
|
||||
3
|
||||
4
|
||||
>::names[] =
|
||||
{
|
||||
"faceZone",
|
||||
"patch",
|
||||
"surface",
|
||||
"sampledSurface"
|
||||
};
|
||||
|
||||
@ -64,12 +66,13 @@ template<>
|
||||
const char* Foam::NamedEnum
|
||||
<
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::operationType,
|
||||
16
|
||||
17
|
||||
>::names[] =
|
||||
{
|
||||
"none",
|
||||
"sum",
|
||||
"sumMag",
|
||||
"weightedSum",
|
||||
"sumDirection",
|
||||
"sumDirectionBalance",
|
||||
"average",
|
||||
@ -100,13 +103,13 @@ const char* Foam::NamedEnum
|
||||
const Foam::NamedEnum
|
||||
<
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypes,
|
||||
3
|
||||
4
|
||||
> Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypeNames_;
|
||||
|
||||
const Foam::NamedEnum
|
||||
<
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::operationType,
|
||||
16
|
||||
17
|
||||
> Foam::functionObjects::fieldValues::surfaceFieldValue::operationTypeNames_;
|
||||
|
||||
const Foam::NamedEnum
|
||||
@ -119,9 +122,23 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::postOperationTypeNames_;
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
const Foam::objectRegistry&
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::obr() const
|
||||
{
|
||||
if (regionType_ == stSurface)
|
||||
{
|
||||
return mesh_.lookupObject<objectRegistry>(regionName_);
|
||||
}
|
||||
else
|
||||
{
|
||||
return mesh_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::functionObjects::fieldValues::surfaceFieldValue::setFaceZoneFaces()
|
||||
{
|
||||
label zoneId = mesh_.faceZones().findZoneID(regionName_);
|
||||
const label zoneId = mesh_.faceZones().findZoneID(regionName_);
|
||||
|
||||
if (zoneId < 0)
|
||||
{
|
||||
@ -137,11 +154,11 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::setFaceZoneFaces()
|
||||
|
||||
DynamicList<label> faceIds(fZone.size());
|
||||
DynamicList<label> facePatchIds(fZone.size());
|
||||
DynamicList<label> faceSigns(fZone.size());
|
||||
DynamicList<bool> faceFlip(fZone.size());
|
||||
|
||||
forAll(fZone, i)
|
||||
{
|
||||
label facei = fZone[i];
|
||||
const label facei = fZone[i];
|
||||
|
||||
label faceId = -1;
|
||||
label facePatchId = -1;
|
||||
@ -178,22 +195,15 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::setFaceZoneFaces()
|
||||
|
||||
if (faceId >= 0)
|
||||
{
|
||||
if (fZone.flipMap()[i])
|
||||
{
|
||||
faceSigns.append(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
faceSigns.append(1);
|
||||
}
|
||||
faceIds.append(faceId);
|
||||
facePatchIds.append(facePatchId);
|
||||
faceFlip.append(fZone.flipMap()[i] ? true : false);
|
||||
}
|
||||
}
|
||||
|
||||
faceId_.transfer(faceIds);
|
||||
facePatchId_.transfer(facePatchIds);
|
||||
faceSign_.transfer(faceSigns);
|
||||
faceFlip_.transfer(faceFlip);
|
||||
nFaces_ = returnReduce(faceId_.size(), sumOp<label>());
|
||||
|
||||
if (debug)
|
||||
@ -229,34 +239,18 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::setPatchFaces()
|
||||
|
||||
faceId_.setSize(nFaces);
|
||||
facePatchId_.setSize(nFaces);
|
||||
faceSign_.setSize(nFaces);
|
||||
faceFlip_.setSize(nFaces);
|
||||
nFaces_ = returnReduce(faceId_.size(), sumOp<label>());
|
||||
|
||||
forAll(faceId_, facei)
|
||||
{
|
||||
faceId_[facei] = facei;
|
||||
facePatchId_[facei] = patchid;
|
||||
faceSign_[facei] = 1;
|
||||
faceFlip_[facei] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::functionObjects::fieldValues::surfaceFieldValue::sampledSurfaceFaces
|
||||
(
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
surfacePtr_ = sampledSurface::New
|
||||
(
|
||||
name(),
|
||||
mesh_,
|
||||
dict.subDict("sampledSurfaceDict")
|
||||
);
|
||||
surfacePtr_().update();
|
||||
nFaces_ = returnReduce(surfacePtr_().faces().size(), sumOp<label>());
|
||||
}
|
||||
|
||||
|
||||
void Foam::functionObjects::fieldValues::surfaceFieldValue::combineMeshGeometry
|
||||
(
|
||||
faceList& faces,
|
||||
@ -385,14 +379,44 @@ combineSurfaceGeometry
|
||||
pointField& points
|
||||
) const
|
||||
{
|
||||
if (surfacePtr_.valid())
|
||||
if (regionType_ == stSurface)
|
||||
{
|
||||
const surfMesh& s = dynamicCast<const surfMesh>(obr());
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
// Dimension as fraction of surface
|
||||
const scalar mergeDim = 1e-10*boundBox(s.points(), true).mag();
|
||||
|
||||
labelList pointsMap;
|
||||
|
||||
PatchTools::gatherAndMerge
|
||||
(
|
||||
mergeDim,
|
||||
primitivePatch
|
||||
(
|
||||
SubList<face>(s.faces(), s.faces().size()),
|
||||
s.points()
|
||||
),
|
||||
points,
|
||||
faces,
|
||||
pointsMap
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
faces = s.faces();
|
||||
points = s.points();
|
||||
}
|
||||
}
|
||||
else if (surfacePtr_.valid())
|
||||
{
|
||||
const sampledSurface& s = surfacePtr_();
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
// Dimension as fraction of mesh bounding box
|
||||
scalar mergeDim = 1e-10*mesh_.bounds().mag();
|
||||
const scalar mergeDim = 1e-10*mesh_.bounds().mag();
|
||||
|
||||
labelList pointsMap;
|
||||
|
||||
@ -423,7 +447,13 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::totalArea() const
|
||||
{
|
||||
scalar totalArea;
|
||||
|
||||
if (surfacePtr_.valid())
|
||||
if (regionType_ == stSurface)
|
||||
{
|
||||
const surfMesh& s = dynamicCast<const surfMesh>(obr());
|
||||
|
||||
totalArea = gSum(s.magSf());
|
||||
}
|
||||
else if (surfacePtr_.valid())
|
||||
{
|
||||
totalArea = gSum(surfacePtr_().magSf());
|
||||
}
|
||||
@ -438,6 +468,42 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::totalArea() const
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
bool Foam::functionObjects::fieldValues::surfaceFieldValue::needsSf() const
|
||||
{
|
||||
// Many operations use the Sf field
|
||||
switch (operation_)
|
||||
{
|
||||
case opNone:
|
||||
case opSum:
|
||||
case opSumMag:
|
||||
case opAverage:
|
||||
case opMin:
|
||||
case opMax:
|
||||
return false;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Foam::functionObjects::fieldValues::surfaceFieldValue::needsWeight() const
|
||||
{
|
||||
// Only a few operations use weight field
|
||||
switch (operation_)
|
||||
{
|
||||
case opWeightedSum:
|
||||
case opWeightedAverage:
|
||||
case opWeightedAreaAverage:
|
||||
case opWeightedAreaIntegrate:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::functionObjects::fieldValues::surfaceFieldValue::initialise
|
||||
(
|
||||
const dictionary& dict
|
||||
@ -450,16 +516,42 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::initialise
|
||||
case stFaceZone:
|
||||
{
|
||||
setFaceZoneFaces();
|
||||
surfacePtr_.clear();
|
||||
break;
|
||||
}
|
||||
case stPatch:
|
||||
{
|
||||
setPatchFaces();
|
||||
surfacePtr_.clear();
|
||||
break;
|
||||
}
|
||||
case stSurface:
|
||||
{
|
||||
const surfMesh& s = dynamicCast<const surfMesh>(obr());
|
||||
nFaces_ = returnReduce(s.size(), sumOp<label>());
|
||||
|
||||
faceId_.clear();
|
||||
facePatchId_.clear();
|
||||
faceFlip_.clear();
|
||||
surfacePtr_.clear();
|
||||
break;
|
||||
}
|
||||
case stSampledSurface:
|
||||
{
|
||||
sampledSurfaceFaces(dict);
|
||||
faceId_.clear();
|
||||
facePatchId_.clear();
|
||||
faceFlip_.clear();
|
||||
|
||||
surfacePtr_ = sampledSurface::New
|
||||
(
|
||||
name(),
|
||||
mesh_,
|
||||
dict.subDict("sampledSurfaceDict")
|
||||
);
|
||||
surfacePtr_().update();
|
||||
nFaces_ =
|
||||
returnReduce(surfacePtr_().faces().size(), sumOp<label>());
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -488,61 +580,93 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::initialise
|
||||
totalArea_ = totalArea();
|
||||
|
||||
Info<< type() << " " << name() << ":" << nl
|
||||
<< " total faces = " << nFaces_ << nl
|
||||
<< " total area = " << totalArea_ << nl;
|
||||
<< " operation = ";
|
||||
|
||||
if (dict.readIfPresent("weightField", weightFieldName_))
|
||||
if (postOperation_ != postOpNone)
|
||||
{
|
||||
Info<< " weight field = " << weightFieldName_ << nl;
|
||||
|
||||
if (regionType_ == stSampledSurface)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Cannot use weightField for a sampledSurface"
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
Info<< postOperationTypeNames_[postOperation_] << '('
|
||||
<< operationTypeNames_[operation_] << ')' << nl;
|
||||
}
|
||||
|
||||
if (dict.found("orientedWeightField"))
|
||||
else
|
||||
{
|
||||
if (weightFieldName_ == "none")
|
||||
Info<< operationTypeNames_[operation_] << nl;
|
||||
}
|
||||
Info<< " total faces = " << nFaces_ << nl
|
||||
<< " total area = " << totalArea_ << nl;
|
||||
|
||||
|
||||
weightFieldName_ = "none";
|
||||
orientWeightField_ = false;
|
||||
if (needsWeight())
|
||||
{
|
||||
if (dict.readIfPresent("weightField", weightFieldName_))
|
||||
{
|
||||
dict.lookup("orientedWeightField") >> weightFieldName_;
|
||||
Info<< " weight field = " << weightFieldName_ << nl;
|
||||
orientWeightField_ = true;
|
||||
if (regionType_ == stSampledSurface)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Cannot use weightField for sampledSurface"
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
Info<< " weight field = " << weightFieldName_ << nl;
|
||||
}
|
||||
else
|
||||
|
||||
if (dict.found("orientedWeightField"))
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Either weightField or orientedWeightField can be supplied, "
|
||||
<< "but not both"
|
||||
<< exit(FatalIOError);
|
||||
if (regionType_ == stSurface || regionType_ == stSampledSurface)
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Cannot use orientedWeightField "
|
||||
<< "for surface/sampledSurface"
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
if (weightFieldName_ == "none")
|
||||
{
|
||||
dict.lookup("orientedWeightField") >> weightFieldName_;
|
||||
orientWeightField_ = true;
|
||||
|
||||
Info<< " weight field = " << weightFieldName_ << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Cannot specify both weightField and orientedWeightField"
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<word> orientedFields;
|
||||
orientedFieldsStart_ = labelMax;
|
||||
if (dict.readIfPresent("orientedFields", orientedFields))
|
||||
{
|
||||
orientedFieldsStart_ = fields_.size();
|
||||
fields_.append(orientedFields);
|
||||
}
|
||||
|
||||
Info<< nl << endl;
|
||||
|
||||
surfaceWriterPtr_.clear();
|
||||
if (writeFields_)
|
||||
{
|
||||
const word surfaceFormat(dict.lookup("surfaceFormat"));
|
||||
|
||||
surfaceWriterPtr_.reset
|
||||
(
|
||||
surfaceWriter::New
|
||||
if (surfaceFormat != "none")
|
||||
{
|
||||
surfaceWriterPtr_.reset
|
||||
(
|
||||
surfaceFormat,
|
||||
dict.subOrEmptyDict("formatOptions").
|
||||
subOrEmptyDict(surfaceFormat)
|
||||
).ptr()
|
||||
);
|
||||
surfaceWriter::New
|
||||
(
|
||||
surfaceFormat,
|
||||
dict.subOrEmptyDict("formatOptions").
|
||||
subOrEmptyDict(surfaceFormat)
|
||||
).ptr()
|
||||
);
|
||||
|
||||
Info<< " surfaceFormat = " << surfaceFormat << nl;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< nl << endl;
|
||||
}
|
||||
|
||||
|
||||
@ -583,8 +707,8 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::writeFileHeader
|
||||
|
||||
|
||||
template<>
|
||||
Foam::scalar Foam::functionObjects::fieldValues::surfaceFieldValue::
|
||||
processValues
|
||||
Foam::scalar
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
||||
(
|
||||
const Field<scalar>& values,
|
||||
const vectorField& Sf,
|
||||
@ -615,8 +739,8 @@ processValues
|
||||
|
||||
|
||||
template<>
|
||||
Foam::vector Foam::functionObjects::fieldValues::surfaceFieldValue::
|
||||
processValues
|
||||
Foam::vector
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
||||
(
|
||||
const Field<vector>& values,
|
||||
const vectorField& Sf,
|
||||
@ -629,27 +753,27 @@ processValues
|
||||
{
|
||||
vector n(dict_.lookup("direction"));
|
||||
n /= mag(n) + ROOTVSMALL;
|
||||
const scalarField nv(n & values);
|
||||
|
||||
const scalarField nv(n & values);
|
||||
return gSum(pos(nv)*n*(nv));
|
||||
}
|
||||
case opSumDirectionBalance:
|
||||
{
|
||||
vector n(dict_.lookup("direction"));
|
||||
n /= mag(n) + ROOTVSMALL;
|
||||
const scalarField nv(n & values);
|
||||
|
||||
const scalarField nv(n & values);
|
||||
return gSum(pos(nv)*n*(nv));
|
||||
}
|
||||
case opAreaNormalAverage:
|
||||
{
|
||||
scalar result = gSum(values & Sf)/gSum(mag(Sf));
|
||||
return vector(result, 0.0, 0.0);
|
||||
const scalar val = gSum(values & Sf)/gSum(mag(Sf));
|
||||
return vector(val, 0, 0);
|
||||
}
|
||||
case opAreaNormalIntegrate:
|
||||
{
|
||||
scalar result = gSum(values & Sf);
|
||||
return vector(result, 0.0, 0.0);
|
||||
const scalar val = gSum(values & Sf);
|
||||
return vector(val, 0, 0);
|
||||
}
|
||||
default:
|
||||
{
|
||||
@ -660,6 +784,58 @@ processValues
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
Foam::tmp<Foam::scalarField>
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
|
||||
(
|
||||
const Field<scalar>& weightField
|
||||
)
|
||||
{
|
||||
// pass through
|
||||
return weightField;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
Foam::tmp<Foam::scalarField>
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
|
||||
(
|
||||
const Field<scalar>& weightField,
|
||||
const vectorField& Sf
|
||||
)
|
||||
{
|
||||
// scalar * Area
|
||||
if (returnReduce(weightField.empty(), andOp<bool>()))
|
||||
{
|
||||
return mag(Sf);
|
||||
}
|
||||
else
|
||||
{
|
||||
return weightField * mag(Sf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
Foam::tmp<Foam::scalarField>
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
|
||||
(
|
||||
const Field<vector>& weightField,
|
||||
const vectorField& Sf
|
||||
)
|
||||
{
|
||||
// vector (dot) Area
|
||||
if (returnReduce(weightField.empty(), andOp<bool>()))
|
||||
{
|
||||
return mag(Sf);
|
||||
}
|
||||
else
|
||||
{
|
||||
return weightField & Sf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
|
||||
@ -670,7 +846,6 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
|
||||
)
|
||||
:
|
||||
fieldValue(name, runTime, dict, typeName),
|
||||
surfaceWriterPtr_(nullptr),
|
||||
regionType_(regionTypeNames_.read(dict.lookup("regionType"))),
|
||||
operation_(operationTypeNames_.read(dict.lookup("operation"))),
|
||||
postOperation_
|
||||
@ -685,7 +860,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
|
||||
nFaces_(0),
|
||||
faceId_(),
|
||||
facePatchId_(),
|
||||
faceSign_()
|
||||
faceFlip_()
|
||||
{
|
||||
read(dict);
|
||||
writeFileHeader(file());
|
||||
@ -700,7 +875,6 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
|
||||
)
|
||||
:
|
||||
fieldValue(name, obr, dict, typeName),
|
||||
surfaceWriterPtr_(nullptr),
|
||||
regionType_(regionTypeNames_.read(dict.lookup("regionType"))),
|
||||
operation_(operationTypeNames_.read(dict.lookup("operation"))),
|
||||
postOperation_
|
||||
@ -715,7 +889,7 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
|
||||
nFaces_(0),
|
||||
faceId_(),
|
||||
facePatchId_(),
|
||||
faceSign_()
|
||||
faceFlip_()
|
||||
{
|
||||
read(dict);
|
||||
writeFileHeader(file());
|
||||
@ -744,66 +918,111 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
|
||||
|
||||
bool Foam::functionObjects::fieldValues::surfaceFieldValue::write()
|
||||
{
|
||||
if (operation_ != opNone)
|
||||
{
|
||||
fieldValue::write();
|
||||
}
|
||||
|
||||
if (surfacePtr_.valid())
|
||||
{
|
||||
surfacePtr_().update();
|
||||
}
|
||||
|
||||
if (operation_ != opNone && Pstream::master())
|
||||
if (operation_ != opNone)
|
||||
{
|
||||
writeTime(file());
|
||||
fieldValue::write();
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
writeTime(file());
|
||||
}
|
||||
}
|
||||
|
||||
if (writeArea_)
|
||||
{
|
||||
totalArea_ = totalArea();
|
||||
Log << " total area = " << totalArea_ << endl;
|
||||
|
||||
if (operation_ != opNone && Pstream::master())
|
||||
{
|
||||
file() << tab << totalArea_;
|
||||
}
|
||||
Log << " total area = " << totalArea_ << endl;
|
||||
}
|
||||
|
||||
// Construct weight field. Note: zero size means weight = 1
|
||||
scalarField weightField;
|
||||
// Many operations use the Sf field
|
||||
vectorField Sf;
|
||||
if (needsSf())
|
||||
{
|
||||
if (regionType_ == stSurface)
|
||||
{
|
||||
const surfMesh& s = dynamicCast<const surfMesh>(obr());
|
||||
Sf = s.Sf();
|
||||
}
|
||||
else if (surfacePtr_.valid())
|
||||
{
|
||||
Sf = surfacePtr_().Sf();
|
||||
}
|
||||
else
|
||||
{
|
||||
Sf = filterField(mesh_.Sf(), true); // Oriented Sf
|
||||
}
|
||||
}
|
||||
|
||||
// Faces and points for surface format (if specified)
|
||||
faceList faces;
|
||||
pointField points;
|
||||
|
||||
if (surfaceWriterPtr_.valid())
|
||||
{
|
||||
if (regionType_ == stSurface || surfacePtr_.valid())
|
||||
{
|
||||
combineSurfaceGeometry(faces, points);
|
||||
}
|
||||
else
|
||||
{
|
||||
combineMeshGeometry(faces, points);
|
||||
}
|
||||
}
|
||||
|
||||
meshedSurfRef surfToWrite(points, faces);
|
||||
|
||||
// Only a few weight types (scalar, vector)
|
||||
if (weightFieldName_ != "none")
|
||||
{
|
||||
weightField =
|
||||
getFieldValues<scalar>
|
||||
if (validField<scalar>(weightFieldName_))
|
||||
{
|
||||
scalarField weightField = getFieldValues<scalar>
|
||||
(
|
||||
weightFieldName_,
|
||||
true,
|
||||
orientWeightField_
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Process the fields
|
||||
forAll(fields_, i)
|
||||
{
|
||||
const word& fieldName = fields_[i];
|
||||
bool ok = false;
|
||||
|
||||
bool orient = i >= orientedFieldsStart_;
|
||||
ok = ok || writeValues<scalar>(fieldName, weightField, orient);
|
||||
ok = ok || writeValues<vector>(fieldName, weightField, orient);
|
||||
ok = ok
|
||||
|| writeValues<sphericalTensor>(fieldName, weightField, orient);
|
||||
ok = ok || writeValues<symmTensor>(fieldName, weightField, orient);
|
||||
ok = ok || writeValues<tensor>(fieldName, weightField, orient);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Requested field " << fieldName
|
||||
<< " not found in database and not processed"
|
||||
<< endl;
|
||||
// Process the fields
|
||||
writeAll(Sf, weightField, surfToWrite);
|
||||
}
|
||||
else if (validField<vector>(weightFieldName_))
|
||||
{
|
||||
vectorField weightField = getFieldValues<vector>
|
||||
(
|
||||
weightFieldName_,
|
||||
true,
|
||||
orientWeightField_
|
||||
);
|
||||
|
||||
// Process the fields
|
||||
writeAll(Sf, weightField, surfToWrite);
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "weightField " << weightFieldName_
|
||||
<< " not found or an unsupported type"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default is a zero-size scalar weight field (ie, weight = 1)
|
||||
scalarField weightField;
|
||||
|
||||
// Process the fields
|
||||
writeAll(Sf, weightField, surfToWrite);
|
||||
}
|
||||
|
||||
if (operation_ != opNone && Pstream::master())
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2015-2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -98,6 +98,7 @@ Usage
|
||||
\plaintable
|
||||
faceZone | requires a 'name' entry to specify the faceZone
|
||||
patch | requires a 'name' entry to specify the patch
|
||||
surface | requires a 'name' entry to specify the surfMesh
|
||||
sampledSurface | requires a 'sampledSurfaceDict' sub-dictionary
|
||||
\endplaintable
|
||||
|
||||
@ -105,6 +106,7 @@ Usage
|
||||
\plaintable
|
||||
none | no operation
|
||||
sum | sum
|
||||
weightedSum | weighted sum
|
||||
sumMag | sum of component magnitudes
|
||||
sumDirection | sum values which are positive in given direction
|
||||
sumDirectionBalance | sum of balance of values in given direction
|
||||
@ -130,6 +132,9 @@ Note
|
||||
faces
|
||||
- the `oriented' entries relate to mesh-oriented fields, such as the
|
||||
flux, phi. These fields will be oriented according to the face normals.
|
||||
- Using \c surface:
|
||||
- The keyword %subRegion should not be used to select surfaces.
|
||||
Specify instead the regionType 'surface' and provide the surface name.
|
||||
- using \c sampledSurface:
|
||||
- not available for surface fields
|
||||
- if interpolate=true they use \c interpolationCellPoint
|
||||
@ -155,7 +160,7 @@ SourceFiles
|
||||
|
||||
#include "fieldValue.H"
|
||||
#include "NamedEnum.H"
|
||||
#include "faceList.H"
|
||||
#include "meshedSurf.H"
|
||||
#include "surfaceMesh.H"
|
||||
#include "fvsPatchField.H"
|
||||
#include "volFieldsFwd.H"
|
||||
@ -182,21 +187,21 @@ class surfaceFieldValue
|
||||
:
|
||||
public fieldValue
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
// Public data types
|
||||
|
||||
//- region type enumeration
|
||||
//- Region type enumeration
|
||||
enum regionTypes
|
||||
{
|
||||
stFaceZone,
|
||||
stPatch,
|
||||
stSurface,
|
||||
stSampledSurface
|
||||
};
|
||||
|
||||
//- region type names
|
||||
static const NamedEnum<regionTypes, 3> regionTypeNames_;
|
||||
//- Region type names
|
||||
static const NamedEnum<regionTypes, 4> regionTypeNames_;
|
||||
|
||||
|
||||
//- Operation type enumeration
|
||||
@ -204,6 +209,7 @@ public:
|
||||
{
|
||||
opNone, //!< None
|
||||
opSum, //!< Sum
|
||||
opWeightedSum, //!< Weighted sum
|
||||
opSumMag, //!< Magnitude of sum
|
||||
opSumDirection, //!< Sum in a given direction
|
||||
opSumDirectionBalance, //!< Sum in a given direction for multiple
|
||||
@ -221,7 +227,7 @@ public:
|
||||
};
|
||||
|
||||
//- Operation type names
|
||||
static const NamedEnum<operationType, 16> operationTypeNames_;
|
||||
static const NamedEnum<operationType, 17> operationTypeNames_;
|
||||
|
||||
|
||||
//- Post-operation type enumeration
|
||||
@ -245,9 +251,6 @@ private:
|
||||
//- Set faces to evaluate based on a patch
|
||||
void setPatchFaces();
|
||||
|
||||
//- Set faces according to sampledSurface
|
||||
void sampledSurfaceFaces(const dictionary&);
|
||||
|
||||
//- Combine mesh faces and points from multiple processors
|
||||
void combineMeshGeometry
|
||||
(
|
||||
@ -270,10 +273,7 @@ protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Surface writer
|
||||
autoPtr<surfaceWriter> surfaceWriterPtr_;
|
||||
|
||||
//- region type
|
||||
//- Region type
|
||||
regionTypes regionType_;
|
||||
|
||||
//- Operation to apply to values
|
||||
@ -309,23 +309,42 @@ protected:
|
||||
//- Local list of patch ID per face
|
||||
labelList facePatchId_;
|
||||
|
||||
//- List of +1/-1 representing face flip map
|
||||
// (1 use as is, -1 negate)
|
||||
labelList faceSign_;
|
||||
//- List representing the face flip map
|
||||
// (false: use as-is, true: negate)
|
||||
boolList faceFlip_;
|
||||
|
||||
|
||||
// If operating on sampledSurface
|
||||
//- Underlying sampledSurface (if operating on sampledSurface)
|
||||
autoPtr<sampledSurface> surfacePtr_;
|
||||
|
||||
//- Underlying sampledSurface
|
||||
autoPtr<sampledSurface> surfacePtr_;
|
||||
//- Surface writer
|
||||
autoPtr<surfaceWriter> surfaceWriterPtr_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- The volume mesh or surface registry being used
|
||||
const objectRegistry& obr() const override;
|
||||
|
||||
//- Return the local list of face IDs
|
||||
inline const labelList& faceId() const;
|
||||
|
||||
//- Return the local list of patch ID per face
|
||||
inline const labelList& facePatch() const;
|
||||
|
||||
//- Return the local true/false list representing the face flip map
|
||||
inline const boolList& faceFlip() const;
|
||||
|
||||
//- True if the specified operation needs a surface Sf
|
||||
bool needsSf() const;
|
||||
|
||||
//- True if the specified operation needs a weight-field
|
||||
bool needsWeight() const;
|
||||
|
||||
//- Initialise, e.g. face addressing
|
||||
void initialise(const dictionary& dict);
|
||||
|
||||
//- Return true if the field name is valid
|
||||
//- Return true if the field name is known and a valid type
|
||||
template<class Type>
|
||||
bool validField(const word& fieldName) const;
|
||||
|
||||
@ -338,26 +357,78 @@ protected:
|
||||
const bool applyOrientation = false
|
||||
) const;
|
||||
|
||||
//- Apply the 'operation' to the values. Operation has to
|
||||
// preserve Type.
|
||||
template<class Type>
|
||||
//- Apply the 'operation' to the values. Operation must preserve Type.
|
||||
template<class Type, class WeightType>
|
||||
Type processSameTypeValues
|
||||
(
|
||||
const Field<Type>& values,
|
||||
const vectorField& Sf,
|
||||
const scalarField& weightField
|
||||
const Field<WeightType>& weightField
|
||||
) const;
|
||||
|
||||
//- Apply the 'operation' to the values. Wrapper around
|
||||
// processSameTypeValues. See also template specialisation below.
|
||||
template<class Type>
|
||||
template<class Type, class WeightType>
|
||||
Type processValues
|
||||
(
|
||||
const Field<Type>& values,
|
||||
const vectorField& Sf,
|
||||
const scalarField& weightField
|
||||
const Field<WeightType>& weightField
|
||||
) const;
|
||||
|
||||
//- Filter a surface field according to faceIds
|
||||
template<class Type>
|
||||
tmp<Field<Type>> filterField
|
||||
(
|
||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& field,
|
||||
const bool applyOrientation
|
||||
) const;
|
||||
|
||||
//- Filter a volume field according to faceIds
|
||||
template<class Type>
|
||||
tmp<Field<Type>> filterField
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& field,
|
||||
const bool applyOrientation
|
||||
) const;
|
||||
|
||||
//- Weighting factor
|
||||
template<class WeightType>
|
||||
static tmp<scalarField> weightingFactor
|
||||
(
|
||||
const Field<WeightType>& weightField
|
||||
);
|
||||
|
||||
//- Weighting factor, weight field with the area
|
||||
template<class WeightType>
|
||||
static tmp<scalarField> weightingFactor
|
||||
(
|
||||
const Field<WeightType>& weightField,
|
||||
const vectorField& Sf
|
||||
);
|
||||
|
||||
|
||||
//- Templated helper function to output field values
|
||||
template<class WeightType>
|
||||
label writeAll
|
||||
(
|
||||
const vectorField& Sf,
|
||||
const Field<WeightType>& weightField,
|
||||
const meshedSurf& surfToWrite
|
||||
);
|
||||
|
||||
//- Templated helper function to output field values
|
||||
template<class Type, class WeightType>
|
||||
bool writeValues
|
||||
(
|
||||
const word& fieldName,
|
||||
const vectorField& Sf,
|
||||
const Field<WeightType>& weightField,
|
||||
const bool orient,
|
||||
const meshedSurf& surfToWrite
|
||||
);
|
||||
|
||||
|
||||
//- Output file header information
|
||||
virtual void writeFileHeader(Ostream& os) const;
|
||||
|
||||
@ -396,52 +467,18 @@ public:
|
||||
//- Return the region type
|
||||
inline const regionTypes& regionType() const;
|
||||
|
||||
//- Return the local list of face IDs
|
||||
inline const labelList& faceId() const;
|
||||
|
||||
//- Return the local list of patch ID per face
|
||||
inline const labelList& facePatch() const;
|
||||
|
||||
//- Return the list of +1/-1 representing face flip map
|
||||
inline const labelList& faceSign() const;
|
||||
|
||||
//- Return the output directory
|
||||
inline fileName outputDir() const;
|
||||
|
||||
//- Templated helper function to output field values
|
||||
template<class Type, class WeightType>
|
||||
bool writeValues
|
||||
(
|
||||
const word& fieldName,
|
||||
const Field<WeightType>& weightField,
|
||||
const bool orient
|
||||
);
|
||||
|
||||
//- Filter a surface field according to faceIds
|
||||
template<class Type>
|
||||
tmp<Field<Type>> filterField
|
||||
(
|
||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& field,
|
||||
const bool applyOrientation
|
||||
) const;
|
||||
|
||||
//- Filter a volume field according to faceIds
|
||||
template<class Type>
|
||||
tmp<Field<Type>> filterField
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& field,
|
||||
const bool applyOrientation
|
||||
) const;
|
||||
|
||||
//- Read from dictionary
|
||||
virtual bool read(const dictionary&);
|
||||
virtual bool read(const dictionary& dict) override;
|
||||
|
||||
//- Calculate and write
|
||||
virtual bool write();
|
||||
virtual bool write() override;
|
||||
};
|
||||
|
||||
|
||||
//- Specialisation for scalar
|
||||
//- Specialisation for scalar fields
|
||||
template<>
|
||||
scalar surfaceFieldValue::processValues
|
||||
(
|
||||
@ -451,7 +488,7 @@ scalar surfaceFieldValue::processValues
|
||||
) const;
|
||||
|
||||
|
||||
//- Specialisation for vector
|
||||
//- Specialisation for vector fields
|
||||
template<>
|
||||
vector surfaceFieldValue::processValues
|
||||
(
|
||||
@ -461,6 +498,32 @@ vector surfaceFieldValue::processValues
|
||||
) const;
|
||||
|
||||
|
||||
//- Specialisation for scalar - pass through
|
||||
template<>
|
||||
tmp<scalarField> surfaceFieldValue::weightingFactor
|
||||
(
|
||||
const Field<scalar>& weightField
|
||||
);
|
||||
|
||||
|
||||
//- Specialisation for scalar - scalar * Area
|
||||
template<>
|
||||
tmp<scalarField> surfaceFieldValue::weightingFactor
|
||||
(
|
||||
const Field<scalar>& weightField,
|
||||
const vectorField& Sf
|
||||
);
|
||||
|
||||
|
||||
//- Specialisation for vector - vector (dot) Area
|
||||
template<>
|
||||
tmp<scalarField> surfaceFieldValue::weightingFactor
|
||||
(
|
||||
const Field<vector>& weightField,
|
||||
const vectorField& Sf
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace fieldValues
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -26,14 +26,7 @@ License
|
||||
#include "surfaceFieldValue.H"
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline const Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypes&
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::regionType() const
|
||||
{
|
||||
return regionType_;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
inline const Foam::labelList&
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::faceId() const
|
||||
@ -49,10 +42,19 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::facePatch() const
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::labelList&
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::faceSign() const
|
||||
inline const Foam::boolList&
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::faceFlip() const
|
||||
{
|
||||
return faceSign_;
|
||||
return faceFlip_;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline const Foam::functionObjects::fieldValues::surfaceFieldValue::regionTypes&
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::regionType() const
|
||||
{
|
||||
return regionType_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015-2016 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2015-2017 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -25,6 +25,7 @@ License
|
||||
|
||||
#include "surfaceFieldValue.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "surfFields.H"
|
||||
#include "volFields.H"
|
||||
#include "sampledSurface.H"
|
||||
#include "surfaceWriter.H"
|
||||
@ -40,17 +41,14 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::validField
|
||||
{
|
||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf;
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> vf;
|
||||
typedef DimensionedField<Type, surfGeoMesh> smt;
|
||||
|
||||
if (regionType_ != stSampledSurface && obr_.foundObject<sf>(fieldName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (obr_.foundObject<vf>(fieldName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return
|
||||
(
|
||||
foundObject<smt>(fieldName)
|
||||
|| foundObject<vf>(fieldName)
|
||||
|| (regionType_ != stSampledSurface && foundObject<sf>(fieldName))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -65,14 +63,19 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::getFieldValues
|
||||
{
|
||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> sf;
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> vf;
|
||||
typedef DimensionedField<Type, surfGeoMesh> smt;
|
||||
|
||||
if (regionType_ != stSampledSurface && obr_.foundObject<sf>(fieldName))
|
||||
if (foundObject<smt>(fieldName))
|
||||
{
|
||||
return filterField(obr_.lookupObject<sf>(fieldName), applyOrientation);
|
||||
return lookupObject<smt>(fieldName);
|
||||
}
|
||||
else if (obr_.foundObject<vf>(fieldName))
|
||||
else if (regionType_ != stSampledSurface && foundObject<sf>(fieldName))
|
||||
{
|
||||
const vf& fld = obr_.lookupObject<vf>(fieldName);
|
||||
return filterField(lookupObject<sf>(fieldName), applyOrientation);
|
||||
}
|
||||
else if (foundObject<vf>(fieldName))
|
||||
{
|
||||
const vf& fld = lookupObject<vf>(fieldName);
|
||||
|
||||
if (surfacePtr_.valid())
|
||||
{
|
||||
@ -124,39 +127,45 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::getFieldValues
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
template<class Type, class WeightType>
|
||||
Type Foam::functionObjects::fieldValues::surfaceFieldValue::
|
||||
processSameTypeValues
|
||||
(
|
||||
const Field<Type>& values,
|
||||
const vectorField& Sf,
|
||||
const scalarField& weightField
|
||||
const Field<WeightType>& weightField
|
||||
) const
|
||||
{
|
||||
Type result = Zero;
|
||||
switch (operation_)
|
||||
{
|
||||
case opNone:
|
||||
break;
|
||||
case opSum:
|
||||
{
|
||||
result = gSum(values);
|
||||
break;
|
||||
}
|
||||
case opWeightedSum:
|
||||
{
|
||||
if (returnReduce(weightField.empty(), andOp<bool>()))
|
||||
{
|
||||
result = gSum(values);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp<scalarField> weight = weightingFactor(weightField);
|
||||
|
||||
result = gSum(weight*values);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case opSumMag:
|
||||
{
|
||||
result = gSum(cmptMag(values));
|
||||
break;
|
||||
}
|
||||
case opSumDirection:
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Operation " << operationTypeNames_[operation_]
|
||||
<< " not available for values of type "
|
||||
<< pTraits<Type>::typeName
|
||||
<< exit(FatalError);
|
||||
|
||||
result = Zero;
|
||||
break;
|
||||
}
|
||||
case opSumDirectionBalance:
|
||||
{
|
||||
FatalErrorInFunction
|
||||
@ -165,27 +174,26 @@ processSameTypeValues
|
||||
<< pTraits<Type>::typeName
|
||||
<< exit(FatalError);
|
||||
|
||||
result = Zero;
|
||||
break;
|
||||
}
|
||||
case opAverage:
|
||||
{
|
||||
label n = returnReduce(values.size(), sumOp<label>());
|
||||
const label n = returnReduce(values.size(), sumOp<label>());
|
||||
result = gSum(values)/(scalar(n) + ROOTVSMALL);
|
||||
break;
|
||||
}
|
||||
case opWeightedAverage:
|
||||
{
|
||||
if (returnReduce(weightField.size(), sumOp<label>()))
|
||||
if (returnReduce(weightField.empty(), andOp<bool>()))
|
||||
{
|
||||
// has weights
|
||||
result =
|
||||
gSum(weightField*values)/(gSum(weightField) + ROOTVSMALL);
|
||||
const label n = returnReduce(values.size(), sumOp<label>());
|
||||
result = gSum(values)/(scalar(n) + ROOTVSMALL);
|
||||
}
|
||||
else
|
||||
{
|
||||
label n = returnReduce(values.size(), sumOp<label>());
|
||||
result = gSum(values)/(scalar(n) + ROOTVSMALL);
|
||||
const scalarField factor = weightingFactor(weightField);
|
||||
|
||||
result = gSum(factor*values)/(gSum(factor) + ROOTVSMALL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -198,14 +206,9 @@ processSameTypeValues
|
||||
}
|
||||
case opWeightedAreaAverage:
|
||||
{
|
||||
const scalarField factor
|
||||
(
|
||||
returnReduce(weightField.size(), sumOp<label>()) // has weights
|
||||
? weightField*mag(Sf)
|
||||
: mag(Sf)
|
||||
);
|
||||
const scalarField factor = weightingFactor(weightField, Sf);
|
||||
|
||||
result = gSum(factor*values)/gSum(factor);
|
||||
result = gSum(factor*values)/gSum(factor + ROOTVSMALL);
|
||||
break;
|
||||
}
|
||||
case opAreaIntegrate:
|
||||
@ -217,12 +220,7 @@ processSameTypeValues
|
||||
}
|
||||
case opWeightedAreaIntegrate:
|
||||
{
|
||||
const scalarField factor
|
||||
(
|
||||
returnReduce(weightField.size(), sumOp<label>()) // has weights
|
||||
? weightField*mag(Sf)
|
||||
: mag(Sf)
|
||||
);
|
||||
const scalarField factor = weightingFactor(weightField, Sf);
|
||||
|
||||
result = gSum(factor*values);
|
||||
break;
|
||||
@ -240,16 +238,13 @@ processSameTypeValues
|
||||
case opCoV:
|
||||
{
|
||||
const scalarField magSf(mag(Sf));
|
||||
|
||||
const scalar gSumMagSf = gSum(magSf);
|
||||
|
||||
Type meanValue = gSum(values*magSf)/gSumMagSf;
|
||||
|
||||
const label nComp = pTraits<Type>::nComponents;
|
||||
|
||||
for (direction d=0; d<nComp; ++d)
|
||||
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
|
||||
{
|
||||
scalarField vals(values.component(d));
|
||||
tmp<scalarField> vals = values.component(d);
|
||||
scalar mean = component(meanValue, d);
|
||||
scalar& res = setComponent(result, d);
|
||||
|
||||
@ -260,38 +255,102 @@ processSameTypeValues
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case opAreaNormalAverage:
|
||||
{}
|
||||
case opAreaNormalIntegrate:
|
||||
{}
|
||||
case opNone:
|
||||
{}
|
||||
// handled in specializations only
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
template<class Type, class WeightType>
|
||||
Type Foam::functionObjects::fieldValues::surfaceFieldValue::processValues
|
||||
(
|
||||
const Field<Type>& values,
|
||||
const vectorField& Sf,
|
||||
const scalarField& weightField
|
||||
const Field<WeightType>& weightField
|
||||
) const
|
||||
{
|
||||
return processSameTypeValues(values, Sf, weightField);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
template<class WeightType>
|
||||
Foam::tmp<Foam::scalarField>
|
||||
Foam::functionObjects::fieldValues::surfaceFieldValue::weightingFactor
|
||||
(
|
||||
const Field<WeightType>& weightField
|
||||
)
|
||||
{
|
||||
return mag(weightField);
|
||||
}
|
||||
|
||||
|
||||
template<class WeightType>
|
||||
Foam::label Foam::functionObjects::fieldValues::surfaceFieldValue::writeAll
|
||||
(
|
||||
const vectorField& Sf,
|
||||
const Field<WeightType>& weightField,
|
||||
const meshedSurf& surfToWrite
|
||||
)
|
||||
{
|
||||
label nProcessed = 0;
|
||||
|
||||
forAll(fields_, i)
|
||||
{
|
||||
const word& fieldName = fields_[i];
|
||||
const bool orient = (i >= orientedFieldsStart_);
|
||||
|
||||
if
|
||||
(
|
||||
writeValues<scalar>
|
||||
(
|
||||
fieldName, Sf, weightField, orient, surfToWrite
|
||||
)
|
||||
|| writeValues<vector>
|
||||
(
|
||||
fieldName, Sf, weightField, orient, surfToWrite
|
||||
)
|
||||
|| writeValues<sphericalTensor>
|
||||
(
|
||||
fieldName, Sf, weightField, orient, surfToWrite
|
||||
)
|
||||
|| writeValues<symmTensor>
|
||||
(
|
||||
fieldName, Sf, weightField, orient, surfToWrite
|
||||
)
|
||||
|| writeValues<tensor>
|
||||
(
|
||||
fieldName, Sf, weightField, orient, surfToWrite
|
||||
)
|
||||
)
|
||||
{
|
||||
++nProcessed;
|
||||
}
|
||||
else
|
||||
{
|
||||
WarningInFunction
|
||||
<< "Requested field " << fieldName
|
||||
<< " not found in database and not processed"
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
|
||||
return nProcessed;
|
||||
}
|
||||
|
||||
|
||||
template<class Type, class WeightType>
|
||||
bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
|
||||
(
|
||||
const word& fieldName,
|
||||
const vectorField& Sf,
|
||||
const Field<WeightType>& weightField,
|
||||
const bool orient
|
||||
const bool orient,
|
||||
const meshedSurf& surfToWrite
|
||||
)
|
||||
{
|
||||
const bool ok = validField<Type>(fieldName);
|
||||
@ -300,47 +359,19 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
|
||||
{
|
||||
Field<Type> values(getFieldValues<Type>(fieldName, true, orient));
|
||||
|
||||
vectorField Sf;
|
||||
if (surfacePtr_.valid())
|
||||
{
|
||||
// Get oriented Sf
|
||||
Sf = surfacePtr_().Sf();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get oriented Sf
|
||||
Sf = filterField(mesh_.Sf(), true);
|
||||
}
|
||||
|
||||
// Write raw values on surface if specified
|
||||
if (surfaceWriterPtr_.valid())
|
||||
{
|
||||
Field<Type> allValues(values);
|
||||
combineFields(allValues);
|
||||
|
||||
faceList faces;
|
||||
pointField points;
|
||||
|
||||
if (surfacePtr_.valid())
|
||||
{
|
||||
combineSurfaceGeometry(faces, points);
|
||||
}
|
||||
else
|
||||
{
|
||||
combineMeshGeometry(faces, points);
|
||||
}
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
surfaceWriterPtr_->write
|
||||
(
|
||||
outputDir(),
|
||||
regionTypeNames_[regionType_] + ("_" + regionName_),
|
||||
meshedSurfRef
|
||||
(
|
||||
points,
|
||||
faces
|
||||
),
|
||||
surfToWrite,
|
||||
fieldName,
|
||||
allValues,
|
||||
false
|
||||
@ -360,27 +391,41 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::writeValues
|
||||
case postOpNone:
|
||||
break;
|
||||
case postOpSqrt:
|
||||
{
|
||||
// sqrt: component-wise - doesn't change the type
|
||||
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
|
||||
{
|
||||
// sqrt: component-wise - doesn't change the type
|
||||
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
|
||||
{
|
||||
setComponent(result, d)
|
||||
= sqrt(mag(component(result, d)));
|
||||
}
|
||||
setComponent(result, d)
|
||||
= sqrt(mag(component(result, d)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
file()<< tab << result;
|
||||
|
||||
Log << " " << operationTypeNames_[operation_]
|
||||
<< "(" << regionName_ << ") of " << fieldName
|
||||
// Write state/results information
|
||||
word prefix, suffix;
|
||||
{
|
||||
if (postOperation_ != postOpNone)
|
||||
{
|
||||
// Adjust result name to include post-operation
|
||||
prefix += postOperationTypeNames_[postOperation_];
|
||||
prefix += '(';
|
||||
suffix += ')';
|
||||
}
|
||||
|
||||
prefix += operationTypeNames_[operation_];
|
||||
prefix += '(';
|
||||
suffix += ')';
|
||||
}
|
||||
|
||||
Log << " " << prefix << regionName_ << suffix
|
||||
<< " of " << fieldName
|
||||
<< " = " << result << endl;
|
||||
|
||||
// Write state/results information
|
||||
const word& opName = operationTypeNames_[operation_];
|
||||
word resultName =
|
||||
opName + '(' + regionName_ + ',' + fieldName + ')';
|
||||
word resultName = prefix + regionName_ + ',' + fieldName + suffix;
|
||||
this->setResult(resultName, result);
|
||||
}
|
||||
}
|
||||
@ -423,7 +468,10 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::filterField
|
||||
{
|
||||
forAll(values, i)
|
||||
{
|
||||
values[i] *= faceSign_[i];
|
||||
if (faceFlip_[i])
|
||||
{
|
||||
values[i] *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -460,7 +508,10 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::filterField
|
||||
{
|
||||
forAll(values, i)
|
||||
{
|
||||
values[i] *= faceSign_[i];
|
||||
if (faceFlip_[i])
|
||||
{
|
||||
values[i] *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user