GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/discretization/staggered/freeflow/gridvolumevariables.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 39 57 68.4%
Functions: 70 211 33.2%
Branches: 48 285 16.8%

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 StaggeredDiscretization
10 * \copydoc Dumux::StaggeredGridVolumeVariables
11 */
12 #ifndef DUMUX_DISCRETIZATION_STAGGERED_GRID_VOLUMEVARIABLES_HH
13 #define DUMUX_DISCRETIZATION_STAGGERED_GRID_VOLUMEVARIABLES_HH
14
15 #include <dune/common/exceptions.hh>
16 #include <dune/common/rangeutilities.hh>
17
18 // make the local view function available whenever we use this class
19 #include <dumux/discretization/localview.hh>
20 #include <dumux/discretization/staggered/elementsolution.hh>
21 #include <dumux/discretization/staggered/freeflow/elementvolumevariables.hh>
22
23 namespace Dumux {
24
25 template<class P, class VV>
26 struct StaggeredGridDefaultGridVolumeVariablesTraits
27 {
28 using Problem = P;
29 using VolumeVariables = VV;
30 using PrimaryVariables = typename VV::PrimaryVariables;
31
32 template<class GridVolumeVariables, bool cachingEnabled>
33 using LocalView = StaggeredElementVolumeVariables<GridVolumeVariables, cachingEnabled>;
34
35 //! Returns the primary variables used for the boundary volVars and checks for admissible
36 //! combinations for boundary conditions.
37 template<class Problem, class SolutionVector, class Element, class SubControlVolumeFace>
38 701368 static PrimaryVariables getBoundaryPriVars(const Problem& problem,
39 const SolutionVector& sol,
40 const Element& element,
41 const SubControlVolumeFace& scvf)
42 {
43 using CellCenterPrimaryVariables = typename SolutionVector::value_type;
44 using Indices = typename VolumeVariables::Indices;
45 static constexpr auto dim = PrimaryVariables::dimension - CellCenterPrimaryVariables::dimension;
46 static constexpr auto offset = dim;
47
48 701368 const auto bcTypes = problem.boundaryTypes(element, scvf);
49 701368 PrimaryVariables boundaryPriVars(0.0);
50
51 // make sure to not use outflow BC for momentum balance
52
2/2
✓ Branch 0 taken 1402736 times.
✓ Branch 1 taken 701368 times.
2104104 for(int i = 0; i < dim; ++i)
53 {
54
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1402736 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1402736 times.
2805472 if(bcTypes.isOutflow(Indices::velocity(i)))
55 DUNE_THROW(Dune::InvalidStateException, "Outflow condition cannot be used for velocity. Set only a Dirichlet value for pressure instead.");
56 }
57
58
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 701368 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 701368 times.
1402736 if(bcTypes.isOutflow(Indices::pressureIdx))
59 DUNE_THROW(Dune::InvalidStateException, "Outflow condition cannot be used for pressure. Set only a Dirichlet value for velocity instead.");
60
61 // Determine the pressure value at a boundary with a Dirichlet condition for velocity.
62 // This just takes the value of the adjacent inner cell.
63
2/2
✓ Branch 0 taken 257400 times.
✓ Branch 1 taken 443968 times.
701368 if(bcTypes.isDirichlet(Indices::velocity(scvf.directionIndex())))
64 {
65
1/2
✓ Branch 0 taken 443968 times.
✗ Branch 1 not taken.
443968 if(bcTypes.isDirichlet(Indices::pressureIdx))
66 DUNE_THROW(Dune::InvalidStateException, "A Dirichlet condition for velocity must not be combined with a Dirichlet condition for pressure");
67 else
68 2167706 boundaryPriVars[Indices::pressureIdx] = sol[scvf.insideScvIdx()][Indices::pressureIdx - offset];
69 // TODO: pressure could be extrapolated to the boundary
70 }
71
72 // Determine the pressure value for a boundary with a Dirichlet condition for pressure.
73 // Takes a value specified in the problem.
74
2/2
✓ Branch 0 taken 505490 times.
✓ Branch 1 taken 195878 times.
701368 if(bcTypes.isDirichlet(Indices::pressureIdx))
75 {
76
1/2
✓ Branch 0 taken 195878 times.
✗ Branch 1 not taken.
195878 if(bcTypes.isDirichlet(Indices::velocity(scvf.directionIndex())))
77 DUNE_THROW(Dune::InvalidStateException, "A Dirichlet condition for velocity must not be combined with a Dirichlet condition for pressure");
78 else
79 238280 boundaryPriVars[Indices::pressureIdx] = problem.dirichlet(element, scvf)[Indices::pressureIdx];
80 }
81
82 // Return for isothermal single-phase systems ...
83 if(CellCenterPrimaryVariables::dimension == 1)
84 return boundaryPriVars;
85
86 // ... or handle values for components, temperature, etc.
87
2/2
✓ Branch 0 taken 2104256 times.
✓ Branch 1 taken 635116 times.
2739372 for(int eqIdx = offset; eqIdx < PrimaryVariables::dimension; ++eqIdx)
88 {
89
2/2
✓ Branch 0 taken 1469140 times.
✓ Branch 1 taken 635116 times.
2104256 if(eqIdx == Indices::pressureIdx)
90 continue;
91
92
2/2
✓ Branch 0 taken 667794 times.
✓ Branch 1 taken 801346 times.
1469140 if(bcTypes.isDirichlet(eqIdx))
93 801346 boundaryPriVars[eqIdx] = problem.dirichlet(element, scvf)[eqIdx];
94
9/10
✓ Branch 0 taken 207088 times.
✓ Branch 1 taken 460706 times.
✓ Branch 2 taken 207088 times.
✓ Branch 3 taken 460706 times.
✓ Branch 4 taken 108318 times.
✓ Branch 5 taken 98770 times.
✓ Branch 6 taken 108318 times.
✓ Branch 7 taken 98770 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 108318 times.
1335588 else if(bcTypes.isOutflow(eqIdx) || bcTypes.isSymmetry() || bcTypes.isNeumann(eqIdx))
95 3338970 boundaryPriVars[eqIdx] = sol[scvf.insideScvIdx()][eqIdx - offset];
96 }
97
98 // make sure that a potential outflow condition is set for all components
99 std::array<bool, VolumeVariables::numFluidComponents() - 1> isComponentOutflow;
100
2/2
✓ Branch 0 taken 287252 times.
✓ Branch 1 taken 277572 times.
922368 for(int compIdx = 1; compIdx < VolumeVariables::numFluidComponents(); ++compIdx)
101 {
102 287252 const auto eqIdx = VolumeVariables::Indices::conti0EqIdx + compIdx;
103 861756 isComponentOutflow[compIdx -1] = bcTypes.isOutflow(eqIdx);
104 }
105
106
3/4
✓ Branch 0 taken 82404 times.
✓ Branch 1 taken 195168 times.
✓ Branch 2 taken 82404 times.
✗ Branch 3 not taken.
717520 if(Dune::any_true(isComponentOutflow) && !Dune::all_true(isComponentOutflow))
107 DUNE_THROW(Dune::InvalidStateException, "Outflow condition must be set for all components!");
108
109 return boundaryPriVars;
110 }
111 };
112
113 /*!
114 * \ingroup StaggeredDiscretization
115 * \brief Grid volume variables class for staggered models
116 */
117 template<class Traits, bool cachingEnabled>
118 class StaggeredGridVolumeVariables;
119
120 /*!
121 * \ingroup StaggeredDiscretization
122 * \brief Grid volume variables class for staggered models.
123 Specialization in case of storing the volume variables
124 */
125 template<class Traits>
126
0/5
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
1325 class StaggeredGridVolumeVariables<Traits, /*cachingEnabled*/true>
127 {
128 using ThisType = StaggeredGridVolumeVariables<Traits, true>;
129 using PrimaryVariables = typename Traits::VolumeVariables::PrimaryVariables;
130
131 public:
132 //! export the problem type
133 using Problem = typename Traits::Problem;
134
135 //! export the type of the indices
136 using Indices = typename Traits::VolumeVariables::Indices;
137
138 //! export the type of the VolumeVariables
139 using VolumeVariables = typename Traits::VolumeVariables;
140
141 //! make it possible to query if caching is enabled
142 static constexpr bool cachingEnabled = true;
143
144 //! export the type of the local view
145 using LocalView = typename Traits::template LocalView<ThisType, cachingEnabled>;
146
147
4/8
✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 50 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 50 times.
✗ Branch 11 not taken.
200 StaggeredGridVolumeVariables(const Problem& problem) : problemPtr_(&problem) {}
148
149 //! Update all volume variables
150 template<class GridGeometry, class SolutionVector>
151 5569 void update(const GridGeometry& gridGeometry, const SolutionVector& sol)
152 {
153
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5569 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5569 times.
11138 if (sol.size() != gridGeometry.numScv())
154 DUNE_THROW(Dune::InvalidStateException, "The solution vector passed to the GridVolumeVariables has the wrong size.\n"
155 << "Make sure to initialize the gridVariables correctly: \n\n"
156 << "auto ffSol = partial(sol, ffFaceIdx, ffCellCenterIdx); \n"
157 << "ffGridVariables->init(ffSol);\n\n");
158
159 11138 volumeVariables_.resize(gridGeometry.numScv());
160 5569 auto fvGeometry = localView(gridGeometry);
161
1/2
✓ Branch 2 taken 1686341 times.
✗ Branch 3 not taken.
3372682 for (const auto& element : elements(gridGeometry.gridView()))
162 {
163 1680772 fvGeometry.bindElement(element);
164
4/4
✓ Branch 2 taken 1680772 times.
✓ Branch 3 taken 1680772 times.
✓ Branch 4 taken 1680772 times.
✓ Branch 5 taken 1680772 times.
6723088 for (auto&& scv : scvs(fvGeometry))
165 {
166 // construct a privars object from the cell center solution vector
167 3361544 const auto& cellCenterPriVars = sol[scv.dofIndex()];
168 1680772 PrimaryVariables priVars = makePriVarsFromCellCenterPriVars<PrimaryVariables>(cellCenterPriVars);
169
170
1/4
✓ Branch 1 taken 1272872 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4634416 auto elemSol = elementSolution<typename GridGeometry::LocalView>(std::move(priVars));
171
4/8
✓ Branch 1 taken 1680772 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1680772 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1680772 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 407900 times.
✗ Branch 10 not taken.
5042316 volumeVariables_[scv.dofIndex()].update(elemSol, problem(), element, scv);
172 }
173 }
174 5569 }
175
176 const VolumeVariables& volVars(const std::size_t scvIdx) const
177 12195864734 { return volumeVariables_[scvIdx]; }
178
179 VolumeVariables& volVars(const std::size_t scvIdx)
180 { return volumeVariables_[scvIdx]; }
181
182 template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
183 const VolumeVariables& volVars(const SubControlVolume& scv) const
184 { return volumeVariables_[scv.dofIndex()]; }
185
186 template<class SubControlVolume, typename std::enable_if_t<!std::is_integral<SubControlVolume>::value, int> = 0>
187 VolumeVariables& volVars(const SubControlVolume& scv)
188 66438174 { return volumeVariables_[scv.dofIndex()]; }
189
190 const Problem& problem() const
191 { return *problemPtr_; }
192
193 //! Returns the primary variables used for the boundary volVars and checks for admissible
194 //! combinations for boundary conditions.
195 template<class... Args>
196 PrimaryVariables getBoundaryPriVars(Args&&... args) const
197 {
198 701368 return Traits::getBoundaryPriVars(std::forward<Args>(args)...);
199 }
200
201 private:
202 const Problem* problemPtr_;
203 std::vector<VolumeVariables> volumeVariables_;
204 };
205
206
207 /*!
208 * \ingroup StaggeredDiscretization
209 * \brief Grid volume variables class for staggered models.
210 Specialization in case of not storing the volume variables
211 */
212 template<class Traits>
213 class StaggeredGridVolumeVariables<Traits, /*cachingEnabled*/false>
214 {
215 using ThisType = StaggeredGridVolumeVariables<Traits, false>;
216 using PrimaryVariables = typename Traits::VolumeVariables::PrimaryVariables;
217
218 public:
219 //! export the problem type
220 using Problem = typename Traits::Problem;
221
222 //! export the type of the VolumeVariables
223 using VolumeVariables = typename Traits::VolumeVariables;
224
225 //! make it possible to query if caching is enabled
226 static constexpr bool cachingEnabled = false;
227
228 //! export the type of the local view
229 using LocalView = typename Traits::template LocalView<ThisType, cachingEnabled>;
230
231 StaggeredGridVolumeVariables(const Problem& problem) : problemPtr_(&problem) {}
232
233 template<class GridGeometry, class SolutionVector>
234 void update(const GridGeometry& gridGeometry, const SolutionVector& sol)
235 {
236 if (sol.size() != gridGeometry.numScv())
237 DUNE_THROW(Dune::InvalidStateException, "The solution vector passed to the GridVolumeVariables has the wrong size.\n"
238 << "Make sure to initialize the gridVariables correctly: \n\n"
239 << "auto ffSol = partial(sol, ffFaceIdx, ffCellCenterIdx); \n"
240 << "ffGridVariables->init(ffSol);\n\n");
241 }
242
243 const Problem& problem() const
244 { return *problemPtr_;}
245
246 //! Returns the primary variables used for the boundary volVars and checks for admissible
247 //! combinations for boundary conditions.
248 template<class... Args>
249 PrimaryVariables getBoundaryPriVars(Args&&... args) const
250 {
251 return Traits::getBoundaryPriVars(std::forward<Args>(args)...);
252 }
253
254 private:
255
256 const Problem* problemPtr_;
257 };
258
259 } // end namespace Dumux
260
261 #endif
262