diff --git a/src/overset/oversetMesh/oversetFringe/donorBasedLayeredOverlapFringe/donorBasedLayeredOverlap.C b/src/overset/oversetMesh/oversetFringe/donorBasedLayeredOverlapFringe/donorBasedLayeredOverlap.C
new file mode 100644
index 000000000..fbedea562
--- /dev/null
+++ b/src/overset/oversetMesh/oversetFringe/donorBasedLayeredOverlapFringe/donorBasedLayeredOverlap.C
@@ -0,0 +1,392 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+\*---------------------------------------------------------------------------*/
+
+#include "donorBasedLayeredOverlapFringe.H"
+#include "faceCellsFringe.H"
+#include "oversetRegion.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+ defineTypeNameAndDebug(donorBasedLayeredOverlapFringe, 0);
+ addToRunTimeSelectionTable
+ (
+ oversetFringe,
+ donorBasedLayeredOverlapFringe,
+ dictionary
+ );
+}
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+void Foam::donorBasedLayeredOverlapFringe::calcAddressing() const
+{
+ if (acceptorsPtr_)
+ {
+ FatalErrorIn
+ (
+ "void Foam::donorBasedLayeredOverlapFringe::calcAddressing() const"
+ ) << "Addressing already calculated"
+ << abort(FatalError);
+ }
+
+ // Get reference to region cell zone
+ const cellZone& rcz = region().zone();
+
+ // Make a hash set to collect acceptor points
+ // Note: 2 patches connecting at the corner may create a duplicate,
+ // which is filtered on insertion
+ labelHashSet acceptorSet;
+
+ // Find patches and mark cells
+ forAll (patchNames_, nameI)
+ {
+ const polyPatchID curFringePatch
+ (
+ patchNames_[nameI],
+ mesh().boundaryMesh()
+ );
+
+ if (!curFringePatch.active())
+ {
+ FatalErrorIn
+ (
+ "void donorBasedLayeredOverlapFringe::calcAddressing() const"
+ ) << "Fringe patch " << patchNames_[nameI]
+ << " cannot be found"
+ << abort(FatalError);
+ }
+
+ const unallocLabelList& curFaceCells =
+ mesh().boundaryMesh()[curFringePatch.index()].donorBasedLayeredOverlap();
+
+ forAll (curFaceCells, fcI)
+ {
+ // Check if cell is in region zone
+ if (rcz.whichCell(curFaceCells[fcI]) > -1)
+ {
+ // Found acceptor
+ acceptorSet.insert(curFaceCells[fcI]);
+ }
+ }
+ }
+
+ // Collect acceptors
+ acceptorsPtr_ = new labelList(acceptorSet.sortedToc());
+
+ // Holes are empty for this fringe
+ fringeHolesPtr_ = new labelList();
+}
+
+
+void Foam::donorBasedLayeredOverlapFringe::clearAddressing() const
+{
+ deleteDemandDrivenData(fringeHolesPtr_);
+ deleteDemandDrivenData(acceptorsPtr_);
+ deleteDemandDrivenData(finalDonorAcceptorsPtr_);
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+// Construct from dictionary
+Foam::donorBasedLayeredOverlapFringe::donorBasedLayeredOverlapFringe
+(
+ const fvMesh& mesh,
+ const oversetRegion& region,
+ const dictionary& dict
+)
+:
+ oversetFringe(mesh, region, dict),
+ connectedRegionIDs_(),
+ regionCentrePoints_
+ (
+ dict.lookupOrDefault("regionCentrePoints", pointList(0))
+ ),
+ nLayers_(readLabel(dict.lookup("nLayers"))),
+ fringeHolesPtr_(nullptr),
+ acceptorsPtr_(nullptr),
+ finalDonorAcceptorsPtr_(nullptr)
+{
+ // Read names of connected regions
+ const wordList connectedRegionNames(dict.lookup("connectedRegions"));
+
+ // Set size of the list containing IDs
+ connectedRegionIDs_.setSize(connectedRegionNames.size());
+
+ // Get list of all overset regions
+ const PtrList& allRegions =
+ this->region().overset().regions();
+
+ // Create list of all region names for easy lookup
+ wordList allRegionNames(allRegions.size());
+ forAll (allRegionNames, arI)
+ {
+ allRegionNames[arI] = allRegions[arI].name();
+ }
+
+ // Loop through all regions and check whether the overlap has been found
+ forAll (connectedRegion_, crI)
+ {
+ // Get name of this connected region
+ const word& crName = connectedRegion_[crI];
+
+ // Find this region in the list of all regions
+ const label regionID = findIndex(allRegions, crName);
+
+ if (regionID == -1)
+ {
+ FatalErrorIn
+ (
+ "donorBasedLayeredOverlapFringe::"
+ "donorBasedLayeredOverlapFringe\n"
+ "(\n"
+ " const fvMesh& mesh,\n"
+ " const oversetRegion& region,\n"
+ " const dictionary& dict\n"
+ ")"
+ ) << "Region " << crName << " not found in list of regions."
+ << "List of overset regions: " << allRegionNames
+ << abort(FatalError);
+ }
+
+ // Collect the region index in the list
+ connectedRegionIDs_[crI] = regionID;
+ }
+
+ // Sanity check: number of (optionally) specified centre points must be
+ // equal to the number of connected regions
+ if
+ (
+ regionCentrePoints_.size()
+ && (regionCentrePoints_.size() != connectedRegionIDs_.size())
+ )
+ {
+ // The list is not empty and the size of the list is not the same as the
+ // size of the connected regions. This is a problem
+ FatalErrorIn
+ (
+ "donorBasedLayeredOverlapFringe::"
+ "donorBasedLayeredOverlapFringe\n"
+ "(\n"
+ " const fvMesh& mesh,\n"
+ " const oversetRegion& region,\n"
+ " const dictionary& dict\n"
+ ")"
+ ) << "You have specified "
+ << regionCentrePoints_.size()
+ << " regionCentrePoints, while specifying "
+ << connectedRegionIDs_.size()
+ << " connectedRegions."
+ << nl
+ << "If you'd like to avoid using automatic centre point detection,"
+ << " make sure to specify centre points for all connected regions."
+ << abort(FatalError);
+ }
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
+
+Foam::donorBasedLayeredOverlapFringe::~donorBasedLayeredOverlapFringe()
+{
+ clearAddressing();
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+bool Foam::donorBasedLayeredOverlapFringe::updateIteration
+(
+ donorAcceptorList& donorAcceptorRegionData
+) const
+{
+ // If the donorAcceptor list has been allocated, something went wrong with
+ // the iteration procedure (not-updated flag): this function has been called
+ // more than once, which should not happen for donorBasedLayeredOverlapFringe
+ if (finalDonorAcceptorsPtr_)
+ {
+ FatalErrorIn
+ (
+ "donorBasedLayeredOverlapFringe::updateIteration(donorAcceptorList&"
+ ) << "finalDonorAcceptorPtr_ already allocated. Something went "
+ << "wrong with the iteration procedure (flag was not updated)."
+ << nl << "This should not happen for donorBasedLayeredOverlapFringe."
+ << abort(FatalError);
+ }
+
+ // Get list of all overset regions
+ const PtrList& allRegions =
+ this->region().overset().regions();
+
+ // Loop through all connected regions and check whether the fringe overlap
+ // has been found for all of them
+ bool allFringesReady = true;
+ forAll (connectedRegionIDs_, crI)
+ {
+ // Get ID of this region
+ const label& regionID = connectedRegionIDs_[crI];
+
+ // Get the overset region
+ const oversetRegion& region = allRegions[regionID];
+
+ // Get the fringe algorithm from the region
+ const oversetFringe& fringe = region.fringe();
+
+ // If this is not faceCells fringe, issue a Warning. This fringe
+ // selection algorithm is intended to work only with faceCells fringe on
+ // the other side. VV, 9/Apr/2019
+ if (!isA(fringe))
+ {
+ WarningIn
+ (
+ "void Foam::donorBasedLayeredOverlapFringe::"
+ "calcAddressing() const"
+ ) << "donorBasedLayeredOverlap fringe is designed to work"
+ << " with faceCells fringe as a connected region fringe."
+ << nl
+ << "Connected overset region " << region.name()
+ << " has " << fringe.type() " fringe type. "
+ << nl
+ << "Proceed with care!"
+ << endl;
+ }
+
+ // Update flag collecting whether all connected regions found the
+ // overlap
+ allFringesReady &= fringe.foundSuitableOverlap();
+ }
+
+ if (allFringesReady)
+ {
+ // Loop through connected regions
+ forAll (connectedRegionIDs_, crI)
+ {
+ // Get ID of this region
+ const label& regionID = connectedRegionIDs_[crI];
+
+ // Get fringe of the connected region
+ const oversetFringe& fringe = allRegions[regionID].fringe();
+
+ // The fringe should be finalized, which means we may take a const
+ // reference to its final donor acceptors
+ const donorAcceptorList& crDonorAcceptorPairs =
+ fringe.finalDonorAcceptors();
+
+ // Sanity check the validity of donor
+
+ // Mark donors on my processor from this connected region
+
+ // Calculate the centre for this connected region if it isn't
+ // specified
+
+ // Mark all future acceptors by moving towards the centre using
+ // face-neighbour walk nLayers times
+
+ // Now that the acceptors are marked, mark all remaining holes
+
+ }
+
+ // Allocate the list by reusing the argument list
+ finalDonorAcceptorsPtr_ = new donorAcceptorList
+ (
+ donorAcceptorRegionData,
+ true
+ );
+
+ // Set the flag to true and return
+ updateSuitableOverlapFlag(true);
+
+ return foundSuitableOverlap();
+ } // else connected fringes are not ready yet, foundSuitableOverlap flag is
+ // alraedy false, so there's nothing to do
+
+ return foundSuitablaOverlap();
+}
+
+
+const Foam::labelList& Foam::donorBasedLayeredOverlapFringe::fringeHoles() const
+{
+ if (!fringeHolesPtr_)
+ {
+ calcAddressing();
+ }
+
+ return *fringeHolesPtr_;
+}
+
+
+const Foam::labelList& Foam::donorBasedLayeredOverlapFringe::candidateAcceptors() const
+{
+ if (!acceptorsPtr_)
+ {
+ calcAddressing();
+ }
+
+ return *acceptorsPtr_;
+}
+
+
+Foam::donorAcceptorList& Foam::donorBasedLayeredOverlapFringe::finalDonorAcceptors() const
+{
+ if (!finalDonorAcceptorsPtr_)
+ {
+ FatalErrorIn("donorBasedLayeredOverlapFringe::finalDonorAcceptors()")
+ << "finalDonorAcceptorPtr_ not allocated. Make sure you have "
+ << "called donorBasedLayeredOverlapFringe::updateIteration() before asking for "
+ << "final set of donor/acceptor pairs."
+ << abort(FatalError);
+ }
+
+ if (!foundSuitableOverlap())
+ {
+ FatalErrorIn("donorBasedLayeredOverlapFringe::finalDonorAcceptors()")
+ << "Attemted to access finalDonorAcceptors but suitable overlap "
+ << "has not been found. This is not allowed. "
+ << abort(FatalError);
+ }
+
+ return *finalDonorAcceptorsPtr_;
+}
+
+
+void Foam::donorBasedLayeredOverlapFringe::update() const
+{
+ if (updateFringe_)
+ {
+ Info<< "donorBasedLayeredOverlapFringe::update() const" << endl;
+
+ // Clear out
+ clearAddressing();
+ }
+
+ // Set flag to false and clear final donor/acceptors only
+ deleteDemandDrivenData(finalDonorAcceptorsPtr_);
+}
+
+
+// ************************************************************************* //
diff --git a/src/overset/oversetMesh/oversetFringe/donorBasedLayeredOverlapFringe/donorBasedLayeredOverlap.H b/src/overset/oversetMesh/oversetFringe/donorBasedLayeredOverlapFringe/donorBasedLayeredOverlap.H
new file mode 100644
index 000000000..dd10a4e5c
--- /dev/null
+++ b/src/overset/oversetMesh/oversetFringe/donorBasedLayeredOverlapFringe/donorBasedLayeredOverlap.H
@@ -0,0 +1,164 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | foam-extend: Open Source CFD
+ \\ / O peration | Version: 4.1
+ \\ / A nd | Web: http://www.foam-extend.org
+ \\/ M anipulation | For copyright notice see file Copyright
+-------------------------------------------------------------------------------
+License
+ This file is part of foam-extend.
+
+ foam-extend 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.
+
+ foam-extend 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 foam-extend. If not, see .
+
+Class
+ donorBasedLayeredOverlapFringe
+
+Description
+ Fringe algorithm based on donors from different regions. The algorithm waits
+ until the final donor/acceptor assembly has been performed for all regions
+ whose donor region is this region. Then, all donors are collected and the
+ acceptors are cells neighbouring the donors nLayers towards the interior.
+ Interior is defined either by a user-specified point or as a centre of
+ volume of the donor cells.
+
+ This fringe algorithm is intended to be used along with the faceCells fringe
+ on the other side, where the cell sizes are not significantly different from
+ each other (e.g. 10:1 cell ratio will probably be problematic to correctly
+ set-up).
+
+Author
+ Vuko Vukcevic, Wikki Ltd. All rights reserved.
+
+SourceFiles
+ donorBasedLayeredOverlapFringe.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef donorBasedLayeredOverlapFringe_H
+#define donorBasedLayeredOverlapFringe_H
+
+#include "oversetFringe.H"
+#include "pointList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+ Class donorBasedLayeredOverlapFringe Declaration
+\*---------------------------------------------------------------------------*/
+
+class donorBasedLayeredOverlapFringe
+:
+ public oversetFringe
+{
+ // Private data
+
+ //- Regions IDs from which the donors will be collected as a starting
+ // point
+ labelList connectedRegionsIDs_;
+
+ //- Optional list of points representing a rough estimate of the centre
+ // for each underlying connected region. If these are not provided, the
+ // centre is calculated as the centre of volume of all donors for a
+ // given connected region
+ pointList regionCentrePoints_;
+
+ //- How many layers to move away from connected region donors to define
+ // acceptor (and holes)
+ label nLayers_;
+
+ //- Fringe hole cells
+ mutable labelList* fringeHolesPtr_;
+
+ //- Acceptor cells
+ mutable labelList* acceptorsPtr_;
+
+ //- Final donor/acceptor pairs for this region (fringe)
+ mutable donorAcceptorList* finalDonorAcceptorsPtr_;
+
+
+ // Private Member Functions
+
+ //- Disallow default bitwise copy construct
+ donorBasedLayeredOverlapFringe(const donorBasedLayeredOverlapFringe&);
+
+ //- Disallow default bitwise assignment
+ void operator=(const donorBasedLayeredOverlapFringe&);
+
+
+ // Calculate hole and acceptor addressing
+ void calcAddressing() const;
+
+ // Clear addressing
+ void clearAddressing() const;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("donorBasedLayeredOverlap");
+
+
+ // Constructors
+
+ //- Construct from dictionary
+ donorBasedLayeredOverlapFringe
+ (
+ const fvMesh& mesh,
+ const oversetRegion& region,
+ const dictionary& dict
+ );
+
+
+ // Destructor
+
+ virtual ~donorBasedLayeredOverlapFringe();
+
+
+ // Member Functions
+
+ //- Update iteration. Note: invalidates parameter
+ virtual bool updateIteration
+ (
+ donorAcceptorList& donorAcceptorRegionData
+ ) const;
+
+ //- Return list of deactivated (hole) cells
+ // Fringe hole cells are collected in addition to geometric hole
+ // cells, which fall outside of all donor regions
+ virtual const labelList& fringeHoles() const;
+
+ //- Return list of acceptor cells
+ virtual const labelList& candidateAcceptors() const;
+
+ //- Return list of final donor acceptor pairs. Note: caller may
+ // invalidate finalDonorAcceptorsPtr_ for optimisation purposes
+ virtual donorAcceptorList& finalDonorAcceptors() const;
+
+ //- Update the fringe
+ virtual void update() const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/overset/oversetMesh/oversetRegion/oversetRegion.C b/src/overset/oversetMesh/oversetRegion/oversetRegion.C
index 009cf948b..573b8d4d7 100644
--- a/src/overset/oversetMesh/oversetRegion/oversetRegion.C
+++ b/src/overset/oversetMesh/oversetRegion/oversetRegion.C
@@ -1730,6 +1730,20 @@ Foam::oversetRegion::~oversetRegion()
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
+const Foam::oversetFringe& Foam::oversetRegion::fringe() const
+{
+ if (fringePtr_.empty())
+ {
+ FatalErrorIn("const oversetFringe& oversetRegion::fringe() const")
+ << "Fringe pointer not allocated. It should have been initialized"
+ << " properly at construction. Something went wrong..."
+ << abort(FatalError);
+ }
+
+ return fringePtr_();
+}
+
+
const Foam::labelList& Foam::oversetRegion::donorRegions() const
{
if (!donorRegionsPtr_)
diff --git a/src/overset/oversetMesh/oversetRegion/oversetRegion.H b/src/overset/oversetMesh/oversetRegion/oversetRegion.H
index efdcb106a..346ef3c51 100644
--- a/src/overset/oversetMesh/oversetRegion/oversetRegion.H
+++ b/src/overset/oversetMesh/oversetRegion/oversetRegion.H
@@ -327,6 +327,9 @@ public:
return zone();
}
+ //- Return overset fringe algorithm for this region
+ const oversetFringe& fringe() const;
+
//- Return list of donor region indices
const labelList& donorRegions() const;