ENH: integrate surfField-based fluxSummary

- additional surface and surfaceAndDirection modes
This commit is contained in:
Mark Olesen
2016-12-15 12:59:35 +01:00
parent b073c0a104
commit e6f8d27553
2 changed files with 303 additions and 31 deletions

View File

@ -25,6 +25,8 @@ License
#include "fluxSummary.H" #include "fluxSummary.H"
#include "surfaceFields.H" #include "surfaceFields.H"
#include "surfFields.H"
#include "surfMesh.H"
#include "dictionary.H" #include "dictionary.H"
#include "Time.H" #include "Time.H"
#include "syncTools.H" #include "syncTools.H"
@ -54,33 +56,59 @@ template<>
const char* NamedEnum const char* NamedEnum
< <
functionObjects::fluxSummary::modeType, functionObjects::fluxSummary::modeType,
3 5
>::names[] = >::names[] =
{ {
"faceZone", "faceZone",
"faceZoneAndDirection", "faceZoneAndDirection",
"cellZoneAndDirection" "cellZoneAndDirection",
"surface",
"surfaceAndDirection"
}; };
} }
const Foam::NamedEnum<Foam::functionObjects::fluxSummary::modeType, 3> const Foam::NamedEnum<Foam::functionObjects::fluxSummary::modeType, 5>
Foam::functionObjects::fluxSummary::modeTypeNames_; Foam::functionObjects::fluxSummary::modeTypeNames_;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::functionObjects::fluxSummary::isSurfaceMode() const
{
bool isSurf = false;
switch (mode_)
{
case mdSurface:
case mdSurfaceAndDirection:
isSurf = true;
break;
default:
break;
}
return isSurf;
}
Foam::word Foam::functionObjects::fluxSummary::checkFlowType Foam::word Foam::functionObjects::fluxSummary::checkFlowType
( (
const dimensionSet& dims, const dimensionSet& fieldDims,
const word& fieldName const word& fieldName
) const ) const
{ {
if (dims == dimVolume/dimTime) // Surfaces are multipled by their area, so account for that
// in the dimension checking
dimensionSet dims =
fieldDims * (isSurfaceMode() ? dimTime*dimArea : dimTime);
if (dims == dimVolume)
{ {
return "volumetric"; return "volumetric";
} }
else if (dims == dimMass/dimTime) else if (dims == dimMass)
{ {
return "mass"; return "mass";
} }
@ -88,7 +116,7 @@ Foam::word Foam::functionObjects::fluxSummary::checkFlowType
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Unsupported flux field " << fieldName << " with dimensions " << "Unsupported flux field " << fieldName << " with dimensions "
<< dims << fieldDims
<< ". Expected either mass flow or volumetric flow rate." << ". Expected either mass flow or volumetric flow rate."
<< abort(FatalError); << abort(FatalError);
@ -97,6 +125,76 @@ Foam::word Foam::functionObjects::fluxSummary::checkFlowType
} }
void Foam::functionObjects::fluxSummary::initialiseSurface
(
const word& surfName,
DynamicList<word>& names,
DynamicList<vector>& directions,
DynamicList<boolList>& faceFlip
) const
{
const surfMesh* sPtr = mesh_.lookupObjectPtr<surfMesh>(surfName);
if (!sPtr)
{
FatalErrorInFunction
<< "Unable to find surface " << surfName
<< ". Valid surfaces are: " << mesh_.sortedNames<surfMesh>()
<< '.'
<< exit(FatalError);
}
names.append(surfName);
directions.append(Zero); // dummy value
faceFlip.append(boolList(0)); // no flip-map
}
void Foam::functionObjects::fluxSummary::initialiseSurfaceAndDirection
(
const word& surfName,
const vector& dir,
DynamicList<word>& names,
DynamicList<vector>& directions,
DynamicList<boolList>& faceFlip
) const
{
const surfMesh* sPtr = mesh_.lookupObjectPtr<surfMesh>(surfName);
if (!sPtr)
{
FatalErrorInFunction
<< "Unable to find surface " << surfName
<< ". Valid surfaces are: " << mesh_.sortedNames<surfMesh>()
<< '.'
<< exit(FatalError);
}
const surfMesh& s = *sPtr;
const vector refDir = dir/(mag(dir) + ROOTVSMALL);
names.append(surfName);
directions.append(refDir);
faceFlip.append(boolList(0));
boolList& flips = faceFlip[faceFlip.size()-1];
flips.setSize(s.size(), false);
forAll(s, i)
{
// orientation set by comparison with reference direction
const vector& n = s.faceNormals()[i];
if ((n & refDir) > tolerance_)
{
flips[i] = false;
}
else
{
flips[i] = true;
}
}
}
void Foam::functionObjects::fluxSummary::initialiseFaceZone void Foam::functionObjects::fluxSummary::initialiseFaceZone
( (
const word& faceZoneName, const word& faceZoneName,
@ -570,15 +668,23 @@ void Foam::functionObjects::fluxSummary::initialiseCellZoneAndDirection
Foam::scalar Foam::functionObjects::fluxSummary::totalArea Foam::scalar Foam::functionObjects::fluxSummary::totalArea
( (
const label zonei const label idx
) const ) const
{
scalar sumMagSf = 0;
if (isSurfaceMode())
{
const surfMesh& s = mesh_.lookupObject<surfMesh>(zoneNames_[idx]);
sumMagSf = sum(s.magSf());
}
else
{ {
const surfaceScalarField& magSf = mesh_.magSf(); const surfaceScalarField& magSf = mesh_.magSf();
const labelList& faceIDs = faceID_[zonei]; const labelList& faceIDs = faceID_[idx];
const labelList& facePatchIDs = facePatchID_[zonei]; const labelList& facePatchIDs = facePatchID_[idx];
scalar sumMagSf = 0;
forAll(faceIDs, i) forAll(faceIDs, i)
{ {
label facei = faceIDs[i]; label facei = faceIDs[i];
@ -593,11 +699,92 @@ Foam::scalar Foam::functionObjects::fluxSummary::totalArea
sumMagSf += magSf.boundaryField()[patchi][facei]; sumMagSf += magSf.boundaryField()[patchi][facei];
} }
} }
}
return returnReduce(sumMagSf, sumOp<scalar>()); return returnReduce(sumMagSf, sumOp<scalar>());
} }
bool Foam::functionObjects::fluxSummary::surfaceModeWrite()
{
if (zoneNames_.size())
{
const label surfi = 0;
const surfMesh& s = mesh_.lookupObject<surfMesh>(zoneNames_[surfi]);
const surfVectorField& phi = s.lookupObject<surfVectorField>(phiName_);
Log << type() << ' ' << name() << ' '
<< checkFlowType(phi.dimensions(), phi.name()) << " write:" << nl;
}
forAll(zoneNames_, surfi)
{
const surfMesh& s = mesh_.lookupObject<surfMesh>(zoneNames_[surfi]);
const surfVectorField& phi = s.lookupObject<surfVectorField>(phiName_);
checkFlowType(phi.dimensions(), phi.name());
const boolList& flips = faceFlip_[surfi];
scalar phiPos = scalar(0);
scalar phiNeg = scalar(0);
tmp<scalarField> tphis = phi & s.Sf();
const scalarField& phis = tphis();
forAll(s, i)
{
scalar phif = phis[i];
if (flips[i])
{
phif *= -1;
}
if (phif > 0)
{
phiPos += phif;
}
else
{
phiNeg += phif;
}
}
reduce(phiPos, sumOp<scalar>());
reduce(phiNeg, sumOp<scalar>());
phiPos *= scaleFactor_;
phiNeg *= scaleFactor_;
scalar netFlux = phiPos + phiNeg;
scalar absoluteFlux = phiPos - phiNeg;
Log << " surface " << zoneNames_[surfi] << ':' << nl
<< " positive : " << phiPos << nl
<< " negative : " << phiNeg << nl
<< " net : " << netFlux << nl
<< " absolute : " << absoluteFlux
<< nl << endl;
if (writeToFile())
{
filePtrs_[surfi]
<< time_.value() << token::TAB
<< phiPos << token::TAB
<< phiNeg << token::TAB
<< netFlux << token::TAB
<< absoluteFlux
<< endl;
}
}
Log << endl;
return true;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::fluxSummary::fluxSummary Foam::functionObjects::fluxSummary::fluxSummary
@ -708,6 +895,40 @@ bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
} }
break; break;
} }
case mdSurface:
{
List<word> surfs(dict.lookup("surfaces"));
forAll(surfs, i)
{
initialiseSurface
(
surfs[i],
faceZoneName,
refDir,
faceFlips
);
}
break;
}
case mdSurfaceAndDirection:
{
List<Tuple2<word, vector>>
surfAndDirection(dict.lookup("surfaceAndDirection"));
forAll(surfAndDirection, i)
{
initialiseSurfaceAndDirection
(
surfAndDirection[i].first(),
surfAndDirection[i].second(),
faceZoneName,
refDir,
faceFlips
);
}
break;
}
default: default:
{ {
FatalIOErrorInFunction(dict) FatalIOErrorInFunction(dict)
@ -730,7 +951,16 @@ bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
const word& zoneName = zoneNames_[zonei]; const word& zoneName = zoneNames_[zonei];
areas[zonei] = totalArea(zonei); areas[zonei] = totalArea(zonei);
Info<< " Zone: " << zoneName << ", area: " << areas[zonei] << nl; if (isSurfaceMode())
{
Info<< " Surface: " << zoneName
<< ", area: " << areas[zonei] << nl;
}
else
{
Info<< " Zone: " << zoneName
<< ", area: " << areas[zonei] << nl;
}
} }
Info<< endl; Info<< endl;
@ -752,7 +982,7 @@ bool Foam::functionObjects::fluxSummary::read(const dictionary& dict)
} }
} }
return true; return !zoneNames_.empty();
} }
@ -765,13 +995,21 @@ void Foam::functionObjects::fluxSummary::writeFileHeader
) const ) const
{ {
writeHeader(os, "Flux summary"); writeHeader(os, "Flux summary");
if (isSurfaceMode())
{
writeHeaderValue(os, "Surface", zoneName);
}
else
{
writeHeaderValue(os, "Face zone", zoneName); writeHeaderValue(os, "Face zone", zoneName);
}
writeHeaderValue(os, "Total area", area); writeHeaderValue(os, "Total area", area);
switch (mode_) switch (mode_)
{ {
case mdFaceZoneAndDirection: case mdFaceZoneAndDirection:
case mdCellZoneAndDirection: case mdCellZoneAndDirection:
case mdSurfaceAndDirection:
{ {
writeHeaderValue(os, "Reference direction", refDir); writeHeaderValue(os, "Reference direction", refDir);
break; break;
@ -799,6 +1037,11 @@ bool Foam::functionObjects::fluxSummary::execute()
bool Foam::functionObjects::fluxSummary::write() bool Foam::functionObjects::fluxSummary::write()
{ {
if (isSurfaceMode())
{
return surfaceModeWrite();
}
const surfaceScalarField& phi = lookupObject<surfaceScalarField>(phiName_); const surfaceScalarField& phi = lookupObject<surfaceScalarField>(phiName_);
Log << type() << ' ' << name() << ' ' Log << type() << ' ' << name() << ' '

View File

@ -68,6 +68,8 @@ Usage
- faceZone - faceZone
- faceZoneAndDirection - faceZoneAndDirection
- cellZoneAndDirection - cellZoneAndDirection
- surface
- surfaceAndDirection
Output data is written to files of the form \<timeDir\>/<faceZoneName>.dat Output data is written to files of the form \<timeDir\>/<faceZoneName>.dat
@ -116,11 +118,13 @@ public:
{ {
mdFaceZone, //!< face zone mdFaceZone, //!< face zone
mdFaceZoneAndDirection, //!< face zone with prescribed direction mdFaceZoneAndDirection, //!< face zone with prescribed direction
mdCellZoneAndDirection //!< cell zone with prescribed direction mdCellZoneAndDirection, //!< cell zone with prescribed direction
mdSurface, //!< surfMesh
mdSurfaceAndDirection //!< surfMesh with prescribed direction
}; };
//- Mode type names //- Mode type names
static const NamedEnum<modeType, 3> modeTypeNames_; static const NamedEnum<modeType, 5> modeTypeNames_;
protected: protected:
@ -161,14 +165,36 @@ protected:
// Private Member Functions // Private Member Functions
//- Check if surface mode instead of zone mode
bool isSurfaceMode() const;
//- Check flowType (mass or volume). //- Check flowType (mass or volume).
// Return name on success, fatal error on failure. // Return name on success, fatal error on failure.
word checkFlowType word checkFlowType
( (
const dimensionSet& dims, const dimensionSet& fieldDims,
const word& fieldName const word& fieldName
) const; ) const;
//- Initialise for given surface name
void initialiseSurface
(
const word& surfName,
DynamicList<word>& names,
DynamicList<vector>& dir,
DynamicList<boolList>& faceFlip
) const;
//- Initialise for given surface name and direction
void initialiseSurfaceAndDirection
(
const word& surfName,
const vector& refDir,
DynamicList<word>& names,
DynamicList<vector>& dir,
DynamicList<boolList>& faceFlip
) const;
//- Initialise face set from face zone //- Initialise face set from face zone
void initialiseFaceZone void initialiseFaceZone
( (
@ -204,8 +230,8 @@ protected:
DynamicList<boolList>& faceFlip DynamicList<boolList>& faceFlip
) const; ) const;
//- Calculate the total area for the derived faceZone //- Calculate the total area for the surface or derived faceZone
scalar totalArea(const label zonei) const; scalar totalArea(const label idx) const;
//- Output file header information //- Output file header information
virtual void writeFileHeader virtual void writeFileHeader
@ -216,6 +242,9 @@ protected:
Ostream& os Ostream& os
) const; ) const;
//- Specialized write for surfaces
bool surfaceModeWrite();
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
fluxSummary(const fluxSummary&) = delete; fluxSummary(const fluxSummary&) = delete;