diff --git a/src/finiteArea/fields/faPatchFields/basic/basicSymmetry/basicSymmetryFaPatchField.C b/src/finiteArea/fields/faPatchFields/basic/basicSymmetry/basicSymmetryFaPatchField.C index 3cf2d45348..29050a1573 100644 --- a/src/finiteArea/fields/faPatchFields/basic/basicSymmetry/basicSymmetryFaPatchField.C +++ b/src/finiteArea/fields/faPatchFields/basic/basicSymmetry/basicSymmetryFaPatchField.C @@ -82,6 +82,41 @@ Foam::basicSymmetryFaPatchField::basicSymmetryFaPatchField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template +void Foam::basicSymmetryFaPatchField::snGrad(UList& result) const +{ + if constexpr (!is_rotational_vectorspace_v) + { + // Rotational-invariant type : treat like zero-gradient + result = Foam::zero{}; + } + else + { + // Get patch internal field, stored temporarily in result + this->patchInternalField(result); + const auto& pif = result; + + tmp tnHat = this->patch().edgeNormals(); + const auto& nHat = tnHat(); + + const auto& dc = this->patch().deltaCoeffs(); + + const label len = result.size(); + + // (dc/2.0)*(transform(I - 2.0*sqr(nHat), iF) - iF); + + for (label i = 0; i < len; ++i) + { + result[i] = + ( + (0.5*dc[i]) + * (transform(I - 2.0*sqr(nHat[i]), pif[i]) - pif[i]) + ); + } + } +} + + template Foam::tmp> Foam::basicSymmetryFaPatchField::snGrad() const @@ -93,17 +128,9 @@ Foam::basicSymmetryFaPatchField::snGrad() const } else { - tmp nHat = this->patch().edgeNormals(); - - const auto& dc = this->patch().deltaCoeffs(); - - const Field pif(this->patchInternalField()); - - return - ( - (0.5*dc) - * (transform(I - 2.0*sqr(nHat), pif) - pif) - ); + auto tresult = tmp>::New(this->size()); + this->snGrad(static_cast&>(tresult.ref())); + return tresult; } } diff --git a/src/finiteArea/fields/faPatchFields/basic/basicSymmetry/basicSymmetryFaPatchField.H b/src/finiteArea/fields/faPatchFields/basic/basicSymmetry/basicSymmetryFaPatchField.H index 417d21a445..bd61135c50 100644 --- a/src/finiteArea/fields/faPatchFields/basic/basicSymmetry/basicSymmetryFaPatchField.H +++ b/src/finiteArea/fields/faPatchFields/basic/basicSymmetry/basicSymmetryFaPatchField.H @@ -119,21 +119,20 @@ public: // Member Functions - // Evaluation functions + //- Retrieve patch-normal gradient at boundary + virtual tmp> snGrad() const; - //- Return gradient at boundary - virtual tmp> snGrad() const; + //- Retrieve patch-normal gradient at boundary + virtual void snGrad(UList& result) const; - //- Evaluate the patch field - // Default argument needed to allow call in constructors - // HJ, 30/Jun/2009 - virtual void evaluate - ( - const Pstream::commsTypes commsType = Pstream::commsTypes::buffered - ); + //- Evaluate the patch field + virtual void evaluate + ( + const Pstream::commsTypes commsType = Pstream::commsTypes::buffered + ); - //- Return face-gradient transform diagonal - virtual tmp> snGradTransformDiag() const; + //- Return face-gradient transform diagonal + virtual tmp> snGradTransformDiag() const; // Member Operators diff --git a/src/finiteArea/fields/faPatchFields/basic/coupled/coupledFaPatchField.C b/src/finiteArea/fields/faPatchFields/basic/coupled/coupledFaPatchField.C index b0e5f2a93a..4a3fd13b88 100644 --- a/src/finiteArea/fields/faPatchFields/basic/coupled/coupledFaPatchField.C +++ b/src/finiteArea/fields/faPatchFields/basic/coupled/coupledFaPatchField.C @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd + Copyright (C) 2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -107,12 +108,40 @@ Foam::coupledFaPatchField::coupledFaPatchField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template +void Foam::coupledFaPatchField::snGrad +( + UList& result +) const +{ + // Get patch neighbour field, store temporarily in result + this->patchNeighbourField(result); + const auto& pnf = result; + + // Same as patchInternalField(...), assuming edgeFaces are an indirection + // into internal field, but without additional storage... + const auto& addr = this->patch().edgeFaces(); + const auto& iF = this->primitiveField(); + + const auto& deltaCoeffs = this->patch().deltaCoeffs(); + + // snGrad = deltaCoeffs * (patchNeighbourField - patchInternalField) + + const label len = result.size(); + + for (label i = 0; i < len; ++i) + { + result[i] = deltaCoeffs[i]*(pnf[i] - iF[addr[i]]); + } +} + + template Foam::tmp> Foam::coupledFaPatchField::snGrad() const { - return - (patchNeighbourField() - this->patchInternalField()) - *this->patch().deltaCoeffs(); + auto tresult = tmp>::New(this->size()); + this->snGrad(static_cast&>(tresult.ref())); + return tresult; } diff --git a/src/finiteArea/fields/faPatchFields/basic/coupled/coupledFaPatchField.H b/src/finiteArea/fields/faPatchFields/basic/coupled/coupledFaPatchField.H index 0449a8e60e..17263b4778 100644 --- a/src/finiteArea/fields/faPatchFields/basic/coupled/coupledFaPatchField.H +++ b/src/finiteArea/fields/faPatchFields/basic/coupled/coupledFaPatchField.H @@ -148,6 +148,9 @@ public: //- Return patch-normal gradient virtual tmp> snGrad() const; + //- Retrieve patch-normal gradient + virtual void snGrad(UList& result) const; + //- Initialise the evaluation of the patch field virtual void initEvaluate ( diff --git a/src/finiteArea/fields/faPatchFields/basic/zeroGradient/zeroGradientFaPatchField.H b/src/finiteArea/fields/faPatchFields/basic/zeroGradient/zeroGradientFaPatchField.H index 298fd742fc..df5c5c26a2 100644 --- a/src/finiteArea/fields/faPatchFields/basic/zeroGradient/zeroGradientFaPatchField.H +++ b/src/finiteArea/fields/faPatchFields/basic/zeroGradient/zeroGradientFaPatchField.H @@ -119,14 +119,22 @@ public: } - // Member functions + // Member Functions - // Evaluation functions + // Evaluation Functions - //- Return gradient at boundary + //- Return patch-normal gradient virtual tmp> snGrad() const { - return tmp>::New(this->size(), Zero); + // zero-gradient + return tmp>::New(this->size(), Foam::zero{}); + } + + //- Retrieve patch-normal gradient [contiguous storage] + virtual void snGrad(UList& result) const + { + // zero-gradient + result = Foam::zero{}; } //- Evaluate the patch field @@ -137,25 +145,25 @@ public: ); //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the value of this patchField with given weights + //- evaluation of the value of this patchField with given weights virtual tmp> valueInternalCoeffs ( const tmp& ) const; //- Return the matrix source coefficients corresponding to the - // evaluation of the value of this patchField with given weights + //- evaluation of the value of this patchField with given weights virtual tmp> valueBoundaryCoeffs ( const tmp& ) const; //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField virtual tmp> gradientInternalCoeffs() const; //- Return the matrix source coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField virtual tmp> gradientBoundaryCoeffs() const; }; diff --git a/src/finiteArea/fields/faPatchFields/constraint/empty/emptyFaPatchField.H b/src/finiteArea/fields/faPatchFields/constraint/empty/emptyFaPatchField.H index cd7d1febbe..726c545962 100644 --- a/src/finiteArea/fields/faPatchFields/constraint/empty/emptyFaPatchField.H +++ b/src/finiteArea/fields/faPatchFields/constraint/empty/emptyFaPatchField.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 Wikki Ltd - Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -125,7 +125,7 @@ public: virtual ~emptyFaPatchField() = default; - // Member functions + // Member Functions // Mapping functions @@ -145,7 +145,7 @@ public: {} - // Evaluation functions + // Evaluation Functions //- Update the coefficients associated with the patch field // This only checks to see the case is actually 1D or 2D @@ -154,7 +154,7 @@ public: //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the value of this patchField with given weights + //- evaluation of the value of this patchField with given weights virtual tmp> valueInternalCoeffs ( const tmp& @@ -164,7 +164,7 @@ public: } //- Return the matrix source coefficients corresponding to the - // evaluation of the value of this patchField with given weights + //- evaluation of the value of this patchField with given weights virtual tmp> valueBoundaryCoeffs ( const tmp& @@ -174,20 +174,31 @@ public: } //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField tmp> gradientInternalCoeffs() const { return tmp>::New(); } //- Return the matrix source coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField tmp> gradientBoundaryCoeffs() const { return tmp>::New(); } + // Contiguous storage + + //- Retrieve patch-normal gradient [contiguous storage]. + //- Placeholder value is zero (treated like zero-gradient). + virtual void snGrad(UList& result) const + { + // Treat like zero-gradient + result = Foam::zero{}; + } + + // Member Functions //- Write without "value" entry! diff --git a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.C b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.C index ea13e88c93..995d62892c 100644 --- a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.C +++ b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.C @@ -305,9 +305,35 @@ void Foam::processorFaPatchField::evaluate } +template +void Foam::processorFaPatchField::snGrad +( + UList& result +) const +{ + // Get patch internal field, store temporarily in result + this->patchInternalField(result); + const auto& pif = result; + + const Field& pnf = *this; + const auto& deltaCoeffs = this->patch().deltaCoeffs(); + + const label len = result.size(); + + for (label i = 0; i < len; ++i) + { + result[i] = deltaCoeffs[i]*(pnf[i] - pif[i]); + } +} + + template Foam::tmp> Foam::processorFaPatchField::snGrad() const { + // OR + // auto tfld = tmp>::New(this->size()); + // this->snGrad(static_cast&>(tfld.ref())); + // return tfld; return this->patch().deltaCoeffs()*(*this - this->patchInternalField()); } diff --git a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.H b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.H index c774ead515..4d68f2402d 100644 --- a/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.H +++ b/src/finiteArea/fields/faPatchFields/constraint/processor/processorFaPatchField.H @@ -210,6 +210,9 @@ public: //- Return patch-normal gradient virtual tmp> snGrad() const; + //- Retrieve patch-normal gradient + virtual void snGrad(UList& result) const; + // Coupled interface functionality diff --git a/src/finiteArea/fields/faPatchFields/faPatchField/faPatchField.C b/src/finiteArea/fields/faPatchFields/faPatchField/faPatchField.C index d4d3a5c929..e36397628c 100644 --- a/src/finiteArea/fields/faPatchFields/faPatchField/faPatchField.C +++ b/src/finiteArea/fields/faPatchFields/faPatchField/faPatchField.C @@ -202,10 +202,31 @@ void Foam::faPatchField::check(const faPatchField& rhs) const } +template +void Foam::faPatchField::snGrad(UList& result) const +{ + // Get patch internal field, store temporarily in result + this->patchInternalField(result); + const auto& pif = result; + + const Field& pfld = *this; + const auto& dc = patch().deltaCoeffs(); + + const label len = result.size(); + + for (label i = 0; i < len; ++i) + { + result[i] = dc[i]*(pfld[i] - pif[i]); + } +} + + template Foam::tmp> Foam::faPatchField::snGrad() const { - return (*this - patchInternalField())*patch().deltaCoeffs(); + auto tfld = tmp>::New(this->size()); + this->snGrad(static_cast&>(tfld.ref())); + return tfld; } diff --git a/src/finiteArea/fields/faPatchFields/faPatchField/faPatchField.H b/src/finiteArea/fields/faPatchFields/faPatchField/faPatchField.H index de8b96c5d1..87d29fe492 100644 --- a/src/finiteArea/fields/faPatchFields/faPatchField/faPatchField.H +++ b/src/finiteArea/fields/faPatchFields/faPatchField/faPatchField.H @@ -582,6 +582,31 @@ public: //- Return patch-normal gradient virtual tmp> snGrad() const; + //- Retrieve patch-normal gradient [contiguous storage] + virtual void snGrad(UList& result) const; + + //- Return patch-normal gradient for coupled-patches + //- using the deltaCoeffs provided + virtual tmp> snGrad + ( + const scalarField& deltaCoeffs + ) const + { + NotImplemented; + return *this; + } + + //- Retrieve patch-normal gradient for coupled-patches + //- using the deltaCoeffs provided [contiguous storage] + virtual void snGrad + ( + const scalarField& deltaCoeffs, + UList& + ) const + { + NotImplemented; + } + //- Return internal field next to patch virtual tmp> patchInternalField() const; @@ -677,6 +702,69 @@ public: } + // Contiguous storage + + //- Retrieve the matrix diagonal coefficients corresponding to the + //- evaluation of the value of this patchField with given weights + virtual void valueInternalCoeffs + ( + const tmp>&, + UList& + ) const + { + NotImplemented; + } + + //- Retrieve the matrix source coefficients corresponding to the + //- evaluation of the value of this patchField with given weights + virtual void valueBoundaryCoeffs + ( + const tmp>&, + UList& + ) const + { + NotImplemented; + } + + //- Retrieve the matrix diagonal coefficients corresponding to the + //- evaluation of the gradient of this patchField + virtual void gradientInternalCoeffs(UList&) const + { + NotImplemented; + } + + //- Retrieve the matrix diagonal coefficients corresponding to the + //- evaluation of the gradient of this coupled patchField + //- using the deltaCoeffs provided + virtual void gradientInternalCoeffs + ( + const scalarField& deltaCoeffs, + UList& + ) const + { + NotImplemented; + } + + //- Retrieve the matrix source coefficients corresponding to the + //- evaluation of the gradient of this patchField + virtual void gradientBoundaryCoeffs(UList&) const + { + NotImplemented; + } + + //- Retrieve the matrix source coefficients corresponding to the + //- evaluation of the gradient of this coupled patchField + //- using the deltaCoeffs provided + virtual void gradientBoundaryCoeffs + ( + const scalarField& deltaCoeffs, + UList& + ) const + { + NotImplemented; + } + + // Other //- Write diff --git a/src/finiteVolume/fields/fvPatchFields/basic/basicSymmetry/basicSymmetryFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/basic/basicSymmetry/basicSymmetryFvPatchField.C index 2991ae8703..43ec2f1be2 100644 --- a/src/finiteVolume/fields/fvPatchFields/basic/basicSymmetry/basicSymmetryFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/basic/basicSymmetry/basicSymmetryFvPatchField.C @@ -82,6 +82,41 @@ Foam::basicSymmetryFvPatchField::basicSymmetryFvPatchField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template +void Foam::basicSymmetryFvPatchField::snGrad(UList& result) const +{ + if constexpr (!is_rotational_vectorspace_v) + { + // Rotational-invariant type : treat like zero-gradient + result = Foam::zero{}; + } + else + { + // Get patch internal field, stored temporarily in result + this->patchInternalField(result); + const auto& pif = result; + + tmp tnHat = this->patch().nf(); + const auto& nHat = tnHat(); + + const auto& dc = this->patch().deltaCoeffs(); + + const label len = result.size(); + + // (dc/2.0)*(transform(I - 2.0*sqr(nHat), iF) - iF); + + for (label i = 0; i < len; ++i) + { + result[i] = + ( + (0.5*dc[i]) + * (transform(I - 2.0*sqr(nHat[i]), pif[i]) - pif[i]) + ); + } + } +} + + template Foam::tmp> Foam::basicSymmetryFvPatchField::snGrad() const @@ -93,17 +128,9 @@ Foam::basicSymmetryFvPatchField::snGrad() const } else { - tmp nHat = this->patch().nf(); - - const auto& dc = this->patch().deltaCoeffs(); - - const Field pif(this->patchInternalField()); - - return - ( - (0.5*dc) - * (transform(I - 2.0*sqr(nHat), pif) - pif) - ); + auto tresult = tmp>::New(this->size()); + this->snGrad(static_cast&>(tresult.ref())); + return tresult; } } diff --git a/src/finiteVolume/fields/fvPatchFields/basic/basicSymmetry/basicSymmetryFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/basic/basicSymmetry/basicSymmetryFvPatchField.H index 0345dfd663..aea10b9341 100644 --- a/src/finiteVolume/fields/fvPatchFields/basic/basicSymmetry/basicSymmetryFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/basic/basicSymmetry/basicSymmetryFvPatchField.H @@ -119,9 +119,12 @@ public: // Member Functions - //- Return gradient at boundary + //- Retrieve patch-normal gradient at boundary virtual tmp> snGrad() const; + //- Retrieve patch-normal gradient at boundary + virtual void snGrad(UList& result) const; + //- Evaluate the patch field virtual void evaluate ( diff --git a/src/finiteVolume/fields/fvPatchFields/basic/coupled/coupledFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/basic/coupled/coupledFvPatchField.C index 5fb74b5480..8b0ad9ec8d 100644 --- a/src/finiteVolume/fields/fvPatchFields/basic/coupled/coupledFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/basic/coupled/coupledFvPatchField.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2023 OpenCFD Ltd. + Copyright (C) 2023-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -108,15 +108,42 @@ Foam::coupledFvPatchField::coupledFvPatchField // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // +template +void Foam::coupledFvPatchField::snGrad +( + const scalarField& deltaCoeffs, + UList& result +) const +{ + // Get patch neighbour field, store temporarily in result + this->patchNeighbourField(result); + const auto& pnf = result; + + // Same as patchInternalField(...), assuming faceCells are an indirection + // into internal field, but without additional storage... + const auto& addr = this->patch().faceCells(); + const auto& iF = this->primitiveField(); + + // snGrad = deltaCoeffs * (patchNeighbourField - patchInternalField) + + const label len = result.size(); + + for (label i = 0; i < len; ++i) + { + result[i] = deltaCoeffs[i]*(pnf[i] - iF[addr[i]]); + } +} + + template Foam::tmp> Foam::coupledFvPatchField::snGrad ( const scalarField& deltaCoeffs ) const { - return - deltaCoeffs - *(this->patchNeighbourField() - this->patchInternalField()); + auto tresult = tmp>::New(this->size()); + this->snGrad(deltaCoeffs, tresult.ref()); + return tresult; } @@ -152,6 +179,44 @@ void Foam::coupledFvPatchField::evaluate(const Pstream::commsTypes) } +template +void Foam::coupledFvPatchField::valueInternalCoeffs +( + const tmp& tweights, + UList& result +) const +{ + const auto& w = tweights(); + + const label len = result.size(); + + for (label i = 0; i < len; ++i) + { + result[i] = Type(pTraits::one)*w[i]; + } + tweights.clear(); +} + + +template +void Foam::coupledFvPatchField::valueBoundaryCoeffs +( + const tmp& tweights, + UList& result +) const +{ + const auto& w = tweights(); + + const label len = result.size(); + + for (label i = 0; i < len; ++i) + { + result[i] = Type(pTraits::one)*(1.0 - w[i]); + } + tweights.clear(); +} + + template Foam::tmp> Foam::coupledFvPatchField::valueInternalCoeffs @@ -174,6 +239,38 @@ Foam::coupledFvPatchField::valueBoundaryCoeffs } +template +void Foam::coupledFvPatchField::gradientInternalCoeffs +( + const scalarField& deltaCoeffs, + UList& result +) const +{ + const label len = result.size(); + + for (label i = 0; i < len; ++i) + { + result[i] = -Type(pTraits::one)*deltaCoeffs[i]; + } +} + + +template +void Foam::coupledFvPatchField::gradientBoundaryCoeffs +( + const scalarField& deltaCoeffs, + UList& result +) const +{ + const label len = result.size(); + + for (label i = 0; i < len; ++i) + { + result[i] = Type(pTraits::one)*deltaCoeffs[i]; + } +} + + template Foam::tmp> Foam::coupledFvPatchField::gradientInternalCoeffs @@ -181,7 +278,9 @@ Foam::coupledFvPatchField::gradientInternalCoeffs const scalarField& deltaCoeffs ) const { - return -Type(pTraits::one)*deltaCoeffs; + auto tresult = tmp>::New(deltaCoeffs.size()); + this->gradientInternalCoeffs(deltaCoeffs, tresult.ref()); + return tresult; } @@ -194,6 +293,17 @@ Foam::coupledFvPatchField::gradientInternalCoeffs() const } +template +void Foam::coupledFvPatchField::gradientInternalCoeffs +( + UList& result +) const +{ + NotImplemented; + this->gradientInternalCoeffs(this->patch().deltaCoeffs(), result); +} + + template Foam::tmp> Foam::coupledFvPatchField::gradientBoundaryCoeffs @@ -214,6 +324,17 @@ Foam::coupledFvPatchField::gradientBoundaryCoeffs() const } +template +void Foam::coupledFvPatchField::gradientBoundaryCoeffs +( + UList& result +) const +{ + NotImplemented; + this->gradientBoundaryCoeffs(this->patch().deltaCoeffs(), result); +} + + template void Foam::coupledFvPatchField::write(Ostream& os) const { diff --git a/src/finiteVolume/fields/fvPatchFields/basic/coupled/coupledFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/basic/coupled/coupledFvPatchField.H index 244d57b49b..e353ec4243 100644 --- a/src/finiteVolume/fields/fvPatchFields/basic/coupled/coupledFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/basic/coupled/coupledFvPatchField.H @@ -208,32 +208,32 @@ public: } //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the value of this patchField with given weights + //- evaluation of the value of this patchField with given weights virtual tmp> valueInternalCoeffs ( const tmp& ) const; //- Return the matrix source coefficients corresponding to the - // evaluation of the value of this patchField with given weights + //- evaluation of the value of this patchField with given weights virtual tmp> valueBoundaryCoeffs ( const tmp& ) const; //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField virtual tmp> gradientInternalCoeffs ( const scalarField& deltaCoeffs ) const; //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField virtual tmp> gradientInternalCoeffs() const; //- Return the matrix source coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField virtual tmp> gradientBoundaryCoeffs ( const scalarField& deltaCoeffs @@ -244,6 +244,65 @@ public: virtual tmp> gradientBoundaryCoeffs() const; + // Contiguous storage + + //- Retrieve patch-normal gradient. + //- Assumes faceCells is an indirection into internal field + virtual void snGrad + ( + const scalarField& deltaCoeffs, + UList& + ) const; + + //- Retrieve patch-normal gradient + virtual void snGrad(UList&) const + { + NotImplemented; + } + + //- Return the matrix diagonal coefficients corresponding to the + // evaluation of the value of this patchField with given weights + virtual void valueInternalCoeffs + ( + const tmp&, + UList& + ) const; + + //- Return the matrix source coefficients corresponding to the + // evaluation of the value of this patchField with given weights + virtual void valueBoundaryCoeffs + ( + const tmp&, + UList& + ) const; + + //- Return the matrix diagonal coefficients corresponding to the + // evaluation of the gradient of this patchField + virtual void gradientInternalCoeffs(UList&) const; + + //- Return the matrix diagonal coefficients corresponding to the + // evaluation of the gradient of this coupled patchField + // using the deltaCoeffs provided + virtual void gradientInternalCoeffs + ( + const scalarField& deltaCoeffs, + UList& + ) const; + + //- Return the matrix source coefficients corresponding to the + // evaluation of the gradient of this patchField + virtual void gradientBoundaryCoeffs(UList&) const; + + //- Return the matrix source coefficients corresponding to the + // evaluation of the gradient of this coupled patchField + // using the deltaCoeffs provided + virtual void gradientBoundaryCoeffs + ( + const scalarField& deltaCoeffs, + UList& + ) const; + + // Coupled interface functionality //- Update result field based on interface functionality diff --git a/src/finiteVolume/fields/fvPatchFields/basic/zeroGradient/zeroGradientFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/basic/zeroGradient/zeroGradientFvPatchField.H index 950b8b2ecf..ab1fd503fb 100644 --- a/src/finiteVolume/fields/fvPatchFields/basic/zeroGradient/zeroGradientFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/basic/zeroGradient/zeroGradientFvPatchField.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation + Copyright (C) 2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -128,14 +129,22 @@ public: } - // Member functions + // Member Functions - // Evaluation functions + // Evaluation Functions - //- Return gradient at boundary + //- Return patch-normal gradient virtual tmp> snGrad() const { - return tmp>::New(this->size(), Zero); + // zero-gradient + return tmp>::New(this->size(), Foam::zero{}); + } + + //- Retrieve patch-normal gradient [contiguous storage] + virtual void snGrad(UList& result) const + { + // zero-gradient + result = Foam::zero{}; } //- Evaluate the patch field @@ -146,25 +155,25 @@ public: ); //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the value of this patchField with given weights + //- evaluation of the value of this patchField with given weights virtual tmp> valueInternalCoeffs ( const tmp& ) const; //- Return the matrix source coefficients corresponding to the - // evaluation of the value of this patchField with given weights + //- evaluation of the value of this patchField with given weights virtual tmp> valueBoundaryCoeffs ( const tmp& ) const; //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField virtual tmp> gradientInternalCoeffs() const; //- Return the matrix source coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField virtual tmp> gradientBoundaryCoeffs() const; }; diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/empty/emptyFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/empty/emptyFvPatchField.H index 3cf910fc07..d95a33ef5b 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/empty/emptyFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/constraint/empty/emptyFvPatchField.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation + Copyright (C) 2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -133,7 +134,7 @@ public: } - // Member functions + // Member Functions // Mapping functions @@ -153,7 +154,7 @@ public: {} - // Evaluation functions + // Evaluation Functions //- Update the coefficients associated with the patch field // This only checks to see the case is actually 1D or 2D @@ -182,20 +183,31 @@ public: } //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField tmp> gradientInternalCoeffs() const { return tmp>::New(); } //- Return the matrix source coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField tmp> gradientBoundaryCoeffs() const { return tmp>::New(); } + // Contiguous storage + + //- Retrieve patch-normal gradient [contiguous storage]. + //- Placeholder value is zero (treated like zero-gradient). + virtual void snGrad(UList& result) const + { + // Treat like zero-gradient + result = Foam::zero{}; + } + + // Member Functions //- Write without "value" entry! diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C index 4a7bd944b6..af418007dc 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.C @@ -314,6 +314,28 @@ void Foam::processorFvPatchField::evaluate } +template +void Foam::processorFvPatchField::snGrad +( + const scalarField& deltaCoeffs, + UList& result +) const +{ + // Get patch internal field, store temporarily in result + this->patchInternalField(result); + const auto& pif = result; + + const auto& pnf = *this; + + const label len = result.size(); + + for (label i = 0; i < len; ++i) + { + result[i] = deltaCoeffs[i]*(pnf[i] - pif[i]); + } +} + + template Foam::tmp> Foam::processorFvPatchField::snGrad @@ -321,6 +343,10 @@ Foam::processorFvPatchField::snGrad const scalarField& deltaCoeffs ) const { + // OR + // auto tfld = tmp>::New(this->size()); + // this->snGrad(deltaCoeffs, tfld.ref()); + // return tfld; return deltaCoeffs*(*this - this->patchInternalField()); } diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H index 05fe1361b5..0cd4e59354 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/constraint/processor/processorFvPatchField.H @@ -221,6 +221,13 @@ public: const scalarField& deltaCoeffs ) const; + //- Retrieve patch-normal gradient + virtual void snGrad + ( + const scalarField& deltaCoeffs, + UList& result + ) const; + // Coupled interface functionality diff --git a/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.C b/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.C index 97dfcf2cad..27d74529c2 100644 --- a/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.C @@ -221,10 +221,31 @@ void Foam::fvPatchField::check(const fvPatchField& rhs) const } +template +void Foam::fvPatchField::snGrad(UList& result) const +{ + // Get patch internal field, store temporarily in result + this->patchInternalField(result); + const auto& pif = result; + + const Field& pfld = *this; + const auto& dc = patch().deltaCoeffs(); + + const label len = result.size(); + + for (label i = 0; i < len; ++i) + { + result[i] = dc[i]*(pfld[i] - pif[i]); + } +} + + template Foam::tmp> Foam::fvPatchField::snGrad() const { - return patch().deltaCoeffs()*(*this - patchInternalField()); + auto tfld = tmp>::New(this->size()); + this->snGrad(static_cast&>(tfld.ref())); + return tfld; } diff --git a/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H b/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H index 26aca3d936..df8164df2d 100644 --- a/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H @@ -622,8 +622,11 @@ public: //- Return patch-normal gradient virtual tmp> snGrad() const; + //- Retrieve patch-normal gradient [contiguous storage] + virtual void snGrad(UList& result) const; + //- Return patch-normal gradient for coupled-patches - // using the deltaCoeffs provided + //- using the deltaCoeffs provided virtual tmp> snGrad ( const scalarField& deltaCoeffs @@ -633,15 +636,16 @@ public: return *this; } - //- Update the coefficients associated with the patch field - // Sets Updated to true - virtual void updateCoeffs(); - - //- Update the coefficients associated with the patch field - // with a weight field (0..1). This weight field is usually - // provided as the amount of geometric overlap for 'duplicate' - // patches. Sets Updated to true - virtual void updateWeightedCoeffs(const scalarField& weights); + //- Retrieve patch-normal gradient for coupled-patches + //- using the deltaCoeffs provided [contiguous storage] + virtual void snGrad + ( + const scalarField& deltaCoeffs, + UList& + ) const + { + NotImplemented; + } //- Return internal field next to patch virtual tmp> patchInternalField() const; @@ -657,6 +661,22 @@ public: return *this; } + //- Retrieve patchField on the opposite patch of a coupled patch + virtual void patchNeighbourField(UList&) const + { + NotImplemented; + } + + //- Update the coefficients associated with the patch field + // Sets Updated to true + virtual void updateCoeffs(); + + //- Update the coefficients associated with the patch field + // with a weight field (0..1). This weight field is usually + // provided as the amount of geometric overlap for 'duplicate' + // patches. Sets Updated to true + virtual void updateWeightedCoeffs(const scalarField& weights); + //- Initialise the evaluation of the patch field virtual void initEvaluate ( @@ -690,7 +710,7 @@ public: {} //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the value of this patchField with given weights + //- evaluation of the value of this patchField with given weights virtual tmp> valueInternalCoeffs ( const tmp& @@ -701,7 +721,7 @@ public: } //- Return the matrix source coefficients corresponding to the - // evaluation of the value of this patchField with given weights + //- evaluation of the value of this patchField with given weights virtual tmp> valueBoundaryCoeffs ( const tmp& @@ -712,7 +732,7 @@ public: } //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField virtual tmp> gradientInternalCoeffs() const { NotImplemented; @@ -720,8 +740,8 @@ public: } //- Return the matrix diagonal coefficients corresponding to the - // evaluation of the gradient of this coupled patchField - // using the deltaCoeffs provided + //- evaluation of the gradient of this coupled patchField + //- using the deltaCoeffs provided virtual tmp> gradientInternalCoeffs ( const scalarField& deltaCoeffs @@ -732,7 +752,7 @@ public: } //- Return the matrix source coefficients corresponding to the - // evaluation of the gradient of this patchField + //- evaluation of the gradient of this patchField virtual tmp> gradientBoundaryCoeffs() const { NotImplemented; @@ -740,8 +760,8 @@ public: } //- Return the matrix source coefficients corresponding to the - // evaluation of the gradient of this coupled patchField - // using the deltaCoeffs provided + //- evaluation of the gradient of this coupled patchField + //- using the deltaCoeffs provided virtual tmp> gradientBoundaryCoeffs ( const scalarField& deltaCoeffs @@ -751,7 +771,6 @@ public: return *this; } - //- Manipulate matrix virtual void manipulateMatrix(fvMatrix& matrix); @@ -771,6 +790,69 @@ public: ); + // Contiguous storage + + //- Retrieve the matrix diagonal coefficients corresponding to the + //- evaluation of the value of this patchField with given weights + virtual void valueInternalCoeffs + ( + const tmp>&, + UList& + ) const + { + NotImplemented; + } + + //- Retrieve the matrix source coefficients corresponding to the + //- evaluation of the value of this patchField with given weights + virtual void valueBoundaryCoeffs + ( + const tmp>&, + UList& + ) const + { + NotImplemented; + } + + //- Retrieve the matrix diagonal coefficients corresponding to the + //- evaluation of the gradient of this patchField + virtual void gradientInternalCoeffs(UList&) const + { + NotImplemented; + } + + //- Retrieve the matrix diagonal coefficients corresponding to the + //- evaluation of the gradient of this coupled patchField + //- using the deltaCoeffs provided + virtual void gradientInternalCoeffs + ( + const scalarField& deltaCoeffs, + UList& + ) const + { + NotImplemented; + } + + //- Retrieve the matrix source coefficients corresponding to the + //- evaluation of the gradient of this patchField + virtual void gradientBoundaryCoeffs(UList&) const + { + NotImplemented; + } + + //- Retrieve the matrix source coefficients corresponding to the + //- evaluation of the gradient of this coupled patchField + //- using the deltaCoeffs provided + virtual void gradientBoundaryCoeffs + ( + const scalarField& deltaCoeffs, + UList& + ) const + { + NotImplemented; + } + + // Other //- Write