BUG: incorrect local face addressing for fa::faceSetOption subset

- list of faces() was using mesh-faces, not area-faces

ENH: provision for patch and faceSet selection in fa::faceSetOption

- adjust most of the faOptions to respect subset of faces

ENH: support Function1 for externalHeatFluxSource

BUG: incorrect handling of fixedPower (externalHeatFluxSource)

- used local areas instead of global total area
This commit is contained in:
Mark Olesen 2022-09-15 11:08:52 +02:00
parent c59dc00623
commit fe7dd51258
17 changed files with 519 additions and 311 deletions

View File

@ -65,8 +65,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef limitVelocity_H #ifndef Foam_fa_limitVelocity_H
#define limitVelocity_H #define Foam_fa_limitVelocity_H
#include "faceSetOption.H" #include "faceSetOption.H"
@ -83,7 +83,7 @@ namespace fa
class limitVelocity class limitVelocity
: :
public faceSetOption public fa::faceSetOption
{ {
protected: protected:
@ -96,17 +96,6 @@ protected:
scalar max_; scalar max_;
private:
// Private Member Functions
//- No copy construct
limitVelocity(const limitVelocity&) = delete;
//- No copy assignment
void operator=(const limitVelocity&) = delete;
public: public:
//- Runtime type information //- Runtime type information
@ -124,6 +113,12 @@ public:
const fvPatch& patch const fvPatch& patch
); );
//- No copy construct
limitVelocity(const limitVelocity&) = delete;
//- No copy assignment
void operator=(const limitVelocity&) = delete;
//- Destructor //- Destructor
virtual ~limitVelocity() = default; virtual ~limitVelocity() = default;

View File

@ -103,26 +103,19 @@ Foam::fa::options& Foam::fa::options::New(const fvPatch& p)
{ {
const fvMesh& mesh = p.boundaryMesh().mesh(); const fvMesh& mesh = p.boundaryMesh().mesh();
if (mesh.thisDb().foundObject<options>(typeName)) options* ptr = mesh.thisDb().getObjectPtr<options>(typeName);
{
return const_cast<options&>
(
mesh.lookupObject<options>(typeName)
);
}
else
{
if (debug)
{
InfoInFunction
<< "Constructing " << typeName
<< " for region " << mesh.name() << endl;
}
options* objectPtr = new options(p); if (!ptr)
regIOobject::store(objectPtr); {
return *objectPtr; DebugInFunction
<< "Constructing " << typeName
<< " for region " << mesh.name() << endl;
ptr = new options(p);
regIOobject::store(ptr);
} }
return *ptr;
} }
@ -133,10 +126,8 @@ bool Foam::fa::options::read()
optionList::read(*this); optionList::read(*this);
return true; return true;
} }
else
{ return false;
return false;
}
} }

View File

@ -86,8 +86,7 @@ public:
//- Destructor //- Destructor
virtual ~options() virtual ~options() = default;
{}
// Member Functions // Member Functions

View File

@ -26,6 +26,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "faceSetOption.H" #include "faceSetOption.H"
#include "faceSet.H"
#include "areaFields.H" #include "areaFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -46,7 +47,10 @@ const Foam::Enum
Foam::fa::faceSetOption::selectionModeTypeNames_ Foam::fa::faceSetOption::selectionModeTypeNames_
({ ({
{ selectionModeType::smAll, "all" }, { selectionModeType::smAll, "all" },
{ selectionModeType::smVolFaceZone, "volFaceZone" } { selectionModeType::smFaceSet, "faceSet" },
{ selectionModeType::smFaceZone, "faceZone" },
{ selectionModeType::smPatch, "patch" },
{ selectionModeType::smFaceZone, "volFaceZone" } // Compat?
}); });
@ -54,15 +58,44 @@ Foam::fa::faceSetOption::selectionModeTypeNames_
void Foam::fa::faceSetOption::setSelection(const dictionary& dict) void Foam::fa::faceSetOption::setSelection(const dictionary& dict)
{ {
selectionNames_.clear();
switch (selectionMode_) switch (selectionMode_)
{ {
case smAll: case smAll:
{ {
break; break;
} }
case smVolFaceZone: case smFaceSet:
{ {
dict.readEntry("faceZone", zoneName_); selectionNames_.resize(1);
dict.readEntry("faceSet", selectionNames_.first());
break;
}
case smFaceZone:
{
if
(
!dict.readIfPresent("faceZones", selectionNames_)
|| selectionNames_.empty()
)
{
selectionNames_.resize(1);
dict.readEntry("faceZone", selectionNames_.first());
}
break;
}
case smPatch:
{
if
(
!dict.readIfPresent("patches", selectionNames_)
|| selectionNames_.empty()
)
{
selectionNames_.resize(1);
dict.readEntry("patch", selectionNames_.first());
}
break; break;
} }
default: default:
@ -82,21 +115,22 @@ void Foam::fa::faceSetOption::setArea()
{ {
// Set area information // Set area information
scalar sumArea = 0.0; scalar sumArea = 0;
for (const label facei : faces_) for (const label facei : faces_)
{ {
sumArea += regionMesh().S()[facei]; sumArea += regionMesh().S()[facei];
} }
reduce(sumArea, sumOp<scalar>()); reduce(sumArea, sumOp<scalar>());
const scalar AOld = A_; const scalar old(A_);
A_ = sumArea; A_ = sumArea;
// Convert both areas to representation using current writeprecision // Compare area values, stringified using current write precision
word AOldName(Time::timeName(AOld, IOstream::defaultPrecision())); if
word AName(Time::timeName(A_, IOstream::defaultPrecision())); (
Time::timeName(old, IOstream::defaultPrecision())
if (AName != AOldName) != Time::timeName(A_, IOstream::defaultPrecision())
)
{ {
Info<< indent Info<< indent
<< "- selected " << returnReduce(faces_.size(), sumOp<label>()) << "- selected " << returnReduce(faces_.size(), sumOp<label>())
@ -109,37 +143,32 @@ void Foam::fa::faceSetOption::setFaceSelection()
{ {
switch (selectionMode_) switch (selectionMode_)
{ {
case smVolFaceZone: case smAll:
{
Info<< indent << "- selecting all faces" << endl;
faces_ = identity(regionMesh().nFaces());
break;
}
case smFaceSet:
{ {
Info<< indent Info<< indent
<< "- selecting faces using volume-mesh faceZone " << "- selecting face subset using volume-mesh faceSet "
<< zoneName_ << nl; << zoneName() << nl;
// Also handles groups, multiple zones (as wordRe match) ... const faceSet subset(mesh_, zoneName());
labelList zoneIDs = mesh_.faceZones().indices(zoneName_);
if (zoneIDs.empty())
{
FatalErrorInFunction
<< "No matching faceZones: " << zoneName_ << nl
<< "Valid zones : "
<< flatOutput(mesh_.faceZones().names()) << nl
<< "Valid groups: "
<< flatOutput(mesh_.faceZones().groupNames())
<< nl
<< exit(FatalError);
}
const bitSet isZoneFace(mesh_.faceZones().selection(zoneIDs));
const labelUList& faceLabels = regionMesh().faceLabels(); const labelUList& faceLabels = regionMesh().faceLabels();
faces_.resize_nocopy(faceLabels.size()); faces_.resize_nocopy(faceLabels.size());
label nUsed = 0; label nUsed = 0;
for (const label facei : faceLabels) forAll(faceLabels, facei)
{ {
if (isZoneFace[facei]) const label meshFacei = faceLabels[facei];
if (subset.test(meshFacei))
{ {
faces_[nUsed] = facei; faces_[nUsed] = facei;
++nUsed; ++nUsed;
@ -149,13 +178,93 @@ void Foam::fa::faceSetOption::setFaceSelection()
break; break;
} }
case smAll: case smFaceZone:
{ {
Info<< indent << "- selecting all faces" << endl; Info<< indent
faces_ = identity(regionMesh().nFaces()); << "- selecting face subset using volume-mesh faceZones "
<< flatOutput(selectionNames_) << nl;
const auto& zones = mesh_.faceZones();
// Also handles groups, multiple zones etc ...
labelList zoneIDs = zones.indices(selectionNames_);
if (zoneIDs.empty())
{
FatalErrorInFunction
<< "No matching faceZones: "
<< flatOutput(selectionNames_) << nl
<< "Valid zones : "
<< flatOutput(zones.names()) << nl
<< "Valid groups: "
<< flatOutput(zones.groupNames())
<< nl
<< exit(FatalError);
}
const bitSet subset(mesh_.faceZones().selection(zoneIDs));
const labelUList& faceLabels = regionMesh().faceLabels();
faces_.resize_nocopy(faceLabels.size());
label nUsed = 0;
forAll(faceLabels, facei)
{
const label meshFacei = faceLabels[facei];
if (subset.test(meshFacei))
{
faces_[nUsed] = facei;
++nUsed;
}
}
faces_.resize(nUsed);
break; break;
} }
case smPatch:
{
Info<< indent
<< "- selecting face subset using volume-mesh patches "
<< flatOutput(selectionNames_) << nl;
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
// Also handles groups, multiple patches etc ...
labelList patchIDs = pbm.indices(selectionNames_);
if (patchIDs.empty())
{
FatalErrorInFunction
<< "No matching patches: "
<< flatOutput(selectionNames_) << nl
<< "Valid patches : "
<< flatOutput(pbm.names()) << nl
<< "Valid groups: "
<< flatOutput(pbm.groupNames()) << nl
<< exit(FatalError);
}
const List<labelPair>& patchFaces = regionMesh().whichPatchFaces();
faces_.resize_nocopy(patchFaces.size());
label nUsed = 0;
forAll(patchFaces, facei)
{
const label patchi = patchFaces[facei].first();
if (patchIDs.found(patchi))
{
faces_[nUsed] = facei;
++nUsed;
}
}
faces_.resize(nUsed);
break;
}
default: default:
{ {
FatalErrorInFunction FatalErrorInFunction
@ -166,6 +275,12 @@ void Foam::fa::faceSetOption::setFaceSelection()
<< exit(FatalError); << exit(FatalError);
} }
} }
if (smAll != selectionMode_ && returnReduceAnd(faces_.empty()))
{
WarningInFunction
<< "No faces selected!" << endl;
}
} }
@ -183,7 +298,7 @@ Foam::fa::faceSetOption::faceSetOption
timeStart_(-1), timeStart_(-1),
duration_(0), duration_(0),
selectionMode_(selectionModeTypeNames_.get("selectionMode", coeffs_)), selectionMode_(selectionModeTypeNames_.get("selectionMode", coeffs_)),
zoneName_(), selectionNames_(),
A_(0) A_(0)
{ {
if (isActive()) if (isActive())
@ -229,6 +344,8 @@ bool Foam::fa::faceSetOption::read(const dictionary& dict)
{ {
if (fa::option::read(dict)) if (fa::option::read(dict))
{ {
timeStart_ = -1;
if (coeffs_.readIfPresent("timeStart", timeStart_)) if (coeffs_.readIfPresent("timeStart", timeStart_))
{ {
coeffs_.readEntry("duration", duration_); coeffs_.readEntry("duration", duration_);

View File

@ -39,18 +39,23 @@ Usage
... ...
// Mandatory entries (unmodifiable) // Mandatory entries (unmodifiable)
selectionMode all; selectionMode all;
// Optional entries (runtime modifiable) // Optional entries (runtime modifiable)
timeStart 1.0; timeStart 1.0;
// Conditional mandatory entries (runtime modifiable) // Conditional mandatory entries (runtime modifiable)
// when timeStart entry is present // when timeStart entry is present
duration 1.4; duration 1.4;
// when selectionMode=volFaceZone // when selectionMode=faceZone
faceZone <faceZoneName>; faceZones (<name> ...);
//or: faceZone <name>;
// when selectionMode=patch
patches (<name> ...)
//or: patch <name>;
} }
\endverbatim \endverbatim
@ -61,13 +66,21 @@ Usage
timeStart | Start time of faOption | scalar | no | -1 timeStart | Start time of faOption | scalar | no | -1
duration | Duration of faOption execution <!-- duration | Duration of faOption execution <!--
--> starting from timeStart | scalar | cndtnl | 0 --> starting from timeStart | scalar | cndtnl | 0
faceZone | Name of operand faceZone | word | cndtnl | - faceSet | Name of operand faceSet | word | cndtnl | -
faceZone | Name of operand faceZone(s) | wordRe | cndtnl | -
faceZones | Names of operand faceZones | wordRes| cndtnl | -
patch | Name of operand poly patch(s) | wordRe | cndtnl | -
patches | Names of operand poly patches | wordRes| cndtnl | -
\endtable \endtable
Options for the \c selectionMode entry: Options for the \c selectionMode entry:
\verbatim \verbatim
all | Use all faces in the computational domain all | Use all faces in the computational domain
faceZone | Use a given faceZone faceSet | Use subset corresponding to specified (volume) faceSet
faceZones | Use subset corresponding to specified (volume) faceZones
faceZone | Use subset corresponding to specified (volume) faceZones
patch | Use subset corresponding of specified volume patches
patches | Use subset corresponding of specified volume patches
\endverbatim \endverbatim
The inherited entries are elaborated in: The inherited entries are elaborated in:
@ -78,6 +91,7 @@ Note
SourceFiles SourceFiles
faceSetOption.C faceSetOption.C
faceSetOptionI.H
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -111,8 +125,10 @@ public:
//- Enumeration for selection mode types //- Enumeration for selection mode types
enum selectionModeType enum selectionModeType
{ {
smAll, smAll, //!< "all" finite-area faces
smVolFaceZone smFaceSet, //!< "faceSet" : subset with (volume) face set
smFaceZone, //!< "faceZone" : subset with (volume) zone faces
smPatch, //!< "patch" : subset with (volume) patches
}; };
//- List of selection mode type names //- List of selection mode type names
@ -132,8 +148,8 @@ protected:
//- Face selection mode //- Face selection mode
selectionModeType selectionMode_; selectionModeType selectionMode_;
//- Name of zone for (volume) "faceZone" selection //- Face selection names (for set, zone or patch selections)
wordRe zoneName_; wordRes selectionNames_;
//- Set of faces to apply source to //- Set of faces to apply source to
labelList faces_; labelList faces_;
@ -153,6 +169,10 @@ protected:
//- Recalculate the area //- Recalculate the area
void setArea(); void setArea();
//- Zero all non-selected locations within field
template<class Type>
inline void subsetFilter(List<Type>& field) const;
public: public:
@ -189,20 +209,23 @@ public:
//- Return true if within time limits //- Return true if within time limits
inline bool inTimeLimits(const scalar timeValue) const; inline bool inTimeLimits(const scalar timeValue) const;
//- Return const access to the face selection mode
inline selectionModeType selectionMode() const noexcept;
//- True if sub-selection should be used //- True if sub-selection should be used
inline bool useSubMesh() const noexcept; inline bool useSubMesh() const noexcept;
//- Return const access to the name of (volume) face zone //- Return the face selection mode
//- for "faceZone" selection mode inline selectionModeType selectionMode() const noexcept;
const wordRe& zoneName() const noexcept { return zoneName_; }
//- Return const access to the selection names
//- (set, zone or patch selection)
inline const wordRes& selectionNames() const noexcept;
//- Return const access to the first set/zone/patch name
inline const wordRe& zoneName() const;
//- Return const access to the total face area //- Return const access to the total face area
inline scalar A() const noexcept; inline scalar A() const noexcept;
//- Return const access to the face selection //- Return const access to the local finite-area face selection
inline const labelList& faces() const noexcept; inline const labelList& faces() const noexcept;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,6 +25,25 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type>
inline void Foam::fa::faceSetOption::subsetFilter(List<Type>& field) const
{
if (selectionMode_ != selectionModeType::smAll)
{
List<Type> filtered(field.size(), Zero);
for (const label facei : faces_)
{
filtered[facei] = field[facei];
}
field.swap(filtered);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::scalar Foam::fa::faceSetOption::timeStart() const noexcept inline Foam::scalar Foam::fa::faceSetOption::timeStart() const noexcept
@ -60,6 +79,19 @@ Foam::fa::faceSetOption::selectionMode() const noexcept
} }
inline const Foam::wordRes&
Foam::fa::faceSetOption::selectionNames() const noexcept
{
return selectionNames_;
}
inline const Foam::wordRe& Foam::fa::faceSetOption::zoneName() const
{
return (selectionNames_.empty() ? wordRe::null : selectionNames_.first());
}
inline bool Foam::fa::faceSetOption::useSubMesh() const noexcept inline bool Foam::fa::faceSetOption::useSubMesh() const noexcept
{ {
return selectionMode_ != selectionModeType::smAll; return selectionMode_ != selectionModeType::smAll;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -59,22 +59,8 @@ Foam::fa::contactHeatFluxSource::contactHeatFluxSource
TName_(dict.getOrDefault<word>("T", "T")), TName_(dict.getOrDefault<word>("T", "T")),
TprimaryName_(dict.get<word>("Tprimary")), TprimaryName_(dict.get<word>("Tprimary")),
Tp_(mesh().lookupObject<volScalarField>(TprimaryName_)), Tp_(mesh().lookupObject<volScalarField>(TprimaryName_)),
Tw1_ thicknessLayers_(),
( kappaLayers_(),
IOobject
(
"Tw1_" + sourceName,
mesh().time().timeName(),
mesh(),
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
),
regionMesh(),
dimensionedScalar(dimTemperature, Zero),
zeroGradientFaPatchScalarField::typeName
),
thicknessLayers_(Zero),
kappaLayers_(Zero),
contactRes_(0), contactRes_(0),
curTimeIndex_(-1) curTimeIndex_(-1)
{ {
@ -88,57 +74,31 @@ Foam::fa::contactHeatFluxSource::contactHeatFluxSource
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::areaScalarField> Foam::fa::contactHeatFluxSource::htc() const Foam::tmp<Foam::DimensionedField<Foam::scalar, Foam::areaMesh>>
Foam::fa::contactHeatFluxSource::htc() const
{ {
IOobject io auto thtc = DimensionedField<scalar, areaMesh>::New
( (
"thtc", "htc_" + option::name(),
mesh().time().timeName(), regionMesh(),
mesh(), dimensionedScalar(dimPower/dimArea/dimTemperature, Zero)
IOobject::NO_READ,
IOobject::NO_WRITE
); );
auto& htc = thtc.ref();
tmp<areaScalarField> thtc htc.field() =
(
new areaScalarField
(
io,
regionMesh(),
dimensionedScalar(dimPower/dimArea/dimTemperature, Zero)
)
);
areaScalarField& htc = thtc.ref();
const volScalarField::Boundary& vfb = Tp_.boundaryField();
htc.primitiveFieldRef() =
temperatureCoupledBase::kappa temperatureCoupledBase::kappa
( (
vsm().mapInternalToSurface<scalar>(vfb)() vsm().mapInternalToSurface<scalar>(Tp_)()
)*patch().deltaCoeffs(); )*patch().deltaCoeffs();
if (contactRes_ != 0) if (contactRes_ != 0)
{ {
tmp<areaScalarField> tcontact htc.field() += contactRes_;
(
new areaScalarField
(
io,
regionMesh(),
dimensionedScalar
(
"contact",
dimPower/dimArea/dimTemperature,
contactRes_
)
)
);
areaScalarField& contact = tcontact.ref();
htc.primitiveFieldRef() += contact.primitiveField();
} }
// Zero htc for non-mapped faces
faceSetOption::subsetFilter(htc.field());
return thtc; return thtc;
} }
@ -153,19 +113,26 @@ void Foam::fa::contactHeatFluxSource::addSup
{ {
if (isActive()) if (isActive())
{ {
DebugInfo<< name() << ": applying source to " << eqn.psi().name() DebugInfo
<< endl; << name() << ": applying source to "
<< eqn.psi().name() << endl;
if (curTimeIndex_ != mesh().time().timeIndex()) if (curTimeIndex_ != mesh().time().timeIndex())
{ {
const volScalarField::Boundary& vfb = Tp_.boundaryField(); tmp<DimensionedField<scalar, areaMesh>> htcw(htc());
Tw1_.primitiveFieldRef() = // Wall temperature - mapped from primary field to finite-area
this->vsm().mapInternalToSurface<scalar>(vfb); auto Twall = DimensionedField<scalar, areaMesh>::New
(
"Tw_" + option::name(),
regionMesh(),
dimensionedScalar(dimTemperature, Zero)
);
tmp<areaScalarField> htcw = htc(); Twall.ref().field() =
this->vsm().mapInternalToSurface<scalar>(Tp_);
eqn += -fam::Sp(htcw(), eqn.psi()) + htcw()*Tw1_; eqn += -fam::Sp(htcw(), eqn.psi()) + htcw()*Twall;
curTimeIndex_ = mesh().time().timeIndex(); curTimeIndex_ = mesh().time().timeIndex();
} }
@ -179,17 +146,21 @@ bool Foam::fa::contactHeatFluxSource::read(const dictionary& dict)
{ {
coeffs_.readIfPresent("T", TName_); coeffs_.readIfPresent("T", TName_);
contactRes_ = 0;
if (dict.readIfPresent("thicknessLayers", thicknessLayers_)) if (dict.readIfPresent("thicknessLayers", thicknessLayers_))
{ {
dict.readEntry("kappaLayers", kappaLayers_); dict.readEntry("kappaLayers", kappaLayers_);
if (thicknessLayers_.size() > 0) // Calculate effective thermal resistance by harmonic averaging
forAll(thicknessLayers_, iLayer)
{
contactRes_ += thicknessLayers_[iLayer]/kappaLayers_[iLayer];
}
if (thicknessLayers_.size())
{ {
// Calculate effective thermal resistance by harmonic averaging
forAll(thicknessLayers_, iLayer)
{
contactRes_ += thicknessLayers_[iLayer]/kappaLayers_[iLayer];
}
contactRes_ = scalar(1)/contactRes_; contactRes_ = scalar(1)/contactRes_;
} }
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -76,8 +76,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef fa_contactHeatFluxSource_H #ifndef Foam_fa_contactHeatFluxSource_H
#define fa_contactHeatFluxSource_H #define Foam_fa_contactHeatFluxSource_H
#include "faOption.H" #include "faOption.H"
#include "Function1.H" #include "Function1.H"
@ -112,9 +112,6 @@ class contactHeatFluxSource
//- Primary region temperature //- Primary region temperature
const volScalarField& Tp_; const volScalarField& Tp_;
//- Temperature - wall [K]
areaScalarField Tw1_;
//- Thickness of layers //- Thickness of layers
scalarList thicknessLayers_; scalarList thicknessLayers_;
@ -130,8 +127,8 @@ class contactHeatFluxSource
// Private Member Functions // Private Member Functions
//- Return htc from the primary region //- Return htc [W/m2/K] coupling to the primary region
tmp<areaScalarField> htc() const; tmp<DimensionedField<scalar, areaMesh>> htc() const;
public: public:

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -64,13 +64,14 @@ Foam::fa::externalFileSource::externalFileSource
mesh_.time().timeName(), mesh_.time().timeName(),
mesh_, mesh_,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE,
false // Do not register
), ),
regionMesh(), regionMesh(),
dimensionedScalar("pExt", dimPressure, Zero), dimensionedScalar(dimPressure, Zero)
zeroGradientFaPatchScalarField::typeName
), ),
value_ curTimeIndex_(-1),
mapping_
( (
new PatchFunction1Types::MappedFile<scalar> new PatchFunction1Types::MappedFile<scalar>
( (
@ -80,8 +81,7 @@ Foam::fa::externalFileSource::externalFileSource
tableName_, // field table name tableName_, // field table name
true // face values true // face values
) )
), )
curTimeIndex_(-1)
{ {
fieldNames_.resize(1, fieldName_); fieldNames_.resize(1, fieldName_);
@ -93,6 +93,17 @@ Foam::fa::externalFileSource::externalFileSource
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::fa::externalFileSource::updateMapping()
{
const scalar t = mesh().time().value();
pExt_.field() = mapping_->value(t);
// Zero pressure for non-mapped faces
faceSetOption::subsetFilter(pExt_.field());
}
void Foam::fa::externalFileSource::addSup void Foam::fa::externalFileSource::addSup
( (
const areaScalarField& solidMass, const areaScalarField& solidMass,
@ -100,16 +111,18 @@ void Foam::fa::externalFileSource::addSup
const label fieldi const label fieldi
) )
{ {
const scalar t = mesh().time().value(); if (isActive())
if (isActive() && t > timeStart() && t < (timeStart() + duration()))
{ {
DebugInfo<< name() << ": applying source to " << eqn.psi().name()<<endl; DebugInfo
<< name() << ": applying source to "
<< eqn.psi().name() << endl;
if (curTimeIndex_ != mesh().time().timeIndex()) if (curTimeIndex_ != mesh().time().timeIndex())
{ {
pExt_.field() = value_->value(t); updateMapping();
eqn += pExt_/solidMass;
eqn += pExt_/solidMass.internalField();
curTimeIndex_ = mesh().time().timeIndex(); curTimeIndex_ = mesh().time().timeIndex();
} }
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -31,7 +31,7 @@ Group
Description Description
Applies sources on a specified field within a specified region Applies sources on a specified field within a specified region
by using an external table file for compressible flows. by using an external table file.
Usage Usage
Minimal example by using \c constant/faOptions: Minimal example by using \c constant/faOptions:
@ -68,8 +68,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef fa_externalFileSource_H #ifndef Foam_fa_externalFileSource_H
#define fa_externalFileSource_H #define Foam_fa_externalFileSource_H
#include "faOption.H" #include "faOption.H"
#include "areaFields.H" #include "areaFields.H"
@ -100,14 +100,20 @@ class externalFileSource
word tableName_; word tableName_;
//- External pressure field //- External pressure field
areaScalarField pExt_; DimensionedField<scalar, areaMesh> pExt_;
//- Mapped data from file
autoPtr<PatchFunction1Types::MappedFile<scalar>> value_;
//- Current time index (used for updating) //- Current time index (used for updating)
label curTimeIndex_; label curTimeIndex_;
//- Mapped data from file
autoPtr<PatchFunction1Types::MappedFile<scalar>> mapping_;
// Private Member Functions
//- Update the pExt_ mapping
void updateMapping();
public: public:

View File

@ -71,9 +71,9 @@ Foam::fa::externalHeatFluxSource::externalHeatFluxSource
fa::faceSetOption(sourceName, modelType, dict, patch), fa::faceSetOption(sourceName, modelType, dict, patch),
mode_(operationModeNames.get("mode", dict)), mode_(operationModeNames.get("mode", dict)),
TName_(dict.getOrDefault<word>("T", "T")), TName_(dict.getOrDefault<word>("T", "T")),
Q_(0), Q_(nullptr),
q_(0), q_(nullptr),
h_(0), h_(nullptr),
Ta_(nullptr), Ta_(nullptr),
emissivity_(dict.getOrDefault<scalar>("emissivity", 0)) emissivity_(dict.getOrDefault<scalar>("emissivity", 0))
{ {
@ -97,73 +97,98 @@ void Foam::fa::externalHeatFluxSource::addSup
{ {
if (isActive()) if (isActive())
{ {
DebugInfo<< name() << ": applying source to " DebugInfo
<< name() << ": applying source to "
<< eqn.psi().name() << endl; << eqn.psi().name() << endl;
IOobject io scalar qflux = 0;
(
"Q",
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
);
auto tQ = tmp<areaScalarField>::New const scalar timeVal = mesh_.time().timeOutputValue();
(
io,
regionMesh(),
dimensionedScalar("q", dimPower/sqr(dimLength), 0),
zeroGradientFaPatchScalarField::typeName
);
areaScalarField& Q = tQ.ref();
switch (mode_) switch (mode_)
{ {
case fixedPower: case fixedPower:
{ {
Q.primitiveFieldRef() = Q_/regionMesh().S().field(); // From [W] to [W/m2]
qflux = Q_->value(timeVal)/(faceSetOption::A() + VSMALL);
break;
}
case fixedHeatFlux:
{
qflux = q_->value(timeVal);
break;
}
default:
{
break;
}
}
switch (mode_)
{
case fixedPower:
case fixedHeatFlux:
{
auto tQ = DimensionedField<scalar, areaMesh>::New
(
"Q",
regionMesh(),
dimensionedScalar(dimPower/sqr(dimLength), Zero)
);
auto& Q = tQ.ref();
if (faceSetOption::useSubMesh())
{
UIndirectList<scalar>(Q.field(), faceSetOption::faces())
= qflux;
}
else
{
Q.field() = qflux;
}
eqn += Q; eqn += Q;
break; break;
} }
case fixedHeatFlux:
{
Q.primitiveFieldRef() = q_;
eqn += Q;
break;
}
case fixedHeatTransferCoeff: case fixedHeatTransferCoeff:
{ {
const dimensionedScalar Ta const dimensionedScalar Ta
( (
"Ta", "Ta",
dimTemperature, dimTemperature,
Ta_->value(mesh_.time().timeOutputValue()) Ta_->value(timeVal)
); );
areaScalarField hp auto thp = DimensionedField<scalar, areaMesh>::New
( (
io, "h",
regionMesh(), regionMesh(),
dimensionedScalar dimensionedScalar
( (
"h", "h",
dimPower/sqr(dimLength)/dimTemperature, dimPower/sqr(dimLength)/dimTemperature,
h_ h_->value(timeVal)
) )
); );
auto& hp = thp.ref();
const areaScalarField hpTa(hp*Ta); DimensionedField<scalar, areaMesh> hpTa(hp*Ta);
if (emissivity_ > 0) if (emissivity_ > 0)
{ {
hp -= emissivity_*sigma.value()*pow3(eqn.psi()); hp -= emissivity_*sigma.value()*pow3(eqn.psi());
} }
eqn -= fam::SuSp(hp, eqn.psi()) - hpTa; // Zero htc for non-mapped faces
faceSetOption::subsetFilter(hp.field());
faceSetOption::subsetFilter(hpTa.field());
eqn -= fam::SuSp(hp, eqn.psi()) - hpTa;
break;
} }
} }
} }
@ -183,17 +208,17 @@ bool Foam::fa::externalHeatFluxSource::read(const dictionary& dict)
{ {
case fixedPower: case fixedPower:
{ {
dict.readEntry("Q", Q_); Q_ = Function1<scalar>::New("Q", dict, &mesh_);
break; break;
} }
case fixedHeatFlux: case fixedHeatFlux:
{ {
dict.readEntry("q", q_); Q_ = Function1<scalar>::New("q", dict, &mesh_);
break; break;
} }
case fixedHeatTransferCoeff: case fixedHeatTransferCoeff:
{ {
dict.readEntry("h", h_); h_ = Function1<scalar>::New("h", dict, &mesh_);
Ta_ = Function1<scalar>::New("Ta", dict, &mesh_); Ta_ = Function1<scalar>::New("Ta", dict, &mesh_);
break; break;
} }
@ -202,7 +227,7 @@ bool Foam::fa::externalHeatFluxSource::read(const dictionary& dict)
return true; return true;
} }
return false; return false;
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2020 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -89,9 +89,9 @@ Usage
T | Name of operand temperature field | word | no | T T | Name of operand temperature field | word | no | T
emissivity | Surface emissivity for radiative flux to ambient <!-- emissivity | Surface emissivity for radiative flux to ambient <!--
--> | scalar | no | 0 --> | scalar | no | 0
Q | Fixed heat power [W] | scalar | cndtnl | - Q | Fixed heat power [W] | Function1 | cndtnl | -
q | Fixed heat flux [W/m2] | scalar | cndtnl | - q | Fixed heat flux [W/m2] | Function1 | cndtnl | -
h | Heat transfer coefficient [W/m^2/K] | scalar | cndtnl | - h | Heat transfer coefficient [W/m^2/K] | Function1 | cndtnl | -
Ta | Ambient temperature [K] | Function1 | cndtnl | - Ta | Ambient temperature [K] | Function1 | cndtnl | -
\endtable \endtable
@ -114,8 +114,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef fa_externalHeatFluxSource_H #ifndef Foam_fa_externalHeatFluxSource_H
#define fa_externalHeatFluxSource_H #define Foam_fa_externalHeatFluxSource_H
#include "faOption.H" #include "faOption.H"
#include "Function1.H" #include "Function1.H"
@ -164,13 +164,13 @@ private:
word TName_; word TName_;
//- Heat power [W] //- Heat power [W]
scalar Q_; autoPtr<Function1<scalar>> Q_;
//- Heat flux [W/m2] //- Heat flux [W/m2]
scalar q_; autoPtr<Function1<scalar>> q_;
//- Heat transfer coefficient [W/m2K] //- Heat transfer coefficient [W/m2K]
scalar h_; autoPtr<Function1<scalar>> h_;
//- Ambient temperature [K] //- Ambient temperature [K]
autoPtr<Function1<scalar>> Ta_; autoPtr<Function1<scalar>> Ta_;
@ -187,7 +187,7 @@ public:
// Constructors // Constructors
//- Construct from explicit source name and mesh //- Construct from explicit source name and mesh
externalHeatFluxSource externalHeatFluxSource
( (
const word& sourceName, const word& sourceName,

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -59,8 +59,8 @@ Foam::fa::jouleHeatingSource::jouleHeatingSource
IOobject IOobject
( (
typeName + ":V_" + regionName_, typeName + ":V_" + regionName_,
mesh().time().timeName(), regionMesh().thisDb().time().timeName(),
mesh(), regionMesh().thisDb(),
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::AUTO_WRITE IOobject::AUTO_WRITE
), ),
@ -105,8 +105,9 @@ void Foam::fa::jouleHeatingSource::addSup
{ {
if (isActive()) if (isActive())
{ {
DebugInfo<< name() << ": applying source to " << eqn.psi().name() DebugInfo
<< endl; << name() << ": applying source to "
<< eqn.psi().name() << endl;
if (curTimeIndex_ != mesh().time().timeIndex()) if (curTimeIndex_ != mesh().time().timeIndex())
{ {
@ -142,6 +143,14 @@ void Foam::fa::jouleHeatingSource::addSup
// Add the Joule heating contribution // Add the Joule heating contribution
areaVectorField gradV("gradV", fac::grad(V_)); areaVectorField gradV("gradV", fac::grad(V_));
if (debug > 1 && mesh().time().outputTime())
{
areaScalarField qgradV("gradVSource", (gradV & gradV));
qgradV.write();
}
tmp<areaScalarField> tsource;
if (anisotropicElectricalConductivity_) if (anisotropicElectricalConductivity_)
{ {
const auto& sigma = const auto& sigma =
@ -150,7 +159,7 @@ void Foam::fa::jouleHeatingSource::addSup
typeName + ":sigma_" + regionName_ typeName + ":sigma_" + regionName_
); );
eqn += (h*sigma & gradV) & gradV; tsource = (h*sigma & gradV) & gradV;
} }
else else
{ {
@ -160,14 +169,13 @@ void Foam::fa::jouleHeatingSource::addSup
typeName + ":sigma_" + regionName_ typeName + ":sigma_" + regionName_
); );
eqn += (h*sigma*gradV) & gradV; tsource = (h*sigma*gradV) & gradV;
if (mesh().time().outputTime() && debug)
{
areaScalarField qgradV("gradVSource", (gradV & gradV));
qgradV.write();
}
} }
// Apply subMesh filter
faceSetOption::subsetFilter(tsource.ref().primitiveFieldRef());
eqn += tsource;
} }
} }

View File

@ -102,23 +102,19 @@ Foam::fv::options::options
Foam::fv::options& Foam::fv::options::New(const fvMesh& mesh) Foam::fv::options& Foam::fv::options::New(const fvMesh& mesh)
{ {
if (mesh.thisDb().foundObject<options>(typeName)) options* ptr = mesh.thisDb().getObjectPtr<options>(typeName);
{
return const_cast<options&> if (!ptr)
(
mesh.lookupObject<options>(typeName)
);
}
else
{ {
DebugInFunction DebugInFunction
<< "Constructing " << typeName << "Constructing " << typeName
<< " for region " << mesh.name() << nl; << " for region " << mesh.name() << nl;
options* objectPtr = new options(mesh); ptr = new options(mesh);
regIOobject::store(objectPtr); regIOobject::store(ptr);
return *objectPtr;
} }
return *ptr;
} }

View File

@ -48,11 +48,11 @@ const Foam::Enum
> >
Foam::fv::cellSetOption::selectionModeTypeNames_ Foam::fv::cellSetOption::selectionModeTypeNames_
({ ({
{ selectionModeType::smAll, "all" },
{ selectionModeType::smGeometric, "geometric" }, { selectionModeType::smGeometric, "geometric" },
{ selectionModeType::smPoints, "points" }, { selectionModeType::smPoints, "points" },
{ selectionModeType::smCellSet, "cellSet" }, { selectionModeType::smCellSet, "cellSet" },
{ selectionModeType::smCellZone, "cellZone" }, { selectionModeType::smCellZone, "cellZone" },
{ selectionModeType::smAll, "all" },
}); });
@ -60,8 +60,14 @@ Foam::fv::cellSetOption::selectionModeTypeNames_
void Foam::fv::cellSetOption::setSelection(const dictionary& dict) void Foam::fv::cellSetOption::setSelection(const dictionary& dict)
{ {
selectionNames_.clear();
switch (selectionMode_) switch (selectionMode_)
{ {
case smAll:
{
break;
}
case smGeometric: case smGeometric:
{ {
geometricSelection_ = dict.subDict("selection"); geometricSelection_ = dict.subDict("selection");
@ -74,16 +80,21 @@ void Foam::fv::cellSetOption::setSelection(const dictionary& dict)
} }
case smCellSet: case smCellSet:
{ {
dict.readEntry("cellSet", zoneName_); selectionNames_.resize(1);
dict.readEntry("cellSet", selectionNames_.first());
break; break;
} }
case smCellZone: case smCellZone:
{ {
dict.readEntry("cellZone", zoneName_); if
break; (
} !dict.readIfPresent("cellZones", selectionNames_)
case smAll: || selectionNames_.empty()
{ )
{
selectionNames_.resize(1);
dict.readEntry("cellZone", selectionNames_.first());
}
break; break;
} }
default: default:
@ -110,14 +121,15 @@ void Foam::fv::cellSetOption::setVol()
} }
reduce(sumVol, sumOp<scalar>()); reduce(sumVol, sumOp<scalar>());
const scalar VOld = V_; const scalar old(V_);
V_ = sumVol; V_ = sumVol;
// Convert both volumes to representation using current writeprecision // Compare volume values, stringified using current write precision
word VOldName(Time::timeName(VOld, IOstream::defaultPrecision())); if
word VName(Time::timeName(V_, IOstream::defaultPrecision())); (
Time::timeName(old, IOstream::defaultPrecision())
if (VName != VOldName) != Time::timeName(V_, IOstream::defaultPrecision())
)
{ {
Info<< indent Info<< indent
<< "- selected " << returnReduce(cells_.size(), sumOp<label>()) << "- selected " << returnReduce(cells_.size(), sumOp<label>())
@ -130,6 +142,13 @@ void Foam::fv::cellSetOption::setCellSelection()
{ {
switch (selectionMode_) switch (selectionMode_)
{ {
case smAll:
{
Info<< indent << "- selecting all cells" << endl;
cells_ = identity(mesh_.nCells());
break;
}
case smGeometric: case smGeometric:
{ {
Info<< indent << "- selecting cells geometrically" << endl; Info<< indent << "- selecting cells geometrically" << endl;
@ -174,48 +193,47 @@ void Foam::fv::cellSetOption::setCellSelection()
case smCellSet: case smCellSet:
{ {
Info<< indent Info<< indent
<< "- selecting cells using cellSet " << zoneName_ << endl; << "- selecting cells using cellSet "
<< zoneName() << endl;
cells_ = cellSet(mesh_, zoneName_).sortedToc(); cells_ = cellSet(mesh_, zoneName()).sortedToc();
break; break;
} }
case smCellZone: case smCellZone:
{ {
Info<< indent Info<< indent
<< "- selecting cells using cellZone " << zoneName_ << endl; << "- selecting cells using cellZones "
<< flatOutput(selectionNames_) << nl;
// Also handles groups, multiple zones (as wordRe match) ... const auto& zones = mesh_.cellZones();
labelList zoneIDs = mesh_.cellZones().indices(zoneName_);
// Also handles groups, multiple zones etc ...
labelList zoneIDs = zones.indices(selectionNames_);
if (zoneIDs.empty()) if (zoneIDs.empty())
{ {
FatalErrorInFunction FatalErrorInFunction
<< "No matching cellZones: " << zoneName_ << nl << "No matching cellZones: "
<< flatOutput(selectionNames_) << nl
<< "Valid zones : " << "Valid zones : "
<< flatOutput(mesh_.cellZones().names()) << nl << flatOutput(zones.names()) << nl
<< "Valid groups: " << "Valid groups: "
<< flatOutput(mesh_.cellZones().groupNames()) << flatOutput(zones.groupNames())
<< nl << nl
<< exit(FatalError); << exit(FatalError);
} }
if (zoneIDs.size() == 1) if (zoneIDs.size() == 1)
{ {
cells_ = mesh_.cellZones()[zoneIDs.first()]; cells_ = zones[zoneIDs.first()];
// TBD: Foam::sort(cells_);
} }
else else
{ {
cells_ = mesh_.cellZones().selection(zoneIDs).sortedToc(); cells_ = zones.selection(zoneIDs).sortedToc();
} }
break; break;
} }
case smAll:
{
Info<< indent << "- selecting all cells" << endl;
cells_ = identity(mesh_.nCells());
break;
}
default: default:
{ {
FatalErrorInFunction FatalErrorInFunction
@ -227,11 +245,7 @@ void Foam::fv::cellSetOption::setCellSelection()
} }
} }
if if (smAll != selectionMode_ && returnReduceAnd(cells_.empty()))
(
smAll != selectionMode_
&& returnReduce(cells_.empty(), andOp<bool>())
)
{ {
WarningInFunction WarningInFunction
<< "No cells selected!" << endl; << "No cells selected!" << endl;
@ -253,7 +267,7 @@ Foam::fv::cellSetOption::cellSetOption
timeStart_(-1), timeStart_(-1),
duration_(0), duration_(0),
selectionMode_(selectionModeTypeNames_.get("selectionMode", coeffs_)), selectionMode_(selectionModeTypeNames_.get("selectionMode", coeffs_)),
zoneName_(), selectionNames_(),
points_(), points_(),
geometricSelection_(), geometricSelection_(),
V_(0) V_(0)
@ -307,6 +321,8 @@ bool Foam::fv::cellSetOption::read(const dictionary& dict)
{ {
if (fv::option::read(dict)) if (fv::option::read(dict))
{ {
timeStart_ = -1;
if (coeffs_.readIfPresent("timeStart", timeStart_)) if (coeffs_.readIfPresent("timeStart", timeStart_))
{ {
coeffs_.readEntry("duration", duration_); coeffs_.readEntry("duration", duration_);

View File

@ -56,6 +56,8 @@ Usage
// when selectionMode=cellZone // when selectionMode=cellZone
cellZone <name>; cellZone <name>;
//OR: cellZones (<name> ...);
// when selectionMode=points // when selectionMode=points
points (<point1> <point2> ... <pointN>); points (<point1> <point2> ... <pointN>);
@ -92,7 +94,8 @@ Usage
duration | Duration of fvOption execution <!-- duration | Duration of fvOption execution <!--
--> starting from timeStart | scalar | cndtnl | 0 --> starting from timeStart | scalar | cndtnl | 0
cellSet | Name of operand cellSet | word | cndtnl | - cellSet | Name of operand cellSet | word | cndtnl | -
cellZone | Name of operand cellZone | word | cndtnl | - cellZone | Name of operand cellZone | wordRe | cndtnl | -
cellZones | Name of operand cellZones | wordRes | cndtnl | -
points | Set of points in global coordinate <!-- points | Set of points in global coordinate <!--
--> system | vectorList | cndtnl | - --> system | vectorList | cndtnl | -
selection | Dictionary of geometric selections | dict | cndtnl | - selection | Dictionary of geometric selections | dict | cndtnl | -
@ -179,8 +182,8 @@ protected:
//- Cell selection mode //- Cell selection mode
selectionModeType selectionMode_; selectionModeType selectionMode_;
//- Name of set/zone for "cellSet" and "cellZone" selectionMode //- Face selection names (for set or zone selections)
wordRe zoneName_; wordRes selectionNames_;
//- List of points for "points" selectionMode //- List of points for "points" selectionMode
List<point> points_; List<point> points_;
@ -242,15 +245,18 @@ public:
//- True if within time limits //- True if within time limits
inline bool inTimeLimits(const scalar timeValue) const; inline bool inTimeLimits(const scalar timeValue) const;
//- Return the cell selection mode
inline selectionModeType selectionMode() const noexcept;
//- True if sub-selection should be used //- True if sub-selection should be used
inline bool useSubMesh() const noexcept; inline bool useSubMesh() const noexcept;
//- Return const access to the name of cell set/zone //- Return the cell selection mode
//- for "cellSet" / "cellZone" selection modes inline selectionModeType selectionMode() const noexcept;
const wordRe& zoneName() const noexcept { return zoneName_; }
//- Return const access to the selection names
//- (set or zone selection)
inline const wordRes& selectionNames() const noexcept;
//- Return const access to the first set/zone name
inline const wordRe& zoneName() const;
//- Return const access to the total cell volume //- Return const access to the total cell volume
inline scalar V() const noexcept; inline scalar V() const noexcept;
@ -284,7 +290,7 @@ public:
//- The name of the cell set/zone [as a word] //- The name of the cell set/zone [as a word]
//- for "cellSet" / "cellZone" selection modes) //- for "cellSet" / "cellZone" selection modes)
const word& cellSetName() const noexcept { return zoneName_; } const word& cellSetName() const { return zoneName(); }
}; };

View File

@ -54,6 +54,12 @@ inline bool Foam::fv::cellSetOption::inTimeLimits(const scalar timeValue) const
} }
inline bool Foam::fv::cellSetOption::useSubMesh() const noexcept
{
return selectionMode_ != selectionModeType::smAll;
}
inline Foam::fv::cellSetOption::selectionModeType inline Foam::fv::cellSetOption::selectionModeType
Foam::fv::cellSetOption::selectionMode() const noexcept Foam::fv::cellSetOption::selectionMode() const noexcept
{ {
@ -61,9 +67,16 @@ Foam::fv::cellSetOption::selectionMode() const noexcept
} }
inline bool Foam::fv::cellSetOption::useSubMesh() const noexcept inline const Foam::wordRes&
Foam::fv::cellSetOption::selectionNames() const noexcept
{ {
return selectionMode_ != selectionModeType::smAll; return selectionNames_;
}
inline const Foam::wordRe& Foam::fv::cellSetOption::zoneName() const
{
return (selectionNames_.empty() ? wordRe::null : selectionNames_.first());
} }