GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/test/multidomain/embedded/1d3d/1p2c_richards2c/problem_root.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 42 49 85.7%
Functions: 4 7 57.1%
Branches: 53 112 47.3%

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 * \file
9 * \ingroup EmbeddedTests
10 * \brief A test problem for the one-phase root model:
11 * Sap is flowing through a 1d network root xylem.
12 */
13
14 #ifndef DUMUX_ROOT_PROBLEM_HH
15 #define DUMUX_ROOT_PROBLEM_HH
16
17 #include <dumux/common/boundarytypes.hh>
18 #include <dumux/common/parameters.hh>
19 #include <dumux/common/properties.hh>
20 #include <dumux/common/numeqvector.hh>
21
22 #include <dumux/porousmediumflow/problem.hh>
23
24 namespace Dumux {
25
26 /*!
27 * \ingroup EmbeddedTests
28 * \brief Exact solution 1D-3D
29 */
30 template <class TypeTag>
31 class RootProblem : public PorousMediumFlowProblem<TypeTag>
32 {
33 using ParentType = PorousMediumFlowProblem<TypeTag>;
34 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
35 using PointSource = GetPropType<TypeTag, Properties::PointSource>;
36 using PrimaryVariables = GetPropType<TypeTag, Properties::PrimaryVariables>;
37 using SourceValues = Dumux::NumEqVector<PrimaryVariables>;
38 using NeumannFluxes = SourceValues;
39 using BoundaryTypes = Dumux::BoundaryTypes<GetPropType<TypeTag, Properties::ModelTraits>::numEq()>;
40 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
41 using GridView = typename GridGeometry::GridView;
42 using FVElementGeometry = typename GridGeometry::LocalView;
43 using SubControlVolume = typename GridGeometry::SubControlVolume;
44 using SubControlVolumeFace = typename GridGeometry::SubControlVolumeFace;
45 using GlobalPosition = typename GridGeometry::GlobalCoordinate;
46 using Element = typename GridView::template Codim<0>::Entity;
47 using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>;
48 using GridVariables = GetPropType<TypeTag, Properties::GridVariables>;
49
50 using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>;
51
52 public:
53 using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
54 enum Indices {
55 // Grid and world dimension
56 dim = GridView::dimension,
57 dimworld = GridView::dimensionworld,
58
59 pressureIdx = 0,
60 transportCompIdx = 1,
61
62 conti0EqIdx = 0,
63 transportEqIdx = 1,
64
65 liquidPhaseIdx = 0
66 };
67
68 template<class SpatialParams>
69 1 RootProblem(std::shared_ptr<const GridGeometry> gridGeometry,
70 std::shared_ptr<SpatialParams> spatialParams,
71 std::shared_ptr<CouplingManager> couplingManager)
72 : ParentType(gridGeometry, spatialParams, "Root")
73
6/20
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
4 , couplingManager_(couplingManager)
74 {
75 // read parameters from input file
76
9/26
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
2 name_ = getParam<std::string>("Vtk.OutputName") + "_" + getParamFromGroup<std::string>(this->paramGroup(), "Problem.Name");
77
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 transpirationRate_ = getParam<Scalar>("BoundaryConditions.TranspirationRate");
78
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 initPressure_ = getParam<Scalar>("BoundaryConditions.InitialRootPressure");
79 1 }
80
81 /*!
82 * \name Problem parameters
83 */
84 // \{
85
86 /*!
87 * \brief The problem name.
88 *
89 * This is used as a prefix for files generated by the simulation.
90 */
91 const std::string& name() const
92
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 { return name_; }
93
94 // \}
95 /*!
96 * \name Boundary conditions
97 */
98 // \{
99
100 /*!
101 * \brief Specifies which kind of boundary condition should be
102 * used for which equation on a given boundary segment.
103 *
104 * \param globalPos The global position
105 */
106 BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
107 {
108 8614 BoundaryTypes values;
109
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6018 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2596 times.
8614 values.setAllNeumann();
110 return values;
111 }
112
113 /*!
114 * \brief Evaluates the boundary conditions for a Dirichlet control volume.
115 *
116 * \param globalPos The global position
117 *
118 * For this method, the \a values parameter stores primary variables.
119 */
120 PrimaryVariables dirichletAtPos(const GlobalPosition& globalPos) const
121 { return initialAtPos(globalPos); }
122
123
124 /*!
125 * \brief Evaluates the boundary conditions for a Neumann boundary segment.
126 *
127 * For this method, the \a priVars parameter stores the mass flux
128 * in normal direction of each component. Negative values mean
129 * influx.
130 */
131 template<class ElementVolumeVariables, class ElementFluxVarsCache>
132 6549 NeumannFluxes neumann(const Element& element,
133 const FVElementGeometry& fvGeometry,
134 const ElementVolumeVariables& elemVolvars,
135 const ElementFluxVarsCache& elemFluxVarsCache,
136 const SubControlVolumeFace& scvf) const
137 {
138 6549 NeumannFluxes values(0.0);
139
12/12
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 6438 times.
✓ Branch 2 taken 111 times.
✓ Branch 3 taken 6438 times.
✓ Branch 4 taken 111 times.
✓ Branch 5 taken 6438 times.
✓ Branch 6 taken 111 times.
✓ Branch 7 taken 6438 times.
✓ Branch 8 taken 111 times.
✓ Branch 9 taken 6438 times.
✓ Branch 10 taken 111 times.
✓ Branch 11 taken 6438 times.
39294 if (scvf.center()[2] + eps_ > this->gridGeometry().bBoxMax()[2])
140 {
141 222 const auto& volVars = elemVolvars[scvf.insideScvIdx()];
142 222 const Scalar value = transpirationRate_ * volVars.molarDensity(liquidPhaseIdx)/volVars.density(liquidPhaseIdx);
143
144 111 values[conti0EqIdx] = value / volVars.extrusionFactor() / scvf.area();
145 // use upwind mole fraction to get outflow condition for the tracer
146 444 values[transportEqIdx] = values[conti0EqIdx] * volVars.moleFraction(liquidPhaseIdx, transportCompIdx);
147 }
148 6549 return values;
149
150 }
151
152 // \}
153
154 /*!
155 * \name Volume terms
156 */
157 // \{
158
159 /*!
160 * \brief Applies a vector of point sources which are possibly solution dependent.
161 *
162 * \param pointSources A vector of PointSource s that contain
163 source values for all phases and space positions.
164 *
165 * For this method, the \a values method of the point source
166 * has to return the absolute mass rate in kg/s. Positive values mean
167 * that mass is created, negative ones mean that it vanishes.
168 */
169 void addPointSources(std::vector<PointSource>& pointSources) const
170
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 { pointSources = this->couplingManager().lowDimPointSources(); }
171
172 /*!
173 * \brief Evaluates the point sources (added by addPointSources)
174 * for all phases within a given sub control volume.
175 *
176 * This is the method for the case where the point source is
177 * solution dependent and requires some quantities that
178 * are specific to the fully-implicit method.
179 *
180 * \param source A single point source
181 * \param element The finite element
182 * \param fvGeometry The finite-volume geometry
183 * \param elemVolVars All volume variables for the element
184 * \param scv The sub control volume within the element
185 *
186 * For this method, the \a values() method of the point sources returns
187 * the absolute rate mass generated or annihilated in kg/s. Positive values mean
188 * that mass is created, negative ones mean that it vanishes.
189 */
190 template<class ElementVolumeVariables>
191 670548 void pointSource(PointSource& source,
192 const Element &element,
193 const FVElementGeometry& fvGeometry,
194 const ElementVolumeVariables& elemVolVars,
195 const SubControlVolume &scv) const
196 {
197 670548 SourceValues sourceValues;
198
199 // compute source at every integration point
200 2011644 const auto priVars3D = this->couplingManager().bulkPriVars(source.id());
201 2011644 const auto priVars1D = this->couplingManager().lowDimPriVars(source.id());
202
1/2
✓ Branch 0 taken 670548 times.
✗ Branch 1 not taken.
670548 const Scalar pressure3D = priVars3D[pressureIdx];
203
1/2
✓ Branch 0 taken 670548 times.
✗ Branch 1 not taken.
670548 const Scalar pressure1D = priVars1D[pressureIdx];
204
205 2011644 const auto lowDimElementIdx = this->couplingManager().pointSourceData(source.id()).lowDimElementIdx();
206
1/2
✓ Branch 0 taken 670548 times.
✗ Branch 1 not taken.
670548 const Scalar Kr = this->spatialParams().Kr(lowDimElementIdx);
207
2/4
✓ Branch 0 taken 670548 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 670548 times.
✗ Branch 3 not taken.
1341096 const Scalar rootRadius = this->spatialParams().radius(lowDimElementIdx);
208
209 // sink defined as radial flow Jr * density [m^2 s-1]* [kg m-3]
210 670548 const auto molarDensityH20 = 1000 / 0.018;
211
1/2
✓ Branch 0 taken 670548 times.
✗ Branch 1 not taken.
670548 sourceValues[conti0EqIdx] = 2 * M_PI * rootRadius * Kr * (pressure3D - pressure1D) * molarDensityH20;
212
213
1/2
✓ Branch 0 taken 670548 times.
✗ Branch 1 not taken.
670548 const Scalar x3D = priVars3D[transportCompIdx];
214
1/2
✓ Branch 0 taken 670548 times.
✗ Branch 1 not taken.
670548 const Scalar x1D = priVars1D[transportCompIdx];
215
216 //! Advective transport over root wall
217 // compute correct upwind concentration
218
2/4
✓ Branch 0 taken 670548 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 670548 times.
✗ Branch 3 not taken.
1341096 if (sourceValues[conti0EqIdx] > 0)
219 2011644 sourceValues[transportEqIdx] = sourceValues[conti0EqIdx]*x3D;
220 else
221 sourceValues[transportEqIdx] = sourceValues[conti0EqIdx]*x1D;
222
223 //! Diffusive transport over root wall
224 670548 const auto molarDensityD20 = 1000 / 0.020;
225 670548 sourceValues[transportEqIdx] += 2 * M_PI * rootRadius * 1.0e-8 * (x3D - x1D) * molarDensityD20;
226
227 670548 sourceValues *= source.quadratureWeight()*source.integrationElement();
228 1341096 source = sourceValues;
229 670548 }
230
231 /*!
232 * \brief Evaluates the initial value for a control volume.
233 *
234 * For this method, the \a priVars parameter stores primary
235 * variables.
236 */
237 PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
238 { return PrimaryVariables({initPressure_, 0.0}); }
239
240 // \}
241
242 /*!
243 * \brief Adds additional VTK output data to the VTKWriter.
244 *
245 * Function is called by the output module on every write.
246 */
247 template<class VtkOutputModule>
248 1 void addVtkOutputFields(VtkOutputModule& vtk) const
249 {
250
6/14
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
2 vtk.addField(this->spatialParams().getRadii(), "radius");
251 1 }
252
253 //! Get the coupling manager
254 const CouplingManager& couplingManager() const
255
4/8
✓ Branch 2 taken 670548 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 670548 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
2682194 { return *couplingManager_; }
256
257 private:
258 Scalar transpirationRate_, initPressure_;
259
260 static constexpr Scalar eps_ = 1.5e-7;
261 std::string name_;
262
263 std::shared_ptr<CouplingManager> couplingManager_;
264 };
265
266 } // end namespace Dumux
267
268 #endif
269