3.2-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
Loading...
Searching...
No Matches
facet/cellcentered/mpfa/couplingmapper.hh
Go to the documentation of this file.
1/*****************************************************************************
2 * See the file COPYING for full copying permissions. *
3 * *
4 * This program is free software: you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation, either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 *****************************************************************************/
22#ifndef DUMUX_CCMPFA_FACETCOUPLING_MAPPER_HH
23#define DUMUX_CCMPFA_FACETCOUPLING_MAPPER_HH
24
25#include <dune/common/indices.hh>
26#include <dune/common/float_cmp.hh>
27
33
34namespace Dumux {
35
48template<class BulkFVG, class LowDimFVG, std::size_t bulkId, std::size_t lowDimId>
49class FacetCouplingMapper<BulkFVG, LowDimFVG, bulkId, lowDimId, DiscretizationMethod::ccmpfa>
50: public virtual FacetCouplingMapperBase<BulkFVG, LowDimFVG, bulkId, lowDimId>
51{
53
54 using BulkFVElementGeometry = typename BulkFVG::LocalView;
55 using BulkSubControlVolumeFace = typename BulkFVG::SubControlVolumeFace;
56
57 using BulkIndexType = typename IndexTraits<typename BulkFVG::GridView>::GridIndex;
58 using LowDimIndexType = typename IndexTraits<typename LowDimFVG::GridView>::GridIndex;
59
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;
63
64public:
68
77 template< class Embeddings >
78 void update(const BulkFVG& bulkFvGridGeometry,
79 const LowDimFVG& lowDimFvGridGeometry,
80 std::shared_ptr<const Embeddings> embeddings)
81 {
82 // forward to update function with instantiated vertex adapter
84 update(bulkFvGridGeometry, lowDimFvGridGeometry, embeddings, GridAdapter(embeddings));
85 }
86
96 template< class Embeddings, class CodimOneGridAdapter >
97 void update(const BulkFVG& bulkFvGridGeometry,
98 const LowDimFVG& lowDimFvGridGeometry,
99 std::shared_ptr<const Embeddings> embeddings,
100 const CodimOneGridAdapter& codimOneGridAdapter)
101 {
102 // define the policy how to add map entries for given lowdim element and adjoined entity indices
103 auto addCouplingEntryPolicy = [&] (auto&& adjoinedEntityIndices,
104 const LowDimElement& lowDimElement,
105 const LowDimFVG& lowDimFvGridGeometry,
106 const BulkFVG& bulkFvGridGeometry)
107 {
108 const auto lowDimElemIdx = lowDimFvGridGeometry.elementMapper().index(lowDimElement);
109 auto& lowDimData = this->couplingMap_(facetGridId, bulkGridId)[lowDimElemIdx];
110
111 // determine corner indices (in bulk grid indices)
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));
117
118 // Find the scvfs in the adjoined entities coinciding with the low dim element
119 for (auto bulkElemIdx : adjoinedEntityIndices)
120 {
121 const auto bulkElement = bulkFvGridGeometry.element(bulkElemIdx);
122
123 auto fvGeometry = localView(bulkFvGridGeometry);
124 fvGeometry.bind(bulkElement);
125
126 std::vector<BulkIndexType> embeddedScvfIndices;
127 for (const auto& scvf : scvfs(fvGeometry))
128 {
129 // for non-boundary faces, it suffices to check if one
130 // of the outside scv indices is in the set of embedments
131 if (!scvf.boundary())
132 {
133 if ( std::count(adjoinedEntityIndices.begin(), adjoinedEntityIndices.end(), scvf.outsideScvIdx()) )
134 embeddedScvfIndices.push_back(scvf.index());
135 }
136
137 // otherwise, do float comparison of element and scvf facet corner
138 else
139 {
140 const auto eps = lowDimGeometry.volume()*1e-8;
141 const auto diffVec = lowDimGeometry.center()-scvf.facetCorner();
142
143 if ( Dune::FloatCmp::eq<GlobalPosition, Dune::FloatCmp::CmpStyle::absolute>(diffVec, GlobalPosition(0.0), eps) )
144 embeddedScvfIndices.push_back(scvf.index());
145 }
146 }
147
148 // Error tracking. The boundary scvf detection might has to be improved for very fine grids!?
149 if ( embeddedScvfIndices.size() != numElementCorners )
150 DUNE_THROW(Dune::InvalidStateException, "Could not find all coupling scvfs in embedment");
151
152 // add each dof in the low dim element to coupling stencil of the bulk element and vice versa
153 auto& bulkData = this->couplingMap_(bulkGridId, facetGridId)[bulkElemIdx];
154 const auto lowDimElementDofs = LowDimFVG::discMethod == DiscretizationMethod::box
155 ? this->extractNodalDofs_(lowDimElement, lowDimFvGridGeometry)
156 : std::vector<LowDimIndexType>( {lowDimElemIdx} );
157
158 // add coupling info to all elements/scvfs in interaction volumes
159 for (auto dofIdx : lowDimElementDofs)
160 for (auto scvfIdx : embeddedScvfIndices)
161 this->addCouplingsFromIV_(bulkFvGridGeometry, fvGeometry.scvf(scvfIdx), fvGeometry, lowDimElemIdx, dofIdx);
162
163 // sort the scvfs according to the corners of the low dim element if box is used
164 // that allows identifying which scvf flux enters which low dim scv later
165 if (LowDimFVG::discMethod == DiscretizationMethod::box)
166 {
167 const auto copy = embeddedScvfIndices;
168
169 for (unsigned int i = 0; i < numElementCorners; ++i)
170 {
171 const auto& scvf = fvGeometry.scvf(copy[i]);
172 auto it = std::find(elemCornerIndices.begin(), elemCornerIndices.end(), scvf.vertexIndex());
173 assert(it != elemCornerIndices.end());
174 embeddedScvfIndices[ std::distance(elemCornerIndices.begin(), it) ] = copy[i];
175 }
176 }
177
178 // add info on which scvfs coincide with which low dim element
179 auto& elemToScvfMap = bulkData.elementToScvfMap[lowDimElemIdx];
180 elemToScvfMap.insert(elemToScvfMap.end(), embeddedScvfIndices.begin(), embeddedScvfIndices.end());
181
182 // add embedment
183 lowDimData.embedments.emplace_back( bulkElemIdx, std::move(embeddedScvfIndices) );
184 }
185 };
186
187 // let the parent do the update subject to the execution policy defined above
188 ParentType::update_(bulkFvGridGeometry, lowDimFvGridGeometry, embeddings, addCouplingEntryPolicy);
189
190 // lambda to make a container unique
191 auto makeUnique = [] (auto& c)
192 {
193 std::sort(c.begin(), c.end());
194 c.erase( std::unique(c.begin(), c.end()), c.end() );
195 };
196
197 // lambda to make bulk coupling map entry unique
198 auto makeBulkMapEntryUnique = [&makeUnique] (auto& data)
199 {
200 makeUnique(data.second.couplingStencil);
201 makeUnique(data.second.couplingElementStencil);
202 std::for_each(data.second.dofToCouplingScvfMap.begin(),
203 data.second.dofToCouplingScvfMap.end(),
204 [&makeUnique] (auto& pair) { makeUnique(pair.second); });
205 };
206
207 // make bulk map unique
208 auto& bulkCouplingData = this->couplingMap_(bulkGridId, facetGridId);
209 std::for_each(bulkCouplingData.begin(), bulkCouplingData.end(), makeBulkMapEntryUnique);
210
211 // coupling stencils might not be unique in lowdim domain
212 auto& lowDimCouplingData = this->couplingMap_(facetGridId, bulkGridId);
213 std::for_each(lowDimCouplingData.begin(),
214 lowDimCouplingData.end(),
215 [&makeUnique] (auto& pair) { makeUnique(pair.second.couplingStencil); });
216 }
217
218private:
219 void addCouplingsFromIV_(const BulkFVG& bulkFvGridGeometry,
220 const BulkSubControlVolumeFace& scvf,
221 const BulkFVElementGeometry& fvGeometry,
222 LowDimIndexType lowDimElemIdx,
223 LowDimIndexType lowDimDofIdx)
224 {
225 const auto& gridIvIndexSets = bulkFvGridGeometry.gridInteractionVolumeIndexSets();
226 if (bulkFvGridGeometry.vertexUsesSecondaryInteractionVolume(scvf.vertexIndex()))
227 addCouplingsFromIVIndexSet_(gridIvIndexSets.secondaryIndexSet(scvf), fvGeometry, lowDimElemIdx, lowDimDofIdx);
228 else
229 addCouplingsFromIVIndexSet_(gridIvIndexSets.primaryIndexSet(scvf), fvGeometry, lowDimElemIdx, lowDimDofIdx);
230 }
231
232 template< class IVIndexSet >
233 void addCouplingsFromIVIndexSet_(const IVIndexSet& indexSet,
234 const BulkFVElementGeometry& fvGeometry,
235 LowDimIndexType lowDimElemIdx,
236 LowDimIndexType lowDimDofIdx)
237 {
238 auto& lowDimData = this->couplingMap_(facetGridId, bulkGridId)[lowDimElemIdx];
239 for (auto bulkElemIdx : indexSet.gridScvIndices())
240 {
241 auto& bulkData = this->couplingMap_(bulkGridId, facetGridId)[bulkElemIdx];
242
243 lowDimData.couplingStencil.push_back( bulkElemIdx );
244 bulkData.couplingStencil.push_back( lowDimDofIdx );
245 bulkData.couplingElementStencil.push_back( lowDimElemIdx );
246 }
247
248 // insert scvf couplings stemming from this interaction volume
249 for (auto scvfIdx : indexSet.gridScvfIndices())
250 {
251 const auto& scvf = fvGeometry.scvf(scvfIdx);
252 auto& bulkData = this->couplingMap_(bulkGridId, facetGridId)[scvf.insideScvIdx()];
253 auto& couplingScvfs = bulkData.dofToCouplingScvfMap[lowDimDofIdx];
254 couplingScvfs.insert(couplingScvfs.end(), scvfIdx);
255 }
256 }
257};
258
259} // end namespace Dumux
260
261#endif // DUMUX_FACETCOUPLING_CCMPFA_COUPLING_MAPPER_HH
Defines the index types used for grid and local indices.
The available discretization methods in Dumux.
Base class for the coupling mapper that sets up and stores the coupling maps between two domains of d...
Adapter that allows retrieving information on a d-dimensional grid for entities of a (d-1)-dimensiona...
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition localview.hh:38
DiscretizationMethod
The available discretization methods in Dumux.
Definition method.hh:37
@ box
Definition method.hh:38
@ ccmpfa
Definition method.hh:38
Definition adapt.hh:29
typename GridView::IndexSet::IndexType GridIndex
Definition indextraits.hh:39
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
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
static constexpr auto bulkGridId
export domain ids
Definition couplingmapperbase.hh:129
Adapter that allows retrieving information on a d-dimensional grid for entities of a (d-1)-dimensiona...
Definition codimonegridadapter.hh:53
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:147
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
static constexpr auto facetGridId
Definition couplingmapperbase.hh:130
std::vector< typename IndexTraits< typename GridGeometry::GridView >::GridIndex > extractNodalDofs_(const typename GridGeometry::GridView::template Codim< 0 >::Entity &element, const GridGeometry &gridGeometry)
Creates a container with the nodal dofs within an element.
Definition couplingmapperbase.hh:210
void update_(const BulkFVG &bulkFvGridGeometry, const LowDimFVG &lowDimFvGridGeometry, std::shared_ptr< const Embeddings > embeddings, AddCouplingEntryPolicy &&addCouplingEntryPolicy)
Update coupling maps.
Definition couplingmapperbase.hh:175
static constexpr auto bulkGridId
Export grid ids.
Definition couplingmapperbase.hh:129
BulkCouplingMap & couplingMap_(GridIdType< bulkId >, GridIdType< lowDimId >)
returns non-const coupling data for bulk -> lowDim
Definition couplingmapperbase.hh:225
Implementation for the coupling mapper that sets up and stores the coupling maps between two domains ...