GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/test/freeflow/navierstokes/periodic/porescale/problem.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 30 31 96.8%
Functions: 4 4 100.0%
Branches: 28 46 60.9%

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-FileCopyrightText: 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 Pore Scale Simulations
10 * \ingroup Basic Pore Structure
11 * \brief The problem file for the evaluation of a pore geometry
12 */
13
14 #ifndef DUMUX_PERIODIC_FLOW_PORE_TEST_PROBLEM_HH
15 #define DUMUX_PERIODIC_FLOW_PORE_TEST_PROBLEM_HH
16
17 #include <dumux/common/parameters.hh>
18 #include <dumux/common/properties.hh>
19
20 #include <dumux/freeflow/navierstokes/boundarytypes.hh>
21
22 #include <dumux/freeflow/navierstokes/momentum/fluxhelper.hh>
23 #include <dumux/freeflow/navierstokes/scalarfluxhelper.hh>
24 #include <dumux/freeflow/navierstokes/mass/1p/advectiveflux.hh>
25
26 namespace Dumux {
27
28 template <class TypeTag, class BaseProblem>
29 2 class FlowPoreStructureProblem : public BaseProblem
30 {
31 using ParentType = BaseProblem;
32 using BoundaryTypes = typename ParentType::BoundaryTypes;
33 using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>;
34 using FVElementGeometry = typename GridGeometry::LocalView;
35 using SubControlVolume = typename FVElementGeometry::SubControlVolume;
36 using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace;
37 using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices;
38 using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>;
39 using InitialValues = typename ParentType::InitialValues;
40 using Sources = typename ParentType::Sources;
41 using DirichletValues = typename ParentType::DirichletValues;
42 using BoundaryFluxes = typename ParentType::BoundaryFluxes;
43 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
44
45 static constexpr auto dimWorld = GridGeometry::GridView::dimensionworld;
46 using Element = typename FVElementGeometry::Element;
47 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
48 using VelocityVector = Dune::FieldVector<Scalar, dimWorld>;
49
50 using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>;
51
52 public:
53 4 FlowPoreStructureProblem(std::shared_ptr<const GridGeometry> gridGeometry,
54 std::shared_ptr<CouplingManager> couplingManager)
55 : ParentType(gridGeometry, couplingManager)
56
3/8
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
16 , eps_(1e-6)
57 {
58
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 momentumForce_ = getParam<Scalar>("Problem.MomentumForce");
59 4 referencePressure_ = 0.0;
60
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 problemName_ = "test_ff_periodic_subgrid";
61 4 }
62
63 /*!
64 * \brief The problem name.
65 */
66 1 const std::string& name() const
67
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 { return problemName_ ; }
68
69 /*!
70 * \brief Specifies which kind of boundary condition should be
71 * used for which equation on a given boundary control volume.
72 *
73 * \param globalPos The position of the center of the finite volume
74 */
75
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 99960 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19992 times.
119952 BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
76 {
77
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 99960 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19992 times.
245160 BoundaryTypes values;
78
79 if constexpr (ParentType::isMomentumProblem())
80 125208 values.setAllDirichlet();
81 else
82 values.setAllNeumann();
83
84 125208 return values;
85 }
86
87 //! Enable internal Dirichlet constraints
88 static constexpr bool enableInternalDirichletConstraints()
89 { return !ParentType::isMomentumProblem(); }
90
91
92 /*!
93 * \brief Tag a degree of freedom to carry internal Dirichlet constraints.
94 * If true is returned for a dof, the equation for this dof is replaced
95 * by the constraint that its primary variable values must match the
96 * user-defined values obtained from the function internalDirichlet(),
97 * which must be defined in the problem.
98 *
99 * \param element The finite element
100 * \param scv The sub-control volume
101 */
102 212054 std::bitset<DirichletValues::dimension> hasInternalDirichletConstraint(const Element& element, const SubControlVolume& scv) const
103 {
104
6/8
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 97200 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 24300 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 90538 times.
212054 std::bitset<DirichletValues::dimension> values;
105
106 // If only Dirichlet BCs are set for the momentum balance, fix the pressure at some cells such that the solution is fully defined.
107 {
108
6/8
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 97200 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 24300 times.
✓ Branch 6 taken 6 times.
✓ Branch 7 taken 90538 times.
212054 if (scv.elementIndex() == 0)
109 16 values.set(Indices::pressureIdx);
110 }
111
112 return values;
113 }
114
115 /*!
116 * \brief Define the values of internal Dirichlet constraints for a degree of freedom.
117 * \param element The finite element
118 * \param scv The sub-control volume
119 */
120 24302 DirichletValues internalDirichlet(const Element& element, const SubControlVolume& scv) const
121 { return DirichletValues{-0.00185227}; }
122
123 template<class ElementVolumeVariables>
124 1890848 Sources source(const Element& element,
125 const FVElementGeometry& fvGeometry,
126 const ElementVolumeVariables& elemVolVars,
127 const SubControlVolume& scv) const
128 {
129 1890848 Sources source(0.0);
130 if constexpr (ParentType::isMomentumProblem())
131 {
132 1890848 GlobalPosition globalPos = scv.dofPosition();
133
2/2
✓ Branch 0 taken 1960 times.
✓ Branch 1 taken 1888888 times.
1890848 if (isInlet_(globalPos))
134 {
135 1960 const auto& frontalScvf = (*scvfs(fvGeometry, scv).begin());
136 1960 source[Indices::momentumXBalanceIdx] = momentumForce_ * frontalScvf.area() / scv.volume();
137 }
138 }
139
140 1890848 return source;
141 }
142
143 /*!
144 * \brief Evaluates the boundary conditions for a Dirichlet control volume.
145 *
146 * \param globalPos The center of the finite volume which ought to be set.
147 */
148 DirichletValues dirichlet(const Element& element, const SubControlVolumeFace& scvf) const
149 570224 { return DirichletValues(0.0); }
150
151 /*!
152 * \brief Returns a reference pressure at a given sub control volume face.
153 * This pressure is subtracted from the actual pressure for the momentum balance
154 * which potentially helps to improve numerical accuracy by avoiding issues related do floating point arithmetic.
155 */
156 1791632 Scalar referencePressure(const Element& element,
157 const FVElementGeometry& fvGeometry,
158 const SubControlVolumeFace& scvf) const
159 1791632 { return referencePressure_; }
160
161 // Return cellCenteredVelocities
162 template <class SolutionVector>
163 std::vector<VelocityVector> cellCenteredVelocity(const SolutionVector& curSol) const
164 {
165 std::vector<VelocityVector> velocity;
166 velocity.resize(this->gridGeometry().elementMapper().size(), VelocityVector(0.0));
167
168 // calculate cell-center-averaged velocities
169 for (const auto& element : elements(this->gridGeometry().gridView()))
170 {
171 auto fvGeometry = localView(this->gridGeometry());
172 fvGeometry.bindElement(element);
173 unsigned int elementIdx = this->gridGeometry().elementMapper().index(element);
174
175 // calculate velocities
176 VelocityVector velocityTemp(0.0);
177 for (auto&& scv : scvs(fvGeometry))
178 {
179 const int dofIdxFace = scv.dofIndex();
180 const auto numericalSolutionFace = curSol[CouplingManager::freeFlowMomentumIndex]
181 [dofIdxFace]
182 [Indices::velocity(scv.dofAxis())];
183 velocityTemp[scv.dofAxis()] += numericalSolutionFace;
184 }
185
186 for (unsigned int dimIdx = 0; dimIdx < dimWorld; ++dimIdx)
187 velocity[elementIdx][dimIdx] = velocityTemp[dimIdx] * 0.5; // faces are equidistant to cell center
188 }
189 return velocity;
190 }
191
192 private:
193
2/2
✓ Branch 0 taken 1960 times.
✓ Branch 1 taken 1888888 times.
1890848 bool isInlet_(const GlobalPosition& globalPos) const
194
2/2
✓ Branch 0 taken 1960 times.
✓ Branch 1 taken 1888888 times.
1890848 { return (globalPos[0] < this->gridGeometry().bBoxMin()[0] + eps_); }
195
196 bool isOutlet_(const GlobalPosition& globalPos) const
197 { return (globalPos[0] > this->gridGeometry().bBoxMax()[0] - eps_); }
198
199 Scalar eps_;
200 Scalar momentumForce_;
201 Scalar referencePressure_;
202 std::string problemName_;
203 };
204
205 } // end namespace Dumux
206
207 #endif
208