GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/examples/porenetwork_upscaling/problem.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 28 41 68.3%
Functions: 8 22 36.4%
Branches: 37 76 48.7%

Line Branch Exec Source
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
8 #ifndef DUMUX_PNM_ONEP_PERMEABILITY_UPSCALING_PROBLEM_HH
9 #define DUMUX_PNM_ONEP_PERMEABILITY_UPSCALING_PROBLEM_HH
10
11 // ## The problem class (`problem.hh`)
12 // This file contains the __problem class__ which defines the initial and boundary
13 // conditions for the single-phase flow simulation.
14 // [[content]]
15 // ### Includes
16 #include <dumux/common/boundarytypes.hh> // for `BoundaryTypes`
17 #include <dumux/common/properties.hh> // for `GetPropType`
18 #include <dumux/common/parameters.hh> // for `getParam`
19 #include <dumux/porousmediumflow/problem.hh> // for `PorousMediumFlowProblem`
20
21 // ### The problem class
22 // We enter the problem class where all necessary boundary conditions and initial conditions are set for our simulation.
23 // As this is a porous medium flow problem, we inherit from the base class `PorousMediumFlowProblem`.
24 namespace Dumux {
25
26 template<class TypeTag>
27 4 class UpscalingProblem : public PorousMediumFlowProblem<TypeTag>
28 {
29 // [[details]] convenience aliases
30 // [[codeblock]]
31 using ParentType = PorousMediumFlowProblem<TypeTag>;
32 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
33 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
34 using FVElementGeometry = typename GridGeometry::LocalView;
35 using SubControlVolume = typename GridGeometry::SubControlVolume;
36 using Element = typename GridGeometry::GridView::template Codim<0>::Entity;
37 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
38 using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
39 using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
40 using BoundaryTypes = Dumux::BoundaryTypes<PrimaryVariables::size()>;
41 // [[/codeblock]]
42 // [[/details]]
43 //
44 // #### The constructor of our problem.
45 // [[codeblock]]
46 public:
47 4 UpscalingProblem(std::shared_ptr<const GridGeometry> gridGeometry)
48
7/18
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✓ Branch 15 taken 2 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
12 : ParentType(gridGeometry)
49 {
50 // the applied pressure gradient
51
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 pressureGradient_ = getParam<Scalar>("Problem.PressureGradient", 1e5);
52
53 // We can either use pore labels (given in the grid file) to identify inlet and outlet pores
54 // or use the network's bounding box to find these pores automatically. Using labels is usually much
55 // more accurate, so this is the default here.
56
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 useLabels_ = getParam<bool>("Problem.UseLabels", true);
57
58 // an epsilon value for the floating point comparisons to determine inlet/outlet pores
59
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 eps_ = getParam<Scalar>("Problem.Epsilon", 1e-7);
60 4 }
61 // [[/codeblock]]
62
63 // #### Temperature
64 // We need to specify a constant temperature for our isothermal problem.
65 // Fluid properties that depend on temperature will be calculated with this value.
66 // [[codeblock]]
67 Scalar temperature() const
68 { return 283.15; }
69 // [[/codeblock]]
70
71 // Set the pressure gradient to be applied to the network
72 void setPressureGradient(Scalar pressureGradient)
73
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
20 { pressureGradient_ = pressureGradient; }
74
75 // #### Boundary conditions
76 // This function is used to define the __type of boundary conditions__ used depending on the location.
77 // Here, we use Dirichlet boundary conditions (fixed pressures) at the inlet and outlet. Note that the PNM does not support Neumann boundaries.
78 // To specify a certain mass flux on a boundary, we would have to use a source term on the boundary pores (which is not done in this example).
79 // [[codeblock]]
80 461188 BoundaryTypes boundaryTypes(const Element &element, const SubControlVolume& scv) const
81 {
82
1/2
✓ Branch 0 taken 230594 times.
✗ Branch 1 not taken.
461188 BoundaryTypes bcTypes;
83
84 // fix the pressure at the inlet and outlet pores
85
4/4
✓ Branch 0 taken 174174 times.
✓ Branch 1 taken 56420 times.
✓ Branch 2 taken 53781 times.
✓ Branch 3 taken 120393 times.
809536 if (isInletPore_(scv)|| isOutletPore_(scv))
86 bcTypes.setAllDirichlet();
87
88 461188 return bcTypes;
89 }
90 // [[/codeblock]]
91
92 // The following function specifies the __values on Dirichlet boundaries__ (pressures).
93 // We set 0 Pa at the outlet and a value based on the given pressure gradient
94 // and the length of the domain at the inlet.
95 // [[codeblock]]
96 171962 PrimaryVariables dirichlet(const Element& element,
97 const SubControlVolume& scv) const
98 {
99
1/2
✓ Branch 0 taken 85981 times.
✗ Branch 1 not taken.
171962 PrimaryVariables values(0.0);
100
101
2/2
✓ Branch 0 taken 44020 times.
✓ Branch 1 taken 41961 times.
171962 if (isInletPore_(scv))
102 176080 values[Indices::pressureIdx] = pressureGradient_ * length_[direction_];
103 else
104 values[Indices::pressureIdx] = 0.0;
105
106 171962 return values;
107 }
108 // [[/codeblock]]
109
110 // #### Upscaling
111
112 // [[details]] auxiliary functions needed for the upscaling process
113 // [[codeblock]]
114
115 // Set the current direction (0:x, 1:y, 2:z) in which the pressure gradient is applied
116 void setDirection(int directionIdx)
117 2 { direction_ = directionIdx; }
118
119 // Get the current direction in which the pressure gradient is applied.
120 int direction() const
121 { return direction_; }
122
123 // Set the side lengths to consider for the upscaling process.
124 void setSideLengths(const GlobalPosition& sideLengths)
125
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 { length_ = sideLengths; }
126
127 // Return the side lengths to consider for the upscaling process.
128 const GlobalPosition& sideLengths() const
129 { return length_; }
130
131 // Return the liquid mass density.
132 Scalar liquidDensity() const
133 {
134 static const Scalar liquidDensity = getParam<Scalar>("Component.LiquidDensity");
135 return liquidDensity;
136 }
137
138 // Return the liquid dynamic viscosity.
139 44 Scalar liquidDynamicViscosity() const
140 {
141
5/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 20 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
44 static const Scalar liquidDynamicViscosity = getParam<Scalar>("Component.LiquidKinematicViscosity") * liquidDensity();
142 44 return liquidDynamicViscosity;
143 }
144
145 // Return the applied pressure gradient.
146 Scalar pressureGradient() const
147 { return pressureGradient_; }
148 // [[/codeblock]]
149 // [[/details]]
150 //
151 // Return the label of inlet pores assuming a previously set direction.
152 int inletPoreLabel() const
153 {
154 static constexpr std::array<int, 3> label = {1, 3, 5};
155 633150 return label[direction_];
156 }
157
158 // Return the label of outlet pores assuming a previously set direction.
159 int outletPoreLabel() const
160 {
161 static constexpr std::array<int, 3> label = {2, 4, 6};
162
4/8
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 10 times.
✗ Branch 11 not taken.
40 return label[direction_];
163 }
164
165 // [[/details]] private class members
166 private:
167
168 bool isInletPore_(const SubControlVolume& scv) const
169 {
170
4/8
✓ Branch 0 taken 61761 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24220 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 154574 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 76020 times.
✗ Branch 7 not taken.
316575 if (useLabels_)
171 1266300 return inletPoreLabel() == this->gridGeometry().poreLabel(scv.dofIndex());
172 else
173 return scv.dofPosition()[direction_] < this->gridGeometry().bBoxMin()[direction_] + eps_;
174 }
175
176 bool isOutletPore_(const SubControlVolume& scv) const
177 {
178
2/4
✓ Branch 0 taken 116754 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57420 times.
✗ Branch 3 not taken.
174174 if (useLabels_)
179 696696 return outletPoreLabel() == this->gridGeometry().poreLabel(scv.dofIndex());
180 else
181 return scv.dofPosition()[direction_] > this->gridGeometry().bBoxMax()[direction_] - eps_;
182 }
183
184 Scalar eps_;
185 Scalar pressureGradient_;
186 int direction_;
187 GlobalPosition length_;
188 bool useLabels_;
189 };
190
191 } // end namespace Dumux
192 // [[/details]]
193 // [[/content]]
194 #endif
195