22#ifndef DUMUX_CCMPFA_FACETCOUPLING_MAPPER_HH
23#define DUMUX_CCMPFA_FACETCOUPLING_MAPPER_HH
25#include <dune/common/indices.hh>
26#include <dune/common/float_cmp.hh>
48template<
class BulkFVG,
class LowDimFVG, std::
size_t bulkId, std::
size_t lowDimId>
54 using BulkFVElementGeometry =
typename BulkFVG::LocalView;
55 using BulkSubControlVolumeFace =
typename BulkFVG::SubControlVolumeFace;
60 using LowDimElement =
typename LowDimFVG::GridView::template Codim<0>::Entity;
61 using GlobalPosition =
typename LowDimElement::Geometry::GlobalCoordinate;
62 static constexpr int lowDimDim = LowDimFVG::GridView::dimension;
66 using ParentType::bulkGridId;
67 using ParentType::facetGridId;
77 template<
class Embeddings >
78 void update(
const BulkFVG& bulkFvGridGeometry,
79 const LowDimFVG& lowDimFvGridGeometry,
80 std::shared_ptr<const Embeddings> embeddings)
84 update(bulkFvGridGeometry, lowDimFvGridGeometry, embeddings, GridAdapter(embeddings));
96 template<
class Embeddings,
class CodimOneGr
idAdapter >
97 void update(
const BulkFVG& bulkFvGridGeometry,
98 const LowDimFVG& lowDimFvGridGeometry,
99 std::shared_ptr<const Embeddings> embeddings,
103 auto addCouplingEntryPolicy = [&] (
auto&& adjoinedEntityIndices,
104 const LowDimElement& lowDimElement,
105 const LowDimFVG& lowDimFvGridGeometry,
106 const BulkFVG& bulkFvGridGeometry)
108 const auto lowDimElemIdx = lowDimFvGridGeometry.elementMapper().index(lowDimElement);
109 auto& lowDimData = this->couplingMap_(facetGridId, bulkGridId)[lowDimElemIdx];
112 const auto& lowDimGeometry = lowDimElement.geometry();
113 const auto numElementCorners = lowDimElement.subEntities(lowDimDim);
114 std::vector<BulkIndexType> elemCornerIndices(numElementCorners);
115 for (
int i = 0; i < numElementCorners; ++i)
116 elemCornerIndices[i] = codimOneGridAdapter.
bulkGridVertexIndex(lowDimElement.template subEntity<lowDimDim>(i));
119 auto fvGeometry =
localView(bulkFvGridGeometry);
120 for (
auto bulkElemIdx : adjoinedEntityIndices)
122 const auto bulkElement = bulkFvGridGeometry.element(bulkElemIdx);
123 fvGeometry.bind(bulkElement);
125 std::vector<BulkIndexType> embeddedScvfIndices;
126 for (
const auto& scvf : scvfs(fvGeometry))
130 if (!scvf.boundary())
132 if ( std::count(adjoinedEntityIndices.begin(), adjoinedEntityIndices.end(), scvf.outsideScvIdx()) )
133 embeddedScvfIndices.push_back(scvf.index());
139 const auto eps = lowDimGeometry.volume()*1e-8;
140 const auto diffVec = lowDimGeometry.center()-scvf.facetCorner();
142 if ( Dune::FloatCmp::eq<GlobalPosition, Dune::FloatCmp::CmpStyle::absolute>(diffVec, GlobalPosition(0.0), eps) )
143 embeddedScvfIndices.push_back(scvf.index());
148 if ( embeddedScvfIndices.size() != numElementCorners )
149 DUNE_THROW(Dune::InvalidStateException,
"Could not find all coupling scvfs in embedment");
152 auto& bulkData = this->couplingMap_(bulkGridId, facetGridId)[bulkElemIdx];
154 ? this->extractNodalDofs_(lowDimElement, lowDimFvGridGeometry)
155 : std::vector<LowDimIndexType>( {lowDimElemIdx} );
158 for (
auto dofIdx : lowDimElementDofs)
159 for (
auto scvfIdx : embeddedScvfIndices)
160 this->addCouplingsFromIV_(bulkFvGridGeometry, fvGeometry.scvf(scvfIdx), fvGeometry, lowDimElemIdx, dofIdx);
166 const auto copy = embeddedScvfIndices;
168 for (
unsigned int i = 0; i < numElementCorners; ++i)
170 const auto& scvf = fvGeometry.scvf(copy[i]);
171 auto it = std::find(elemCornerIndices.begin(), elemCornerIndices.end(), scvf.vertexIndex());
172 assert(it != elemCornerIndices.end());
173 embeddedScvfIndices[
std::distance(elemCornerIndices.begin(), it) ] = copy[i];
178 auto& elemToScvfMap = bulkData.elementToScvfMap[lowDimElemIdx];
179 elemToScvfMap.insert(elemToScvfMap.end(), embeddedScvfIndices.begin(), embeddedScvfIndices.end());
182 lowDimData.embedments.emplace_back( bulkElemIdx, std::move(embeddedScvfIndices) );
187 ParentType::update_(bulkFvGridGeometry, lowDimFvGridGeometry, embeddings, addCouplingEntryPolicy);
190 auto makeUnique = [] (
auto& c)
192 std::sort(c.begin(), c.end());
193 c.erase( std::unique(c.begin(), c.end()), c.end() );
197 auto makeBulkMapEntryUnique = [&makeUnique] (
auto& data)
199 makeUnique(data.second.couplingStencil);
200 makeUnique(data.second.couplingElementStencil);
201 std::for_each(data.second.dofToCouplingScvfMap.begin(),
202 data.second.dofToCouplingScvfMap.end(),
203 [&makeUnique] (
auto& pair) { makeUnique(pair.second); });
207 auto& bulkCouplingData = this->couplingMap_(bulkGridId, facetGridId);
208 std::for_each(bulkCouplingData.begin(), bulkCouplingData.end(), makeBulkMapEntryUnique);
211 auto& lowDimCouplingData = this->couplingMap_(facetGridId, bulkGridId);
212 std::for_each(lowDimCouplingData.begin(),
213 lowDimCouplingData.end(),
214 [&makeUnique] (
auto& pair) { makeUnique(pair.second.couplingStencil); });
218 void addCouplingsFromIV_(
const BulkFVG& bulkFvGridGeometry,
219 const BulkSubControlVolumeFace& scvf,
220 const BulkFVElementGeometry& fvGeometry,
221 LowDimIndexType lowDimElemIdx,
222 LowDimIndexType lowDimDofIdx)
224 const auto& gridIvIndexSets = bulkFvGridGeometry.gridInteractionVolumeIndexSets();
225 if (bulkFvGridGeometry.vertexUsesSecondaryInteractionVolume(scvf.vertexIndex()))
226 addCouplingsFromIVIndexSet_(gridIvIndexSets.secondaryIndexSet(scvf), fvGeometry, lowDimElemIdx, lowDimDofIdx);
228 addCouplingsFromIVIndexSet_(gridIvIndexSets.primaryIndexSet(scvf), fvGeometry, lowDimElemIdx, lowDimDofIdx);
231 template<
class IVIndexSet >
232 void addCouplingsFromIVIndexSet_(
const IVIndexSet& indexSet,
233 const BulkFVElementGeometry& fvGeometry,
234 LowDimIndexType lowDimElemIdx,
235 LowDimIndexType lowDimDofIdx)
237 auto& lowDimData = this->couplingMap_(facetGridId, bulkGridId)[lowDimElemIdx];
238 for (
auto bulkElemIdx : indexSet.gridScvIndices())
240 auto& bulkData = this->couplingMap_(bulkGridId, facetGridId)[bulkElemIdx];
242 lowDimData.couplingStencil.push_back( bulkElemIdx );
243 bulkData.couplingStencil.push_back( lowDimDofIdx );
244 bulkData.couplingElementStencil.push_back( lowDimElemIdx );
248 for (
auto scvfIdx : indexSet.gridScvfIndices())
250 const auto& scvf = fvGeometry.scvf(scvfIdx);
251 auto& bulkData = this->couplingMap_(bulkGridId, facetGridId)[scvf.insideScvIdx()];
252 auto& couplingScvfs = bulkData.dofToCouplingScvfMap[lowDimDofIdx];
253 couplingScvfs.insert(couplingScvfs.end(), scvfIdx);
Defines the index types used for grid and local indices.
The available discretization methods in Dumux.
static ctype distance(const Dune::FieldVector< ctype, dimWorld > &a, const Dune::FieldVector< ctype, dimWorld > &b)
Compute the shortest distance between two points.
Definition: distance.hh:292
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
constexpr Box box
Definition: method.hh:139
typename GridView::IndexSet::IndexType GridIndex
Definition: indextraits.hh:39
void update(const BulkFVG &bulkFvGridGeometry, const LowDimFVG &lowDimFvGridGeometry, std::shared_ptr< const Embeddings > embeddings, const CodimOneGridAdapter &codimOneGridAdapter)
Update coupling maps. This is the standard interface required by any mapper implementation.
Definition: facet/cellcentered/mpfa/couplingmapper.hh:97
void update(const BulkFVG &bulkFvGridGeometry, const LowDimFVG &lowDimFvGridGeometry, std::shared_ptr< const Embeddings > embeddings)
Update coupling maps. This is the standard interface required by any mapper implementation.
Definition: facet/cellcentered/mpfa/couplingmapper.hh:78
Adapter that allows retrieving information on a d-dimensional grid for entities of a (d-1)-dimensiona...
Definition: codimonegridadapter.hh:52
BulkIndexType bulkGridVertexIndex(const FacetGridVertex &v) const
Returns the index within the d-dimensional grid of a vertex of the (d-1)-dimensional grid.
Definition: codimonegridadapter.hh:145
Implementation for the coupling mapper that sets up and stores the coupling maps between two domains ...
Definition: facet/couplingmapper.hh:52
Base class for the coupling mapper that sets up and stores the coupling maps between two domains of d...
Definition: couplingmapperbase.hh:51