3.5-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
boundary/stokesdarcy/couplingmapper.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*****************************************************************************
4 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
25#ifndef DUMUX_STOKES_DARCY_COUPLINGMAPPER_HH
26#define DUMUX_STOKES_DARCY_COUPLINGMAPPER_HH
27
28#include <type_traits>
29#include <unordered_map>
30#include <vector>
31
32#include <dune/common/exceptions.hh>
34
35namespace Dumux {
36
42{
43 struct ElementMapInfo
44 {
45 std::size_t eIdx;
46 std::size_t scvfIdx;
47 std::size_t flipScvfIdx;
48 };
49
50public:
51
55 template<class CouplingManager, class Stencils>
57 Stencils& darcyToStokesCellCenterStencils,
58 Stencils& darcyToStokesFaceStencils,
59 Stencils& stokesCellCenterToDarcyStencils,
60 Stencils& stokesFaceToDarcyStencils)
61 {
62 const auto& stokesFvGridGeometry = couplingManager.problem(CouplingManager::stokesIdx).gridGeometry();
63 const auto& darcyFvGridGeometry = couplingManager.problem(CouplingManager::darcyIdx).gridGeometry();
64
65 static_assert(std::decay_t<decltype(stokesFvGridGeometry)>::discMethod == DiscretizationMethods::staggered,
66 "The free flow domain must use the staggered discretization");
67
68 static_assert(std::decay_t<decltype(darcyFvGridGeometry)>::discMethod == DiscretizationMethods::cctpfa,
69 "The Darcy domain must use the CCTpfa discretization");
70
71 isCoupledDarcyScvf_.resize(darcyFvGridGeometry.numScvf(), false);
72
73 const auto& stokesGridView = stokesFvGridGeometry.gridView();
74 auto stokesFvGeometry = localView(stokesFvGridGeometry);
75 for (const auto& stokesElement : elements(stokesGridView))
76 {
77 stokesFvGeometry.bindElement(stokesElement);
78
79 for (const auto& scvf : scvfs(stokesFvGeometry))
80 {
81 // skip the DOF if it is not on the boundary
82 if (!scvf.boundary())
83 continue;
84
85 // get element intersecting with the scvf center
86 // for robustness, add epsilon in unit outer normal direction
87 const auto eps = (scvf.center() - stokesElement.geometry().center()).two_norm()*1e-8;
88 auto globalPos = scvf.center(); globalPos.axpy(eps, scvf.unitOuterNormal());
89 const auto darcyElementIdx = intersectingEntities(globalPos, darcyFvGridGeometry.boundingBoxTree());
90
91 // skip if no intersection was found
92 if (darcyElementIdx.empty())
93 continue;
94
95 // sanity check
96 if (darcyElementIdx.size() > 1)
97 DUNE_THROW(Dune::InvalidStateException, "Stokes face dof should only intersect with one Darcy element");
98
99 const auto stokesElementIdx = stokesFvGridGeometry.elementMapper().index(stokesElement);
100
101 const auto darcyDofIdx = darcyElementIdx[0];
102
103 stokesFaceToDarcyStencils[scvf.dofIndex()].push_back(darcyDofIdx);
104 stokesCellCenterToDarcyStencils[stokesElementIdx].push_back(darcyDofIdx);
105
106 darcyToStokesFaceStencils[darcyElementIdx[0]].push_back(scvf.dofIndex());
107 darcyToStokesCellCenterStencils[darcyElementIdx[0]].push_back(stokesElementIdx);
108
109 const auto& darcyElement = darcyFvGridGeometry.element(darcyElementIdx[0]);
110 const auto darcyFvGeometry = localView(darcyFvGridGeometry).bindElement(darcyElement);
111
112 // find the corresponding Darcy sub control volume face
113 for (const auto& darcyScvf : scvfs(darcyFvGeometry))
114 {
115 const auto distance = (darcyScvf.center() - scvf.center()).two_norm();
116
117 if (distance < eps)
118 {
119 isCoupledDarcyScvf_[darcyScvf.index()] = true;
120 darcyElementToStokesElementMap_[darcyElementIdx[0]].push_back({stokesElementIdx, scvf.index(), darcyScvf.index()});
121 stokesElementToDarcyElementMap_[stokesElementIdx].push_back({darcyElementIdx[0], darcyScvf.index(), scvf.index()});
122 }
123 }
124 }
125 }
126 }
127
131 bool isCoupledDarcyScvf(std::size_t darcyScvfIdx) const
132 {
133 return isCoupledDarcyScvf_[darcyScvfIdx];
134 }
135
140 {
141 return darcyElementToStokesElementMap_;
142 }
143
148 {
149 return stokesElementToDarcyElementMap_;
150 }
151
152private:
153 std::unordered_map<std::size_t, std::vector<ElementMapInfo>> darcyElementToStokesElementMap_;
154 std::unordered_map<std::size_t, std::vector<ElementMapInfo>> stokesElementToDarcyElementMap_;
155
156 std::vector<bool> isCoupledDarcyScvf_;
157};
158
159} // end namespace Dumux
160
161#endif
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
std::vector< std::size_t > intersectingEntities(const Dune::FieldVector< ctype, dimworld > &point, const BoundingBoxTree< EntitySet > &tree, bool isCartesianGrid=false)
Compute all intersections between entities and a point.
Definition: intersectingentities.hh:112
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
Definition: adapt.hh:29
constexpr CCTpfa cctpfa
Definition: method.hh:137
constexpr Staggered staggered
Definition: method.hh:140
Coupling mapper for Stokes and Darcy domains with equal dimension.
Definition: boundary/stokesdarcy/couplingmapper.hh:42
bool isCoupledDarcyScvf(std::size_t darcyScvfIdx) const
Returns whether a Darcy scvf is coupled to the other domain.
Definition: boundary/stokesdarcy/couplingmapper.hh:131
void computeCouplingMapsAndStencils(const CouplingManager &couplingManager, Stencils &darcyToStokesCellCenterStencils, Stencils &darcyToStokesFaceStencils, Stencils &stokesCellCenterToDarcyStencils, Stencils &stokesFaceToDarcyStencils)
Main update routine.
Definition: boundary/stokesdarcy/couplingmapper.hh:56
const auto & darcyElementToStokesElementMap() const
A map that returns all Stokes elements coupled to a Darcy element.
Definition: boundary/stokesdarcy/couplingmapper.hh:139
const auto & stokesElementToDarcyElementMap() const
A map that returns all Darcy elements coupled to a Stokes element.
Definition: boundary/stokesdarcy/couplingmapper.hh:147
The interface of the coupling manager for multi domain problems.
Definition: multidomain/couplingmanager.hh:60
const Problem< i > & problem(Dune::index_constant< i > domainIdx) const
Return a reference to the sub problem.
Definition: multidomain/couplingmanager.hh:321