ENH: extrapolateInternal() method for patch fields

- provides a more succinct way of writing

      {fa,fv}PatchField<Type>::patchInternalField(*this)

  as well as a consistent naming that can be used for patches derived
  from valuePointPatchField

ENH: readGradientEntry helper method for fixedGradient conditions

- simplifies coding and logic.
- support different read construct modes for fixedGradient
This commit is contained in:
Mark Olesen
2023-06-16 14:25:12 +02:00
parent e54ead28e8
commit fc86e52451
39 changed files with 269 additions and 116 deletions

View File

@ -47,7 +47,7 @@ tractionDisplacementFvPatchVectorField
traction_(p.size(), Zero), traction_(p.size(), Zero),
pressure_(p.size(), Zero) pressure_(p.size(), Zero)
{ {
fvPatchField<vector>::patchInternalField(*this); extrapolateInternal();
gradient() = Zero; gradient() = Zero;
} }
@ -79,7 +79,7 @@ tractionDisplacementFvPatchVectorField
traction_("traction", dict, p.size()), traction_("traction", dict, p.size()),
pressure_("pressure", dict, p.size()) pressure_("pressure", dict, p.size())
{ {
fvPatchField<vector>::patchInternalField(*this); extrapolateInternal();
gradient() = Zero; gradient() = Zero;
} }

View File

@ -47,7 +47,7 @@ tractionDisplacementCorrectionFvPatchVectorField
traction_(p.size(), Zero), traction_(p.size(), Zero),
pressure_(p.size(), Zero) pressure_(p.size(), Zero)
{ {
fvPatchField<vector>::patchInternalField(*this); extrapolateInternal();
gradient() = Zero; gradient() = Zero;
} }
@ -79,7 +79,7 @@ tractionDisplacementCorrectionFvPatchVectorField
traction_("traction", dict, p.size()), traction_("traction", dict, p.size()),
pressure_("pressure", dict, p.size()) pressure_("pressure", dict, p.size())
{ {
fvPatchField<vector>::patchInternalField(*this); extrapolateInternal();
gradient() = Zero; gradient() = Zero;
} }

View File

@ -125,10 +125,10 @@ ${typeName}FixedValuePointPatch${FieldType}
const pointPatch& p, const pointPatch& p,
const DimensionedField<${TemplateType}, pointMesh>& iF, const DimensionedField<${TemplateType}, pointMesh>& iF,
const dictionary& dict, const dictionary& dict,
const bool valueRequired IOobjectOption::readOption requireValue
) )
: :
parent_bctype(p, iF, dict, valueRequired) parent_bctype(p, iF, dict, requireValue)
{ {
if (${verbose:-false}) if (${verbose:-false})
{ {

View File

@ -89,8 +89,8 @@ public:
( (
const pointPatch&, const pointPatch&,
const DimensionedField<${TemplateType}, pointMesh>&, const DimensionedField<${TemplateType}, pointMesh>&,
const dictionary&, const dictionary& dict,
const bool valueRequired=true IOobjectOption::readOption requireValue = IOobjectOption::MUST_READ
); );
//- Construct by mapping a copy onto a new patch //- Construct by mapping a copy onto a new patch

View File

@ -62,6 +62,23 @@ bool Foam::valuePointPatchField<Type>::readValueEntry
} }
template<class Type>
void Foam::valuePointPatchField<Type>::extrapolateInternal()
{
const labelUList& meshPoints = pointPatchFieldBase::patch().meshPoints();
const Field<Type>& iF = this->primitiveField();
Field<Type>& pfld = *this;
pfld.resize_nocopy(meshPoints.size()); // In general this is a no-op
forAll(meshPoints, i)
{
pfld[i] = iF[meshPoints[i]];
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class Type> template<class Type>

View File

@ -74,6 +74,9 @@ protected:
Field<Type>::writeEntry("value", os); Field<Type>::writeEntry("value", os);
} }
//- Assign the patch field from the internal field
void extrapolateInternal();
public: public:

View File

@ -106,15 +106,9 @@ atmTurbulentHeatFluxTemperatureFvPatchScalarField
Cp0_(Function1<scalar>::New("Cp0", dict, &db())), Cp0_(Function1<scalar>::New("Cp0", dict, &db())),
q_(PatchFunction1<scalar>::New(p.patch(), "q", dict)) q_(PatchFunction1<scalar>::New(p.patch(), "q", dict))
{ {
const auto* hasGrad = dict.findEntry("gradient", keyType::LITERAL); if (!this->readGradientEntry(dict) || !this->readValueEntry(dict))
if (hasGrad && this->readValueEntry(dict))
{ {
gradient().assign(*hasGrad, p.size()); extrapolateInternal();
}
else
{
fvPatchField<scalar>::patchInternalField(*this);
gradient() = Zero; gradient() = Zero;
} }
} }

View File

@ -48,10 +48,10 @@ Foam::calculatedFaPatchField<Type>::calculatedFaPatchField
const faPatch& p, const faPatch& p,
const DimensionedField<Type, areaMesh>& iF, const DimensionedField<Type, areaMesh>& iF,
const dictionary& dict, const dictionary& dict,
IOobjectOption::readOption valueRequired IOobjectOption::readOption requireValue
) )
: :
faPatchField<Type>(p, iF, dict, valueRequired) faPatchField<Type>(p, iF, dict, requireValue)
{} {}

View File

@ -79,7 +79,7 @@ public:
const DimensionedField<Type, areaMesh>&, const DimensionedField<Type, areaMesh>&,
const dictionary& dict, const dictionary& dict,
//! The "value" entry (default: optional) //! The "value" entry (default: optional)
IOobjectOption::readOption valueRequired = IOobjectOption::LAZY_READ IOobjectOption::readOption requireValue = IOobjectOption::LAZY_READ
); );
//- Construct by mapping given patch field onto a new patch //- Construct by mapping given patch field onto a new patch

View File

@ -74,11 +74,11 @@ Foam::coupledFaPatchField<Type>::coupledFaPatchField
const faPatch& p, const faPatch& p,
const DimensionedField<Type, areaMesh>& iF, const DimensionedField<Type, areaMesh>& iF,
const dictionary& dict, const dictionary& dict,
IOobjectOption::readOption valueRequired IOobjectOption::readOption requireValue
) )
: :
lduInterfaceField(refCast<const lduInterface>(p, dict)), lduInterfaceField(refCast<const lduInterface>(p, dict)),
faPatchField<Type>(p, iF, dict, valueRequired) faPatchField<Type>(p, iF, dict, requireValue)
{} {}

View File

@ -90,7 +90,7 @@ public:
const DimensionedField<Type, areaMesh>&, const DimensionedField<Type, areaMesh>&,
const dictionary& dict, const dictionary& dict,
//! The "value" entry (default: mandatory) //! The "value" entry (default: mandatory)
IOobjectOption::readOption valueRequired = IOobjectOption::MUST_READ IOobjectOption::readOption requireValue = IOobjectOption::MUST_READ
); );
//- Construct by mapping the given coupledFaPatchField onto a new patch //- Construct by mapping the given coupledFaPatchField onto a new patch

View File

@ -54,8 +54,7 @@ extrapolatedCalculatedFaPatchField
: :
calculatedFaPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ) calculatedFaPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ)
{ {
// Set to the internal field faPatchField<Type>::extrapolateInternal(); // Zero-gradient patch values
faPatchField<Type>::patchInternalField(*this);
} }
@ -109,8 +108,7 @@ void Foam::extrapolatedCalculatedFaPatchField<Type>::evaluate
this->updateCoeffs(); this->updateCoeffs();
} }
// Set to the internal field faPatchField<Type>::extrapolateInternal(); // Zero-gradient patch values
faPatchField<Type>::patchInternalField(*this);
calculatedFaPatchField<Type>::evaluate(); calculatedFaPatchField<Type>::evaluate();
} }

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,6 +29,39 @@ License
#include "fixedGradientFaPatchField.H" #include "fixedGradientFaPatchField.H"
#include "dictionary.H" #include "dictionary.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type>
bool Foam::fixedGradientFaPatchField<Type>::readGradientEntry
(
const dictionary& dict,
IOobjectOption::readOption readOpt
)
{
if (!IOobjectOption::isAnyRead(readOpt)) return false;
const auto& p = faPatchFieldBase::patch();
const auto* eptr = dict.findEntry("gradient", keyType::LITERAL);
if (eptr)
{
gradient_.assign(*eptr, p.size());
return true;
}
if (IOobjectOption::isReadRequired(readOpt))
{
FatalIOErrorInFunction(dict)
<< "Required entry 'gradient' : missing for patch " << p.name()
<< " in dictionary " << dict.relativeName() << nl
<< exit(FatalIOError);
}
return false;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
@ -42,6 +76,32 @@ Foam::fixedGradientFaPatchField<Type>::fixedGradientFaPatchField
{} {}
template<class Type>
Foam::fixedGradientFaPatchField<Type>::fixedGradientFaPatchField
(
const faPatch& p,
const DimensionedField<Type, areaMesh>& iF,
const dictionary& dict,
IOobjectOption::readOption requireGrad
)
:
faPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ),
gradient_(p.size())
{
if (readGradientEntry(dict, requireGrad))
{
evaluate();
}
else
{
// Not read (eg, optional and missing):
// - treat as zero-gradient, do not evaluate
faPatchField<Type>::extrapolateInternal();
gradient_ = Zero;
}
}
template<class Type> template<class Type>
Foam::fixedGradientFaPatchField<Type>::fixedGradientFaPatchField Foam::fixedGradientFaPatchField<Type>::fixedGradientFaPatchField
( (
@ -56,21 +116,6 @@ Foam::fixedGradientFaPatchField<Type>::fixedGradientFaPatchField
{} {}
template<class Type>
Foam::fixedGradientFaPatchField<Type>::fixedGradientFaPatchField
(
const faPatch& p,
const DimensionedField<Type, areaMesh>& iF,
const dictionary& dict
)
:
faPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ),
gradient_("gradient", dict, p.size())
{
evaluate();
}
template<class Type> template<class Type>
Foam::fixedGradientFaPatchField<Type>::fixedGradientFaPatchField Foam::fixedGradientFaPatchField<Type>::fixedGradientFaPatchField
( (

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -27,6 +28,35 @@ Class
Foam::fixedGradientFaPatchField Foam::fixedGradientFaPatchField
Description Description
This boundary condition supplies a fixed gradient condition, such that
the patch values are calculated using:
\f[
x_p = x_c + \frac{\nabla(x)}{\Delta}
\f]
where
\vartable
x_p | patch values
x_c | internal field values
\nabla(x)| gradient (user-specified)
\Delta | inverse distance from patch face centre to cell centre
\endvartable
Usage
\table
Property | Description | Required | Default value
gradient | gradient | yes |
\endtable
Example of the boundary condition specification:
\verbatim
<patchName>
{
type fixedGradient;
gradient uniform 0;
}
\endverbatim
Author Author
Zeljko Tukovic, FMENA Zeljko Tukovic, FMENA
@ -37,8 +67,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef fixedGradientFaPatchField_H #ifndef Foam_fixedGradientFaPatchField_H
#define fixedGradientFaPatchField_H #define Foam_fixedGradientFaPatchField_H
#include "faPatchField.H" #include "faPatchField.H"
@ -56,10 +86,22 @@ class fixedGradientFaPatchField
: :
public faPatchField<Type> public faPatchField<Type>
{ {
// Private data // Private Data
Field<Type> gradient_; Field<Type> gradient_;
protected:
// Protected Member Functions
//- Read the "gradient" entry into corresponding member
// The reading can be optional (default), mandatory etc.
// \returns True on success
bool readGradientEntry
(
const dictionary& dict,
IOobjectOption::readOption readOpt = IOobjectOption::LAZY_READ
);
public: public:
@ -76,12 +118,14 @@ public:
const DimensionedField<Type, areaMesh>& const DimensionedField<Type, areaMesh>&
); );
//- Construct from patch, internal field and dictionary //- Construct from patch, internal field and dictionary.
fixedGradientFaPatchField fixedGradientFaPatchField
( (
const faPatch&, const faPatch&,
const DimensionedField<Type, areaMesh>&, const DimensionedField<Type, areaMesh>&,
const dictionary& const dictionary& dict,
//! The "gradient" entry (default: mandatory)
IOobjectOption::readOption requireGrad = IOobjectOption::MUST_READ
); );
//- Construct by mapping the given fixedGradient patch field //- Construct by mapping the given fixedGradient patch field

View File

@ -58,10 +58,10 @@ Foam::fixedValueFaPatchField<Type>::fixedValueFaPatchField
const faPatch& p, const faPatch& p,
const DimensionedField<Type, areaMesh>& iF, const DimensionedField<Type, areaMesh>& iF,
const dictionary& dict, const dictionary& dict,
IOobjectOption::readOption valueRequired IOobjectOption::readOption requireValue
) )
: :
faPatchField<Type>(p, iF, dict, valueRequired) faPatchField<Type>(p, iF, dict, requireValue)
{} {}

View File

@ -87,7 +87,7 @@ public:
const DimensionedField<Type, areaMesh>&, const DimensionedField<Type, areaMesh>&,
const dictionary&, const dictionary&,
//! The "value" entry (default: mandatory) //! The "value" entry (default: mandatory)
IOobjectOption::readOption valueRequired = IOobjectOption::MUST_READ IOobjectOption::readOption requireValue = IOobjectOption::MUST_READ
); );
//- Construct by mapping the given fixedValue patch field //- Construct by mapping the given fixedValue patch field

View File

@ -64,8 +64,7 @@ Foam::zeroGradientFaPatchField<Type>::zeroGradientFaPatchField
: :
faPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ) faPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ)
{ {
// Set to the internal field faPatchField<Type>::extrapolateInternal(); // Zero-gradient patch values
faPatchField<Type>::patchInternalField(*this);
} }
@ -100,8 +99,7 @@ void Foam::zeroGradientFaPatchField<Type>::evaluate(const Pstream::commsTypes)
this->updateCoeffs(); this->updateCoeffs();
} }
// Set to the internal field faPatchField<Type>::extrapolateInternal(); // Zero-gradient patch values
faPatchField<Type>::patchInternalField(*this);
faPatchField<Type>::evaluate(); faPatchField<Type>::evaluate();
} }

View File

@ -73,7 +73,7 @@ Foam::cyclicFaPatchField<Type>::cyclicFaPatchField
const faPatch& p, const faPatch& p,
const DimensionedField<Type, areaMesh>& iF, const DimensionedField<Type, areaMesh>& iF,
const dictionary& dict, const dictionary& dict,
IOobjectOption::readOption valueRequired IOobjectOption::readOption requireValue
) )
: :
coupledFaPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ), coupledFaPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ),
@ -90,7 +90,7 @@ Foam::cyclicFaPatchField<Type>::cyclicFaPatchField
<< exit(FatalIOError); << exit(FatalIOError);
} }
if (IOobjectOption::isReadRequired(valueRequired)) if (IOobjectOption::isReadRequired(requireValue))
{ {
this->evaluate(Pstream::commsTypes::blocking); this->evaluate(Pstream::commsTypes::blocking);
} }

View File

@ -100,7 +100,7 @@ public:
const DimensionedField<Type, areaMesh>&, const DimensionedField<Type, areaMesh>&,
const dictionary& dict, const dictionary& dict,
//! Evaluate (default: mandatory) //! Evaluate (default: mandatory)
IOobjectOption::readOption valueRequired = IOobjectOption::MUST_READ IOobjectOption::readOption requireValue = IOobjectOption::MUST_READ
); );
//- Construct by mapping given cyclicFaPatchField onto a new patch //- Construct by mapping given cyclicFaPatchField onto a new patch

View File

@ -63,6 +63,13 @@ bool Foam::faPatchField<Type>::readValueEntry
} }
template<class Type>
void Foam::faPatchField<Type>::extrapolateInternal()
{
faPatchFieldBase::patch().patchInternalField(internalField_, *this);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type> template<class Type>

View File

@ -273,6 +273,9 @@ protected:
Field<Type>::writeEntry("value", os); Field<Type>::writeEntry("value", os);
} }
//- Assign the patch field from the internal field
void extrapolateInternal();
public: public:

View File

@ -61,10 +61,10 @@ Foam::calculatedFaePatchField<Type>::calculatedFaePatchField
const faPatch& p, const faPatch& p,
const DimensionedField<Type, edgeMesh>& iF, const DimensionedField<Type, edgeMesh>& iF,
const dictionary& dict, const dictionary& dict,
IOobjectOption::readOption valueRequired IOobjectOption::readOption requireValue
) )
: :
faePatchField<Type>(p, iF, dict, valueRequired) faePatchField<Type>(p, iF, dict, requireValue)
{} {}

View File

@ -79,7 +79,7 @@ public:
const DimensionedField<Type, edgeMesh>&, const DimensionedField<Type, edgeMesh>&,
const dictionary& dict, const dictionary& dict,
//! The "value" entry (default: mandatory) //! The "value" entry (default: mandatory)
IOobjectOption::readOption valueRequired = IOobjectOption::MUST_READ IOobjectOption::readOption requireValue = IOobjectOption::MUST_READ
); );
//- Construct by mapping given patch field onto a new patch //- Construct by mapping given patch field onto a new patch

View File

@ -71,10 +71,10 @@ Foam::coupledFaePatchField<Type>::coupledFaePatchField
const faPatch& p, const faPatch& p,
const DimensionedField<Type, edgeMesh>& iF, const DimensionedField<Type, edgeMesh>& iF,
const dictionary& dict, const dictionary& dict,
IOobjectOption::readOption valueRequired IOobjectOption::readOption requireValue
) )
: :
faePatchField<Type>(p, iF, dict, valueRequired) faePatchField<Type>(p, iF, dict, requireValue)
{} {}

View File

@ -88,7 +88,7 @@ public:
const DimensionedField<Type, edgeMesh>&, const DimensionedField<Type, edgeMesh>&,
const dictionary& dict, const dictionary& dict,
//! The "value" entry (default: optional) //! The "value" entry (default: optional)
IOobjectOption::readOption valueRequired = IOobjectOption::LAZY_READ IOobjectOption::readOption requireValue = IOobjectOption::LAZY_READ
); );
//- Construct by mapping the given coupledFaePatchField onto a new patch //- Construct by mapping the given coupledFaePatchField onto a new patch

View File

@ -59,10 +59,10 @@ Foam::fixedValueFaePatchField<Type>::fixedValueFaePatchField
const faPatch& p, const faPatch& p,
const DimensionedField<Type, edgeMesh>& iF, const DimensionedField<Type, edgeMesh>& iF,
const dictionary& dict, const dictionary& dict,
IOobjectOption::readOption valueRequired IOobjectOption::readOption requireValue
) )
: :
faePatchField<Type>(p, iF, dict, valueRequired) faePatchField<Type>(p, iF, dict, requireValue)
{} {}

View File

@ -87,7 +87,7 @@ public:
const DimensionedField<Type, edgeMesh>&, const DimensionedField<Type, edgeMesh>&,
const dictionary& dict, const dictionary& dict,
//! The "value" entry (default: mandatory) //! The "value" entry (default: mandatory)
IOobjectOption::readOption valueRequired = IOobjectOption::MUST_READ IOobjectOption::readOption requireValue = IOobjectOption::MUST_READ
); );
//- Construct by mapping the given fixedValue patch field //- Construct by mapping the given fixedValue patch field

View File

@ -82,7 +82,7 @@ Foam::exprFixedValueFvPatchField<Type>::exprFixedValueFvPatchField
const fvPatch& p, const fvPatch& p,
const DimensionedField<Type, volMesh>& iF, const DimensionedField<Type, volMesh>& iF,
const dictionary& dict, const dictionary& dict,
const bool valueRequired IOobjectOption::readOption requireValue // (ignored)
) )
: :
parent_bctype(p, iF), // bypass dictionary constructor parent_bctype(p, iF), // bypass dictionary constructor

View File

@ -110,7 +110,7 @@ public:
const fvPatch&, const fvPatch&,
const DimensionedField<Type, volMesh>&, const DimensionedField<Type, volMesh>&,
const dictionary& dict, const dictionary& dict,
const bool valueRequired=true IOobjectOption::readOption requireValue = IOobjectOption::MUST_READ
); );
//- Construct by mapping onto a new patch //- Construct by mapping onto a new patch

View File

@ -54,8 +54,7 @@ extrapolatedCalculatedFvPatchField
: :
calculatedFvPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ) calculatedFvPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ)
{ {
// Set to the internal field fvPatchField<Type>::extrapolateInternal(); // Zero-gradient patch values
fvPatchField<Type>::patchInternalField(*this);
} }
@ -109,8 +108,7 @@ void Foam::extrapolatedCalculatedFvPatchField<Type>::evaluate
this->updateCoeffs(); this->updateCoeffs();
} }
// Set to the internal field fvPatchField<Type>::extrapolateInternal(); // Zero-gradient patch values
fvPatchField<Type>::patchInternalField(*this);
calculatedFvPatchField<Type>::evaluate(); calculatedFvPatchField<Type>::evaluate();
} }

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -28,6 +29,39 @@ License
#include "fixedGradientFvPatchField.H" #include "fixedGradientFvPatchField.H"
#include "dictionary.H" #include "dictionary.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
template<class Type>
bool Foam::fixedGradientFvPatchField<Type>::readGradientEntry
(
const dictionary& dict,
IOobjectOption::readOption readOpt
)
{
if (!IOobjectOption::isAnyRead(readOpt)) return false;
const auto& p = fvPatchFieldBase::patch();
const auto* eptr = dict.findEntry("gradient", keyType::LITERAL);
if (eptr)
{
gradient_.assign(*eptr, p.size());
return true;
}
if (IOobjectOption::isReadRequired(readOpt))
{
FatalIOErrorInFunction(dict)
<< "Required entry 'gradient' : missing for patch " << p.name()
<< " in dictionary " << dict.relativeName() << nl
<< exit(FatalIOError);
}
return false;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
@ -47,13 +81,24 @@ Foam::fixedGradientFvPatchField<Type>::fixedGradientFvPatchField
( (
const fvPatch& p, const fvPatch& p,
const DimensionedField<Type, volMesh>& iF, const DimensionedField<Type, volMesh>& iF,
const dictionary& dict const dictionary& dict,
IOobjectOption::readOption requireGrad
) )
: :
fvPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ), fvPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ),
gradient_("gradient", dict, p.size()) gradient_(p.size())
{ {
evaluate(); if (readGradientEntry(dict, requireGrad))
{
evaluate();
}
else
{
// Not read (eg, optional and missing):
// - treat as zero-gradient, do not evaluate
fvPatchField<Type>::extrapolateInternal();
gradient_ = Zero;
}
} }

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -65,8 +66,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef fixedGradientFvPatchField_H #ifndef Foam_fixedGradientFvPatchField_H
#define fixedGradientFvPatchField_H #define Foam_fixedGradientFvPatchField_H
#include "fvPatchField.H" #include "fvPatchField.H"
@ -84,10 +85,22 @@ class fixedGradientFvPatchField
: :
public fvPatchField<Type> public fvPatchField<Type>
{ {
// Private data // Private Data
Field<Type> gradient_; Field<Type> gradient_;
protected:
// Protected Member Functions
//- Read the "gradient" entry into corresponding member
// The reading can be optional (default), mandatory etc.
// \returns True on success
bool readGradientEntry
(
const dictionary& dict,
IOobjectOption::readOption readOpt = IOobjectOption::LAZY_READ
);
public: public:
@ -104,12 +117,14 @@ public:
const DimensionedField<Type, volMesh>& const DimensionedField<Type, volMesh>&
); );
//- Construct from patch, internal field and dictionary //- Construct from patch, internal field and dictionary.
fixedGradientFvPatchField fixedGradientFvPatchField
( (
const fvPatch&, const fvPatch&,
const DimensionedField<Type, volMesh>&, const DimensionedField<Type, volMesh>&,
const dictionary& const dictionary& dict,
//! The "gradient" entry (default: mandatory)
IOobjectOption::readOption requireGrad = IOobjectOption::MUST_READ
); );
//- Construct by mapping the given fixedGradientFvPatchField //- Construct by mapping the given fixedGradientFvPatchField

View File

@ -6,6 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2023 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -51,8 +52,7 @@ Foam::zeroGradientFvPatchField<Type>::zeroGradientFvPatchField
: :
fvPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ) fvPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ)
{ {
// Set to the internal field fvPatchField<Type>::extrapolateInternal(); // Zero-gradient patch values
fvPatchField<Type>::patchInternalField(*this);
} }
@ -100,8 +100,7 @@ void Foam::zeroGradientFvPatchField<Type>::evaluate(const Pstream::commsTypes)
this->updateCoeffs(); this->updateCoeffs();
} }
// Set to the internal field fvPatchField<Type>::extrapolateInternal(); // Zero-gradient patch values
fvPatchField<Type>::patchInternalField(*this);
fvPatchField<Type>::evaluate(); fvPatchField<Type>::evaluate();
} }

View File

@ -57,15 +57,9 @@ Foam::fixedFluxPressureFvPatchScalarField::fixedFluxPressureFvPatchScalarField
{ {
fvPatchFieldBase::readDict(dict); fvPatchFieldBase::readDict(dict);
const auto* hasGrad = dict.findEntry("gradient", keyType::LITERAL); if (!this->readGradientEntry(dict) || !this->readValueEntry(dict))
if (hasGrad && this->readValueEntry(dict))
{ {
gradient().assign(*hasGrad, p.size()); extrapolateInternal();
}
else
{
fvPatchField<scalar>::patchInternalField(*this);
gradient() = Zero; gradient() = Zero;
} }
} }
@ -85,7 +79,7 @@ Foam::fixedFluxPressureFvPatchScalarField::fixedFluxPressureFvPatchScalarField
patchType() = ptf.patchType(); patchType() = ptf.patchType();
// Map gradient. Set unmapped values and overwrite with mapped ptf // Map gradient. Set unmapped values and overwrite with mapped ptf
gradient() = 0.0; gradient() = Zero;
gradient().map(ptf.gradient(), mapper); gradient().map(ptf.gradient(), mapper);
// Evaluate the value field from the gradient if the internal field is valid // Evaluate the value field from the gradient if the internal field is valid

View File

@ -65,6 +65,13 @@ bool Foam::fvPatchField<Type>::readValueEntry
} }
template<class Type>
void Foam::fvPatchField<Type>::extrapolateInternal()
{
fvPatchFieldBase::patch().patchInternalField(internalField_, *this);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type> template<class Type>

View File

@ -302,6 +302,9 @@ protected:
Field<Type>::writeEntry("value", os); Field<Type>::writeEntry("value", os);
} }
//- Assign the patch field from the internal field
void extrapolateInternal();
public: public:

View File

@ -77,16 +77,9 @@ fixedIncidentRadiationFvPatchScalarField
temperatureCoupledBase(patch(), dict), temperatureCoupledBase(patch(), dict),
qrIncident_("qrIncident", dict, p.size()) qrIncident_("qrIncident", dict, p.size())
{ {
const auto* hasGrad = dict.findEntry("gradient", keyType::LITERAL); if (!this->readGradientEntry(dict) || !this->readValueEntry(dict))
if (hasGrad && this->readValueEntry(dict))
{ {
gradient().assign(*hasGrad, p.size()); extrapolateInternal();
}
else
{
// Still reading so cannot yet evaluate. Make up a value.
fvPatchField<scalar>::patchInternalField(*this);
gradient() = Zero; gradient() = Zero;
} }
} }

View File

@ -303,16 +303,9 @@ sorptionWallFunctionFvPatchScalarField::sorptionWallFunctionFvPatchScalarField
<< exit(FatalIOError); << exit(FatalIOError);
} }
const auto* hasGrad = dict.findEntry("gradient", keyType::LITERAL); if (!this->readGradientEntry(dict) || !this->readValueEntry(dict))
if (hasGrad && this->readValueEntry(dict))
{ {
gradient().assign(*hasGrad, p.size()); extrapolateInternal();
}
else
{
// Fallback: set to zero-gradient
fvPatchField<scalar>::patchInternalField(*this);
gradient() = Zero; gradient() = Zero;
} }
} }

View File

@ -70,18 +70,15 @@ alphaContactAngleTwoPhaseFvPatchScalarField
fixedGradientFvPatchScalarField(p, iF), // Bypass dictionary constructor fixedGradientFvPatchScalarField(p, iF), // Bypass dictionary constructor
limit_(limitControlNames_.get("limit", dict)) limit_(limitControlNames_.get("limit", dict))
{ {
const auto* hasGrad = dict.findEntry("gradient", keyType::LITERAL); if (this->readGradientEntry(dict))
if (hasGrad)
{ {
gradient().assign(*hasGrad, p.size());
fixedGradientFvPatchScalarField::updateCoeffs(); fixedGradientFvPatchScalarField::updateCoeffs();
fixedGradientFvPatchScalarField::evaluate(); fixedGradientFvPatchScalarField::evaluate();
} }
else else
{ {
// Fallback: set to zero-gradient // Fallback: set to zero-gradient
fvPatchField<scalar>::patchInternalField(*this); extrapolateInternal();
gradient() = Zero; gradient() = Zero;
} }
} }
@ -142,7 +139,7 @@ void Foam::alphaContactAngleTwoPhaseFvPatchScalarField::evaluate
} }
else if (limit_ == lcZeroGradient) else if (limit_ == lcZeroGradient)
{ {
gradient() = 0.0; gradient() = Zero;
} }
fixedGradientFvPatchScalarField::evaluate(); fixedGradientFvPatchScalarField::evaluate();