3.4
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
staticdrainge.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 *****************************************************************************/
19
25#ifndef DUMUX_PNM_TWOP_STATIC_DRAINAGE_HH
26#define DUMUX_PNM_TWOP_STATIC_DRAINAGE_HH
27
28#include <stack>
29#include <vector>
30
31namespace Dumux::PoreNetwork {
32
39template<class GridGeometry, class Scalar>
41{
42 using GridView = typename GridGeometry::GridView;
43
44public:
45
46 TwoPStaticDrainage(const GridGeometry& gridGeometry,
47 const std::vector<Scalar>& pcEntry,
48 const std::vector<int>& throatLabel,
49 const int inletPoreLabel,
50 const int outletPoreLabel,
51 const bool allowDraingeOfOutlet = false)
52 : gridView_(gridGeometry.gridView())
53 , pcEntry_(pcEntry)
54 , throatLabel_(throatLabel)
55 , inletThroatLabel_(inletPoreLabel)
56 , outletThroatLabel_(outletPoreLabel)
57 , allowDraingeOfOutlet_(allowDraingeOfOutlet)
58 {}
59
66 void updateInvasionState(std::vector<bool>& elementIsInvaded, const Scalar pcGlobal)
67 {
68 // iterate over all elements (throats)
69 for (const auto& element : elements(gridView_))
70 {
71 const auto eIdx = gridView_.indexSet().index(element);
72
73 // if the throat is already invaded, do nothing and continue
74 if (elementIsInvaded[eIdx])
75 continue;
76
77 // try to find a seed from which to start the search process
78 bool isSeed = false;
79
80 // start at the inlet boundary
81 if (throatLabel_[eIdx] == inletThroatLabel_ && pcGlobal >= pcEntry_[eIdx])
82 {
83 ++numThroatsInvaded_;
84 isSeed = true;
85 }
86
87 // if no throat gets invaded at the inlet, search the interior domain
88 if (!isSeed)
89 {
90 // find a throat which is not invaded yet but has an invaded neighbor (invasion-percolation)
91 for (const auto& intersection : intersections(gridView_, element))
92 {
93 if (intersection.neighbor())
94 {
95 const auto& neighborElement = intersection.outside();
96 const auto nIdx = gridView_.indexSet().index(neighborElement);
97 if (elementIsInvaded[nIdx] && pcGlobal >= pcEntry_[eIdx] && (allowDraingeOfOutlet_ || throatLabel_[eIdx] != outletThroatLabel_))
98 {
99 ++numThroatsInvaded_;
100 isSeed = true;
101 break;
102 }
103 }
104 }
105 }
106
107 // if an invaded throat is found, continue the search for neighboring invaded throats
108 if (isSeed)
109 {
110 elementIsInvaded[eIdx] = true;
111
112 // use iteration instead of recursion here because the recursion can get too deep
113 using Element = typename GridView::template Codim<0>::Entity;
114 std::stack<Element> elementStack;
115 elementStack.push(element);
116 while (!elementStack.empty())
117 {
118 auto e = elementStack.top();
119 elementStack.pop();
120
121 for (const auto& intersection : intersections(gridView_, e))
122 {
123 if (intersection.neighbor())
124 {
125 const auto& neighborElement = intersection.outside();
126 const auto nIdx = gridView_.indexSet().index(neighborElement);
127 if (!elementIsInvaded[nIdx] && pcGlobal >= pcEntry_[nIdx] && (allowDraingeOfOutlet_ || throatLabel_[nIdx] != outletThroatLabel_))
128 {
129 ++numThroatsInvaded_;
130 elementIsInvaded[nIdx] = true;
131 elementStack.push(neighborElement);
132 }
133 }
134 }
135 }
136 }
137 }
138 }
139
143 std::size_t numThroatsInvaded() const
144 { return numThroatsInvaded_; }
145
146private:
147 const GridView& gridView_;
148 const std::vector<Scalar>& pcEntry_;
149 const std::vector<int>& throatLabel_;
150 const int inletThroatLabel_;
151 const int outletThroatLabel_;
152 const int allowDraingeOfOutlet_;
153 std::size_t numThroatsInvaded_ = 0;
154};
155
156} // namespace Dumux::PoreNetwork
157
158#endif
Definition: discretization/porenetwork/fvelementgeometry.hh:33
Base class for the finite volume geometry for porenetwork models.
Definition: discretization/porenetwork/gridgeometry.hh:488
A (quasi-) static two-phase pore-network model for drainage processes. This assumes that there are no...
Definition: staticdrainge.hh:41
std::size_t numThroatsInvaded() const
Returns the number of invaded throats.
Definition: staticdrainge.hh:143
void updateInvasionState(std::vector< bool > &elementIsInvaded, const Scalar pcGlobal)
Updates the invasion state of the network for the given global capillary pressure.
Definition: staticdrainge.hh:66
TwoPStaticDrainage(const GridGeometry &gridGeometry, const std::vector< Scalar > &pcEntry, const std::vector< int > &throatLabel, const int inletPoreLabel, const int outletPoreLabel, const bool allowDraingeOfOutlet=false)
Definition: staticdrainge.hh:46