diff --git a/src/TurbulenceModels/turbulenceModels/LES/LESdeltas/smoothDelta/smoothDelta.H b/src/TurbulenceModels/turbulenceModels/LES/LESdeltas/smoothDelta/smoothDelta.H index 6bcd6efdd4..6433e6586f 100644 --- a/src/TurbulenceModels/turbulenceModels/LES/LESdeltas/smoothDelta/smoothDelta.H +++ b/src/TurbulenceModels/turbulenceModels/LES/LESdeltas/smoothDelta/smoothDelta.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2016-2020 OpenCFD Ltd. + Copyright (C) 2016-2020,2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -189,6 +189,23 @@ public: template inline bool equal(const deltaData&, TrackingData& td) const; + //- Interpolate between two values (lerp). Returns true if + //- causes changes. Not sure if needs to be specialised between + //- face and cell and what index is needed... + template + inline bool interpolate + ( + const polyMesh&, + const point& pt, + const label i0, + const deltaData& f0, + const label i1, + const deltaData& f1, + const scalar weight, + const scalar tol, + TrackingData& td + ); + // Member Operators @@ -296,6 +313,17 @@ public: template<> struct is_contiguous : std::true_type {}; +//- Interpolation - used in e.g. cyclicAMI interpolation +inline LESModels::smoothDelta::deltaData lerp +( + const LESModels::smoothDelta::deltaData& a, + const LESModels::smoothDelta::deltaData& b, + const scalar t +) +{ + return LESModels::smoothDelta::deltaData(lerp(a.delta(), b.delta(), t)); +} + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/TurbulenceModels/turbulenceModels/LES/LESdeltas/smoothDelta/smoothDeltaDeltaDataI.H b/src/TurbulenceModels/turbulenceModels/LES/LESdeltas/smoothDelta/smoothDeltaDeltaDataI.H index 827cfda833..75196d514c 100644 --- a/src/TurbulenceModels/turbulenceModels/LES/LESdeltas/smoothDelta/smoothDeltaDeltaDataI.H +++ b/src/TurbulenceModels/turbulenceModels/LES/LESdeltas/smoothDelta/smoothDeltaDeltaDataI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019,2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -191,6 +191,40 @@ inline bool Foam::LESModels::smoothDelta::deltaData::equal } +template +inline bool Foam::LESModels::smoothDelta::deltaData::interpolate +( + const polyMesh&, + const point& pt, + const label i0, + const deltaData& f0, + const label i1, + const deltaData& f1, + const scalar weight, + const scalar tol, + TrackingData& td +) +{ + if (f0.valid(td) && f1.valid(td)) + { + const deltaData w2(lerp(f0.delta(), f1.delta(), weight)); + return update(w2, 1.0, tol, td); + } + else if (f0.valid(td)) + { + return update(f0, 1.0, tol, td); + } + else if (f1.valid(td)) + { + return update(f1, 1.0, tol, td); + } + else + { + return false; + } +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // inline bool Foam::LESModels::smoothDelta::deltaData::operator== diff --git a/src/dynamicMesh/meshCut/directions/directionInfo/directionInfo.H b/src/dynamicMesh/meshCut/directions/directionInfo/directionInfo.H index 6cdf73ef7d..1a94ea0d3a 100644 --- a/src/dynamicMesh/meshCut/directions/directionInfo/directionInfo.H +++ b/src/dynamicMesh/meshCut/directions/directionInfo/directionInfo.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2020,2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -242,6 +242,23 @@ public: template inline bool equal(const directionInfo&, TrackingData& td) const; + //- Interpolate between two values (lerp). Returns true if + //- causes changes. Not sure if needs to be specialised between + //- face and cell and what index is needed... + template + inline bool interpolate + ( + const polyMesh&, + const point& pt, + const label i0, + const directionInfo& f0, + const label i1, + const directionInfo& f1, + const scalar weight, + const scalar tol, + TrackingData& td + ); + // Member Operators diff --git a/src/dynamicMesh/meshCut/directions/directionInfo/directionInfoI.H b/src/dynamicMesh/meshCut/directions/directionInfo/directionInfoI.H index 6005807f33..1f6c934c97 100644 --- a/src/dynamicMesh/meshCut/directions/directionInfo/directionInfoI.H +++ b/src/dynamicMesh/meshCut/directions/directionInfo/directionInfoI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2020 OpenCFD Ltd. + Copyright (C) 2020,2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -287,6 +287,35 @@ inline bool Foam::directionInfo::equal } +template +inline bool Foam::directionInfo::interpolate +( + const polyMesh& mesh, + const point& pt, + const label i0, + const directionInfo& f0, + const label i1, + const directionInfo& f1, + const scalar weight, + const scalar tol, + TrackingData& td +) +{ + if (f0.valid(td)) + { + return updateFace(mesh, -1, f0, tol, td); + } + if (f1.valid(td)) + { + return updateFace(mesh, -1, f1, tol, td); + } + else + { + return false; + } +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // inline bool Foam::directionInfo::operator== diff --git a/src/dynamicMesh/meshCut/wallLayerCells/wallNormalInfo/wallNormalInfo.H b/src/dynamicMesh/meshCut/wallLayerCells/wallNormalInfo/wallNormalInfo.H index 630203f44f..16a7078ace 100644 --- a/src/dynamicMesh/meshCut/wallLayerCells/wallNormalInfo/wallNormalInfo.H +++ b/src/dynamicMesh/meshCut/wallLayerCells/wallNormalInfo/wallNormalInfo.H @@ -186,6 +186,23 @@ public: TrackingData& td ); + //- Interpolate between two values (lerp). Returns true if + //- causes changes. Not sure if needs to be specialised between + //- face and cell and what index is needed... + template + inline bool interpolate + ( + const polyMesh&, + const point& pt, + const label i0, + const wallNormalInfo& f0, + const label i1, + const wallNormalInfo& f1, + const scalar weight, + const scalar tol, + TrackingData& td + ); + //- Test for equality, with TrackingData template inline bool equal(const wallNormalInfo&, TrackingData& td) const; diff --git a/src/dynamicMesh/meshCut/wallLayerCells/wallNormalInfo/wallNormalInfoI.H b/src/dynamicMesh/meshCut/wallLayerCells/wallNormalInfo/wallNormalInfoI.H index 0260c2828d..92b0d0be1c 100644 --- a/src/dynamicMesh/meshCut/wallLayerCells/wallNormalInfo/wallNormalInfoI.H +++ b/src/dynamicMesh/meshCut/wallLayerCells/wallNormalInfo/wallNormalInfoI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2020 OpenCFD Ltd. + Copyright (C) 2020,2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -191,6 +191,35 @@ inline bool Foam::wallNormalInfo::equal } +template +inline bool Foam::wallNormalInfo::interpolate +( + const polyMesh&, + const point& pt, + const label i0, + const wallNormalInfo& f0, + const label i1, + const wallNormalInfo& f1, + const scalar weight, + const scalar tol, + TrackingData& td +) +{ + if (f0.valid(td)) + { + return update(f0, td); + } + if (f1.valid(td)) + { + return update(f1, td); + } + else + { + return false; + } +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // inline bool Foam::wallNormalInfo::operator== diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementData.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementData.H index 7ee11722de..ff6369153c 100644 --- a/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementData.H +++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementData.H @@ -197,6 +197,23 @@ public: template inline bool equal(const refinementData&, TrackingData& td) const; + //- Interpolate between two values (lerp). Returns true if + //- causes changes. Not sure if needs to be specialised between + //- face and cell and what index is needed... + template + inline bool interpolate + ( + const polyMesh&, + const point& pt, + const label i0, + const refinementData& f0, + const label i1, + const refinementData& f1, + const scalar weight, + const scalar tol, + TrackingData& td + ); + // Member Operators diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementDataI.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementDataI.H index f8bdaae0cb..fe3877eff2 100644 --- a/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementDataI.H +++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementDataI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2020 OpenCFD Ltd. + Copyright (C) 2020,2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -248,6 +248,35 @@ inline bool Foam::refinementData::equal } +template +inline bool Foam::refinementData::interpolate +( + const polyMesh& mesh, + const point& pt, + const label i0, + const refinementData& f0, + const label i1, + const refinementData& f1, + const scalar weight, + const scalar tol, + TrackingData& td +) +{ + if (f0.valid(td)) + { + return updateFace(mesh, -1, f0, tol, td); + } + if (f1.valid(td)) + { + return updateFace(mesh, -1, f1, tol, td); + } + else + { + return false; + } +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // inline bool Foam::refinementData::operator== diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementDistanceData.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementDistanceData.H index 5e0cecacd9..c1e2f0b61b 100644 --- a/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementDistanceData.H +++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementDistanceData.H @@ -229,6 +229,23 @@ public: inline bool equal(const refinementDistanceData&, TrackingData&) const; + //- Interpolate between two values (lerp). Returns true if + //- causes changes. Not sure if needs to be specialised between + //- face and cell and what index is needed... + template + inline bool interpolate + ( + const polyMesh&, + const point& pt, + const label i0, + const refinementDistanceData& f0, + const label i1, + const refinementDistanceData& f1, + const scalar weight, + const scalar tol, + TrackingData& td + ); + // Member Operators diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementDistanceDataI.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementDistanceDataI.H index e7995019e6..26d0e774c3 100644 --- a/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementDistanceDataI.H +++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementDistanceDataI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2020,2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -278,6 +278,35 @@ inline bool Foam::refinementDistanceData::equal } +template +inline bool Foam::refinementDistanceData::interpolate +( + const polyMesh&, + const point& pt, + const label i0, + const refinementDistanceData& f0, + const label i1, + const refinementDistanceData& f1, + const scalar weight, + const scalar tol, + TrackingData& td +) +{ + if (f0.valid(td)) + { + return update(pt, f0, tol, td); + } + if (f1.valid(td)) + { + return update(pt, f1, tol, td); + } + else + { + return false; + } +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // inline bool Foam::refinementDistanceData::operator== diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C index ebd326cdb3..51e975cfdd 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.C @@ -227,9 +227,15 @@ bool Foam::cyclicACMIFvPatchField::all_ready() const recvRequests_.start(), recvRequests_.size() ) + && UPstream::finishedRequests + ( + recvRequests1_.start(), + recvRequests1_.size() + ) ) { recvRequests_.clear(); + recvRequests1_.clear(); ++done; } @@ -240,9 +246,15 @@ bool Foam::cyclicACMIFvPatchField::all_ready() const sendRequests_.start(), sendRequests_.size() ) + && UPstream::finishedRequests + ( + sendRequests1_.start(), + sendRequests1_.size() + ) ) { sendRequests_.clear(); + sendRequests1_.clear(); ++done; } @@ -260,9 +272,15 @@ bool Foam::cyclicACMIFvPatchField::ready() const recvRequests_.start(), recvRequests_.size() ) + && UPstream::finishedRequests + ( + recvRequests1_.start(), + recvRequests1_.size() + ) ) { recvRequests_.clear(); + recvRequests1_.clear(); if ( @@ -271,9 +289,15 @@ bool Foam::cyclicACMIFvPatchField::ready() const sendRequests_.start(), sendRequests_.size() ) + && UPstream::finishedRequests + ( + sendRequests1_.start(), + sendRequests1_.size() + ) ) { sendRequests_.clear(); + sendRequests1_.clear(); } return true; @@ -483,7 +507,7 @@ void Foam::cyclicACMIFvPatchField::initEvaluate const Field pnf(this->primitiveField(), nbrFaceCells); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -494,14 +518,20 @@ void Foam::cyclicACMIFvPatchField::initEvaluate // Assume that sends are also OK sendRequests_.clear(); + sendRequests1_.clear(); cyclicACMIPatch_.initInterpolate ( pnf, sendRequests_, - sendBufs_, recvRequests_, - recvBufs_ + sendBufs_, + recvBufs_, + + sendRequests1_, + recvRequests1_, + sendBufs1_, + recvBufs1_ ); } } @@ -547,12 +577,15 @@ void Foam::cyclicACMIFvPatchField::evaluate ( Field::null(), // Not used for distributed recvRequests_, - recvBufs_ + recvBufs_, + recvRequests1_, + recvBufs1_ ).ptr() ); // Receive requests all handled by last function call recvRequests_.clear(); + recvRequests1_.clear(); if (doTransform()) { @@ -608,7 +641,7 @@ void Foam::cyclicACMIFvPatchField::initInterfaceMatrixUpdate transformCoupleField(pnf, cmpt); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -619,14 +652,20 @@ void Foam::cyclicACMIFvPatchField::initInterfaceMatrixUpdate // Assume that sends are also OK sendRequests_.clear(); + sendRequests1_.clear(); cyclicACMIPatch_.initInterpolate ( pnf, sendRequests_, - scalarSendBufs_, recvRequests_, - scalarRecvBufs_ + scalarSendBufs_, + scalarRecvBufs_, + + sendRequests1_, + recvRequests1_, + scalarSendBufs1_, + scalarRecvBufs1_ ); } @@ -681,11 +720,14 @@ void Foam::cyclicACMIFvPatchField::updateInterfaceMatrix ( solveScalarField::null(), // Not used for distributed recvRequests_, - scalarRecvBufs_ + scalarRecvBufs_, + recvRequests1_, + scalarRecvBufs1_ ); // Receive requests all handled by last function call recvRequests_.clear(); + recvRequests1_.clear(); } else { @@ -738,7 +780,7 @@ void Foam::cyclicACMIFvPatchField::initInterfaceMatrixUpdate transformCoupleField(pnf); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -749,14 +791,20 @@ void Foam::cyclicACMIFvPatchField::initInterfaceMatrixUpdate // Assume that sends are also OK sendRequests_.clear(); + sendRequests1_.clear(); cyclicACMIPatch_.initInterpolate ( pnf, sendRequests_, - sendBufs_, recvRequests_, - recvBufs_ + sendBufs_, + recvBufs_, + + sendRequests1_, + recvRequests1_, + sendBufs1_, + recvBufs1_ ); } @@ -798,11 +846,14 @@ void Foam::cyclicACMIFvPatchField::updateInterfaceMatrix ( Field::null(), // Not used for distributed recvRequests_, - recvBufs_ + recvBufs_, + recvRequests1_, + recvBufs1_ ); // Receive requests all handled by last function call recvRequests_.clear(); + recvRequests1_.clear(); } else { diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H index d19975f48a..7e044a1163 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicACMI/cyclicACMIFvPatchField.H @@ -102,6 +102,28 @@ class cyclicACMIFvPatchField //- Scalar receive buffers mutable PtrList> scalarRecvBufs_; + + // Only used for AMI caching + + //- Current range of send requests (non-blocking) + mutable labelRange sendRequests1_; + + //- Current range of recv requests (non-blocking) + mutable labelRange recvRequests1_; + + //- Send buffers + mutable PtrList> sendBufs1_; + + //- Receive buffers_ + mutable PtrList> recvBufs1_; + + //- Scalar send buffers + mutable PtrList> scalarSendBufs1_; + + //- Scalar receive buffers + mutable PtrList> scalarRecvBufs1_; + + //- Neighbour coupled internal cell data mutable autoPtr> patchNeighbourFieldPtr_; diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C index 314bbc5c21..a4433a14e0 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.C @@ -207,9 +207,15 @@ bool Foam::cyclicAMIFvPatchField::all_ready() const recvRequests_.start(), recvRequests_.size() ) + && UPstream::finishedRequests + ( + recvRequests1_.start(), + recvRequests1_.size() + ) ) { recvRequests_.clear(); + recvRequests1_.clear(); ++done; } @@ -220,9 +226,15 @@ bool Foam::cyclicAMIFvPatchField::all_ready() const sendRequests_.start(), sendRequests_.size() ) + && UPstream::finishedRequests + ( + sendRequests1_.start(), + sendRequests1_.size() + ) ) { sendRequests_.clear(); + sendRequests1_.clear(); ++done; } @@ -240,9 +252,15 @@ bool Foam::cyclicAMIFvPatchField::ready() const recvRequests_.start(), recvRequests_.size() ) + && UPstream::finishedRequests + ( + recvRequests1_.start(), + recvRequests1_.size() + ) ) { recvRequests_.clear(); + recvRequests1_.clear(); if ( @@ -251,9 +269,15 @@ bool Foam::cyclicAMIFvPatchField::ready() const sendRequests_.start(), sendRequests_.size() ) + && UPstream::finishedRequests + ( + sendRequests1_.start(), + sendRequests1_.size() + ) ) { sendRequests_.clear(); + sendRequests1_.clear(); } return true; @@ -319,9 +343,18 @@ Foam::cyclicAMIFvPatchField::getNeighbourField template -bool Foam::cyclicAMIFvPatchField::cacheNeighbourField() +bool Foam::cyclicAMIFvPatchField::cacheNeighbourField() const { - return (FieldBase::localBoundaryConsistency() != 0); + // const auto& AMI = this->ownerAMI(); + + // if (AMI.cacheActive()) + // { + // return false; + // } + // else + { + return (FieldBase::localBoundaryConsistency() != 0); + } } @@ -350,11 +383,12 @@ Foam::cyclicAMIFvPatchField::getPatchNeighbourField } const auto& fvp = this->patch(); + const auto& mesh = fvp.boundaryMesh().mesh(); if ( patchNeighbourFieldPtr_ - && !fvp.boundaryMesh().mesh().upToDatePoints(this->internalField()) + && !mesh.upToDatePoints(this->internalField()) ) { //DebugPout @@ -418,7 +452,8 @@ template Foam::tmp> Foam::cyclicAMIFvPatchField::patchNeighbourField() const { - return this->getPatchNeighbourField(true); // checkCommunicator = true + // checkCommunicator = true + return this->getPatchNeighbourField(true); } @@ -491,7 +526,7 @@ void Foam::cyclicAMIFvPatchField::initEvaluate const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch(); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -502,14 +537,20 @@ void Foam::cyclicAMIFvPatchField::initEvaluate // Assume that sends are also OK sendRequests_.clear(); + sendRequests1_.clear(); cpp.initInterpolate ( pnf, sendRequests_, - sendBufs_, recvRequests_, - recvBufs_ + sendBufs_, + recvBufs_, + + sendRequests1_, + recvRequests1_, + sendBufs1_, + recvBufs1_ ); } } @@ -562,12 +603,15 @@ void Foam::cyclicAMIFvPatchField::evaluate Field::null(), // Not used for distributed recvRequests_, recvBufs_, + recvRequests1_, + recvBufs1_, defaultValues ).ptr() ); // Receive requests all handled by last function call recvRequests_.clear(); + recvRequests1_.clear(); if (doTransform()) { @@ -618,7 +662,7 @@ void Foam::cyclicAMIFvPatchField::initInterfaceMatrixUpdate const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch(); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -629,14 +673,20 @@ void Foam::cyclicAMIFvPatchField::initInterfaceMatrixUpdate // Assume that sends are also OK sendRequests_.clear(); + sendRequests1_.clear(); cpp.initInterpolate ( pnf, sendRequests_, - scalarSendBufs_, recvRequests_, - scalarRecvBufs_ + scalarSendBufs_, + scalarRecvBufs_, + + sendRequests1_, + recvRequests1_, + scalarSendBufs1_, + scalarRecvBufs1_ ); } @@ -691,11 +741,14 @@ void Foam::cyclicAMIFvPatchField::updateInterfaceMatrix solveScalarField::null(), // Not used for distributed recvRequests_, scalarRecvBufs_, + recvRequests1_, + scalarRecvBufs1_, defaultValues ); // Receive requests all handled by last function call recvRequests_.clear(); + recvRequests1_.clear(); } else { @@ -757,7 +810,7 @@ void Foam::cyclicAMIFvPatchField::initInterfaceMatrixUpdate const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch(); // Assert that all receives are known to have finished - if (!recvRequests_.empty()) + if (!recvRequests_.empty() || !recvRequests1_.empty()) { FatalErrorInFunction << "Outstanding recv request(s) on patch " @@ -768,14 +821,20 @@ void Foam::cyclicAMIFvPatchField::initInterfaceMatrixUpdate // Assume that sends are also OK sendRequests_.clear(); + sendRequests1_.clear(); cpp.initInterpolate ( pnf, sendRequests_, - sendBufs_, recvRequests_, - recvBufs_ + sendBufs_, + recvBufs_, + + sendRequests1_, + recvRequests1_, + sendBufs1_, + recvBufs1_ ); } @@ -829,11 +888,14 @@ void Foam::cyclicAMIFvPatchField::updateInterfaceMatrix Field::null(), // Not used for distributed recvRequests_, recvBufs_, + recvRequests1_, + recvBufs1_, defaultValues ); // Receive requests all handled by last function call recvRequests_.clear(); + recvRequests1_.clear(); } else { @@ -918,7 +980,7 @@ void Foam::cyclicAMIFvPatchField::manipulateMatrix } // Set internalCoeffs and boundaryCoeffs in the assembly matrix - // on clyclicAMI patches to be used in the individual matrix by + // on cyclicAMI patches to be used in the individual matrix by // matrix.flux() if (matrix.psi(mat).mesh().fluxRequired(this->internalField().name())) { diff --git a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H index 9afe8cf1c5..4ac4fbf123 100644 --- a/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H +++ b/src/finiteVolume/fields/fvPatchFields/constraint/cyclicAMI/cyclicAMIFvPatchField.H @@ -113,6 +113,28 @@ class cyclicAMIFvPatchField //- Scalar receive buffers mutable PtrList> scalarRecvBufs_; + + // Only used for AMI caching + + //- Current range of send requests (non-blocking) + mutable labelRange sendRequests1_; + + //- Current range of recv requests (non-blocking) + mutable labelRange recvRequests1_; + + //- Send buffers + mutable PtrList> sendBufs1_; + + //- Receive buffers_ + mutable PtrList> recvBufs1_; + + //- Scalar send buffers + mutable PtrList> scalarSendBufs1_; + + //- Scalar receive buffers + mutable PtrList> scalarRecvBufs1_; + + //- Neighbour coupled internal cell data mutable autoPtr> patchNeighbourFieldPtr_; @@ -134,7 +156,7 @@ class cyclicAMIFvPatchField virtual bool all_ready() const; //- Use neighbour field caching - static bool cacheNeighbourField(); + bool cacheNeighbourField() const; //- Return neighbour coupled internal cell data tmp> getNeighbourField(const UList&) const; diff --git a/src/finiteVolume/finiteVolume/fvc/fvcSmooth/smoothData.H b/src/finiteVolume/finiteVolume/fvc/fvcSmooth/smoothData.H index 546d56faea..1e559ae1c1 100644 --- a/src/finiteVolume/finiteVolume/fvc/fvcSmooth/smoothData.H +++ b/src/finiteVolume/finiteVolume/fvc/fvcSmooth/smoothData.H @@ -209,6 +209,23 @@ public: template inline bool equal(const smoothData&, TrackingData& td) const; + //- Interpolate between two values (lerp). Returns true if + //- causes changes. Not sure if needs to be specialised between + //- face and cell and what index is needed... + template + inline bool interpolate + ( + const polyMesh&, + const point& pt, + const label i0, + const smoothData& f0, + const label i1, + const smoothData& f1, + const scalar weight, + const scalar tol, + TrackingData& td + ); + // Member Operators diff --git a/src/finiteVolume/finiteVolume/fvc/fvcSmooth/smoothDataI.H b/src/finiteVolume/finiteVolume/fvc/fvcSmooth/smoothDataI.H index 301b478d21..4efcba3bec 100644 --- a/src/finiteVolume/finiteVolume/fvc/fvcSmooth/smoothDataI.H +++ b/src/finiteVolume/finiteVolume/fvc/fvcSmooth/smoothDataI.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2013 OpenFOAM Foundation - Copyright (C) 2020 OpenCFD Ltd. + Copyright (C) 2020,2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -191,6 +191,45 @@ inline bool Foam::smoothData::equal } +template +inline bool Foam::smoothData::interpolate +( + const polyMesh&, + const point& pt, + const label i0, + const smoothData& f0, + const label i1, + const smoothData& f1, + const scalar weight, + const scalar tol, + TrackingData& td +) +{ + // TBD. What to interpolate? Do we have a position? cell/face centre? + + if (!valid(td)) + { + if (f0.valid(td)) + { + operator=(f0); + } + else + { + operator=(f1); + } + } + else if (f0.valid(td)) + { + operator=(f0); + } + else + { + operator=(f1); + } + return true; +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // inline bool Foam::smoothData::operator== diff --git a/src/finiteVolume/finiteVolume/fvc/fvcSmooth/sweepData.H b/src/finiteVolume/finiteVolume/fvc/fvcSmooth/sweepData.H index fea4a8986e..95f9144d03 100644 --- a/src/finiteVolume/finiteVolume/fvc/fvcSmooth/sweepData.H +++ b/src/finiteVolume/finiteVolume/fvc/fvcSmooth/sweepData.H @@ -207,6 +207,23 @@ public: template inline bool equal(const sweepData&, TrackingData& td) const; + //- Interpolate between two values (lerp). Returns true if + //- causes changes. Not sure if needs to be specialised between + //- face and cell and what index is needed... + template + inline bool interpolate + ( + const polyMesh&, + const point& pt, + const label i0, + const sweepData& f0, + const label i1, + const sweepData& f1, + const scalar weight, + const scalar tol, + TrackingData& td + ); + // Member Operators diff --git a/src/finiteVolume/finiteVolume/fvc/fvcSmooth/sweepDataI.H b/src/finiteVolume/finiteVolume/fvc/fvcSmooth/sweepDataI.H index a57cfcd880..1585c8c0a3 100644 --- a/src/finiteVolume/finiteVolume/fvc/fvcSmooth/sweepDataI.H +++ b/src/finiteVolume/finiteVolume/fvc/fvcSmooth/sweepDataI.H @@ -210,6 +210,45 @@ inline bool Foam::sweepData::equal } +template +inline bool Foam::sweepData::interpolate +( + const polyMesh&, + const point& pt, + const label i0, + const sweepData& f0, + const label i1, + const sweepData& f1, + const scalar weight, + const scalar tol, + TrackingData& td +) +{ + // TBD. What to interpolate? Do we have a position? cell/face centre? + + if (!valid(td)) + { + if (f0.valid(td)) + { + operator=(f0); + } + else + { + operator=(f1); + } + } + else if (f0.valid(td)) + { + operator=(f0); + } + else + { + operator=(f1); + } + return true; +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // inline bool Foam::sweepData::operator== diff --git a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H index 9525a4db0a..68c98c8d01 100644 --- a/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H +++ b/src/finiteVolume/fvMesh/fvPatches/constraint/cyclicACMI/cyclicACMIFvPatch.H @@ -220,9 +220,14 @@ public: ( const Field& fld, labelRange& sendRequests, - PtrList>& sendBuffers, labelRange& recvRequests, - PtrList>& recvBuffers + PtrList>& sendBuffers, + PtrList>& recvBuffers, + + labelRange& sendRequests1, + labelRange& recvRequests1, + PtrList>& sendBuffers1, + PtrList>& recvBuffers1 ) const { // Make sure areas are up-to-date @@ -232,9 +237,14 @@ public: ( fld, sendRequests, - sendBuffers, recvRequests, - recvBuffers + sendBuffers, + recvBuffers, + + sendRequests1, + recvRequests1, + sendBuffers1, + recvBuffers1 ); } @@ -243,7 +253,9 @@ public: ( const Field& localFld, const labelRange& requests, // The receive requests - const PtrList>& recvBuffers + const PtrList>& recvBuffers, + const labelRange& requests1, // The receive requests + const PtrList>& recvBuffers1 ) const { return cyclicACMIPolyPatch_.interpolate @@ -251,6 +263,8 @@ public: localFld, requests, recvBuffers, + requests1, + recvBuffers1, UList() ); } diff --git a/src/mesh/snappyHexMesh/meshRefinement/wallPoints.H b/src/mesh/snappyHexMesh/meshRefinement/wallPoints.H index aabb81a3c3..f660da450c 100644 --- a/src/mesh/snappyHexMesh/meshRefinement/wallPoints.H +++ b/src/mesh/snappyHexMesh/meshRefinement/wallPoints.H @@ -251,6 +251,23 @@ public: template inline bool equal(const wallPoints&, TrackingData&) const; + //- Interpolate between two values (lerp). Returns true if + //- causes changes. Not sure if needs to be specialised between + //- face and cell and what index is needed... + template + inline bool interpolate + ( + const polyMesh&, + const point& pt, + const label i0, + const wallPoints& f0, + const label i1, + const wallPoints& f1, + const scalar weight, + const scalar tol, + TrackingData& td + ); + // Member Operators diff --git a/src/mesh/snappyHexMesh/meshRefinement/wallPointsI.H b/src/mesh/snappyHexMesh/meshRefinement/wallPointsI.H index 61d01998b8..a5ad0e3ac5 100644 --- a/src/mesh/snappyHexMesh/meshRefinement/wallPointsI.H +++ b/src/mesh/snappyHexMesh/meshRefinement/wallPointsI.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018-2023 OpenCFD Ltd. + Copyright (C) 2018-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -443,6 +443,41 @@ inline bool Foam::wallPoints::equal } +template +inline bool Foam::wallPoints::interpolate +( + const polyMesh&, + const point& pt, + const label i0, + const wallPoints& f0, + const label i1, + const wallPoints& f1, + const scalar weight, + const scalar tol, + TrackingData& td +) +{ + if (valid(td)) + { + return false; + } + else if (f0.valid(td)) + { + operator=(f0); + return true; + } + else if (f1.valid(td)) + { + operator=(f1); + return true; + } + else + { + return false; + } +} + + // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // inline bool Foam::wallPoints::operator== diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMICache.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMICache.C new file mode 100644 index 0000000000..77caafb3ef --- /dev/null +++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMICache.C @@ -0,0 +1,651 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2025 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "AMICache.H" +#include "AMIInterpolation.H" +#include "mathematicalConstants.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +Foam::scalar Foam::AMICache::cacheThetaTolerance_ = 1e-8; + +int Foam::AMICache::debug = 0; + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::scalar Foam::AMICache::getRotationAngle(const point& globalPoint) const +{ + if (!coordSysPtr_) + { + FatalErrorInFunction + << "No co-ordinate system available for theta evaluation" + << abort(FatalError); + } + + + scalar theta = coordSysPtr_->localPosition(globalPoint).y(); + + // Ensure 0 < theta < 2pi + if (mag(theta) < cacheThetaTolerance_) + { + theta = 0; + } + else if (theta < 0) + { + theta += constant::mathematical::twoPi; + } + + return theta; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::AMICache::AMICache(const dictionary& dict, const bool toSource) +: + size_(dict.getOrDefault