version 3.8
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// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
7
13#ifndef DUMUX_PNM_TWOP_STATIC_DRAINAGE_HH
14#define DUMUX_PNM_TWOP_STATIC_DRAINAGE_HH
15
16#include <stack>
17#include <vector>
18
19namespace Dumux::PoreNetwork {
20
27template<class GridGeometry, class Scalar>
29{
30 using GridView = typename GridGeometry::GridView;
31
32public:
33
34 TwoPStaticDrainage(const GridGeometry& gridGeometry,
35 const std::vector<Scalar>& pcEntry,
36 const std::vector<int>& throatLabel,
37 const int inletPoreLabel,
38 const int outletPoreLabel,
39 const bool allowDraingeOfOutlet = false)
40 : gridView_(gridGeometry.gridView())
41 , pcEntry_(pcEntry)
42 , throatLabel_(throatLabel)
43 , inletThroatLabel_(inletPoreLabel)
44 , outletThroatLabel_(outletPoreLabel)
45 , allowDraingeOfOutlet_(allowDraingeOfOutlet)
46 {}
47
54 void updateInvasionState(std::vector<bool>& elementIsInvaded, const Scalar pcGlobal)
55 {
56 // iterate over all elements (throats)
57 for (const auto& element : elements(gridView_))
58 {
59 const auto eIdx = gridView_.indexSet().index(element);
60
61 // if the throat is already invaded, do nothing and continue
62 if (elementIsInvaded[eIdx])
63 continue;
64
65 // try to find a seed from which to start the search process
66 bool isSeed = false;
67
68 // start at the inlet boundary
69 if (throatLabel_[eIdx] == inletThroatLabel_ && pcGlobal >= pcEntry_[eIdx])
70 {
71 ++numThroatsInvaded_;
72 isSeed = true;
73 }
74
75 // if no throat gets invaded at the inlet, search the interior domain
76 if (!isSeed)
77 {
78 // find a throat which is not invaded yet but has an invaded neighbor (invasion-percolation)
79 for (const auto& intersection : intersections(gridView_, element))
80 {
81 if (intersection.neighbor())
82 {
83 const auto& neighborElement = intersection.outside();
84 const auto nIdx = gridView_.indexSet().index(neighborElement);
85 if (elementIsInvaded[nIdx] && pcGlobal >= pcEntry_[eIdx] && (allowDraingeOfOutlet_ || throatLabel_[eIdx] != outletThroatLabel_))
86 {
87 ++numThroatsInvaded_;
88 isSeed = true;
89 break;
90 }
91 }
92 }
93 }
94
95 // if an invaded throat is found, continue the search for neighboring invaded throats
96 if (isSeed)
97 {
98 elementIsInvaded[eIdx] = true;
99
100 // use iteration instead of recursion here because the recursion can get too deep
101 using Element = typename GridView::template Codim<0>::Entity;
102 std::stack<Element> elementStack;
103 elementStack.push(element);
104 while (!elementStack.empty())
105 {
106 auto e = elementStack.top();
107 elementStack.pop();
108
109 for (const auto& intersection : intersections(gridView_, e))
110 {
111 if (intersection.neighbor())
112 {
113 const auto& neighborElement = intersection.outside();
114 const auto nIdx = gridView_.indexSet().index(neighborElement);
115 if (!elementIsInvaded[nIdx] && pcGlobal >= pcEntry_[nIdx] && (allowDraingeOfOutlet_ || throatLabel_[nIdx] != outletThroatLabel_))
116 {
117 ++numThroatsInvaded_;
118 elementIsInvaded[nIdx] = true;
119 elementStack.push(neighborElement);
120 }
121 }
122 }
123 }
124 }
125 }
126 }
127
131 std::size_t numThroatsInvaded() const
132 { return numThroatsInvaded_; }
133
134private:
135 const GridView& gridView_;
136 const std::vector<Scalar>& pcEntry_;
137 const std::vector<int>& throatLabel_;
138 const int inletThroatLabel_;
139 const int outletThroatLabel_;
140 const int allowDraingeOfOutlet_;
141 std::size_t numThroatsInvaded_ = 0;
142};
143
144} // namespace Dumux::PoreNetwork
145
146#endif
Base class for the finite volume geometry for porenetwork models.
Definition: discretization/porenetwork/gridgeometry.hh:477
A (quasi-) static two-phase pore-network model for drainage processes. This assumes that there are no...
Definition: staticdrainge.hh:29
std::size_t numThroatsInvaded() const
Returns the number of invaded throats.
Definition: staticdrainge.hh:131
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:54
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:34
Scalar pcEntry(const Scalar surfaceTension, const Scalar contactAngle, const Scalar inscribedRadius, const Scalar shapeFactor) noexcept
The entry capillary pressure of a pore throat.
Definition: thresholdcapillarypressures.hh:82
Definition: discretization/porenetwork/fvelementgeometry.hh:24