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 | #ifndef DUMUX_TEST_FREEFLOW_NAVIERSTOKES_3D_CHANNEL_PROBLEM_HH | ||
8 | #define DUMUX_TEST_FREEFLOW_NAVIERSTOKES_3D_CHANNEL_PROBLEM_HH | ||
9 | |||
10 | #if HAVE_DUNE_FOAMGRID | ||
11 | #include <dune/foamgrid/foamgrid.hh> | ||
12 | #endif | ||
13 | |||
14 | #include <dune/common/float_cmp.hh> | ||
15 | |||
16 | #include <dumux/common/math.hh> | ||
17 | #include <dumux/common/properties.hh> | ||
18 | #include <dumux/common/parameters.hh> | ||
19 | #include <dumux/io/vtkoutputmodule.hh> | ||
20 | #include <dumux/io/vtk/function.hh> | ||
21 | #include <dumux/io/grid/griddata.hh> | ||
22 | |||
23 | #include <dumux/geometry/diameter.hh> | ||
24 | #include <dumux/geometry/geometricentityset.hh> | ||
25 | #include <dumux/geometry/boundingboxtree.hh> | ||
26 | #include <dumux/multidomain/embedded/circlepoints.hh> | ||
27 | |||
28 | namespace Dumux { | ||
29 | |||
30 | /*! | ||
31 | * \brief Test problem for the (Navier-) Stokes model in a 3D channel | ||
32 | * | ||
33 | * Flow from left to right in a three-dimensional channel is considered. At the inlet (left) | ||
34 | * and outlet (right) fixed values for pressure are set. | ||
35 | */ | ||
36 | template <class TypeTag, class BaseProblem> | ||
37 | class ThreeDChannelTestProblem : public BaseProblem | ||
38 | { | ||
39 | using ParentType = BaseProblem; | ||
40 | |||
41 | using BoundaryTypes = typename ParentType::BoundaryTypes; | ||
42 | using GridGeometry = GetPropType<TypeTag, Properties::GridGeometry>; | ||
43 | using FVElementGeometry = typename GridGeometry::LocalView; | ||
44 | using SubControlVolume = typename FVElementGeometry::SubControlVolume; | ||
45 | using SubControlVolumeFace = typename FVElementGeometry::SubControlVolumeFace; | ||
46 | using Indices = typename GetPropType<TypeTag, Properties::ModelTraits>::Indices; | ||
47 | using BoundaryFluxes = typename ParentType::BoundaryFluxes; | ||
48 | using DirichletValues = typename ParentType::DirichletValues; | ||
49 | using ModelTraits = GetPropType<TypeTag, Properties::ModelTraits>; | ||
50 | using Scalar = GetPropType<TypeTag, Properties::Scalar>; | ||
51 | using SolutionVector = GetPropType<TypeTag, Properties::SolutionVector>; | ||
52 | |||
53 | static constexpr int dim = GridGeometry::GridView::dimension; | ||
54 | static constexpr auto dimWorld = GridGeometry::GridView::dimensionworld; | ||
55 | |||
56 | using Element = typename GridGeometry::GridView::template Codim<0>::Entity; | ||
57 | using GlobalPosition = typename Element::Geometry::GlobalCoordinate; | ||
58 | using VelocityVector = Dune::FieldVector<Scalar, dimWorld>; | ||
59 | |||
60 | using CouplingManager = GetPropType<TypeTag, Properties::CouplingManager>; | ||
61 | |||
62 | public: | ||
63 | template<class GridData> | ||
64 | 12 | ThreeDChannelTestProblem(std::shared_ptr<const GridGeometry> gridGeometry, std::shared_ptr<CouplingManager> couplingManager, GridData gridData) | |
65 | : ParentType(gridGeometry, couplingManager, ParentType::isMomentumProblem() ? "Momentum" : "Mass") | ||
66 |
6/20✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 6 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
|
48 | , gridData_(gridData) |
67 | { | ||
68 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
12 | deltaP_ = getParam<Scalar>("Problem.DeltaP"); |
69 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
12 | density_ = getParam<Scalar>("Component.LiquidDensity"); |
70 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
12 | viscosity_ = getParam<Scalar>("Component.LiquidDynamicViscosity"); |
71 | 12 | } | |
72 | |||
73 | /*! | ||
74 | * \brief Specifies which kind of boundary condition should be | ||
75 | * used for which equation on a given boundary segment. | ||
76 | * | ||
77 | * \param element The finite element | ||
78 | * \param scvf The sub control volume face | ||
79 | */ | ||
80 | ✗ | BoundaryTypes boundaryTypes(const Element& element, | |
81 | const SubControlVolumeFace& scvf) const | ||
82 | { | ||
83 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 125040 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 32256 times.
|
157296 | BoundaryTypes values; |
84 | |||
85 | if constexpr (ParentType::isMomentumProblem()) | ||
86 | { | ||
87 | if (isOutlet_(scvf) || isInlet_(scvf)) | ||
88 | values.setAllNeumann(); | ||
89 | else | ||
90 | values.setAllDirichlet(); | ||
91 | } | ||
92 | else | ||
93 |
4/8✗ Branch 0 not taken.
✓ Branch 1 taken 125040 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 125040 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 32256 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 32256 times.
|
314592 | values.setNeumann(Indices::conti0EqIdx); |
94 | |||
95 | ✗ | return values; | |
96 | } | ||
97 | |||
98 | /*! | ||
99 | * \brief Specifies which kind of boundary condition should be | ||
100 | * used for which equation on a given boundary segment. | ||
101 | * | ||
102 | * \param element The finite element | ||
103 | * \param scv The sub control volume | ||
104 | */ | ||
105 | 58704 | BoundaryTypes boundaryTypes(const Element& element, | |
106 | const SubControlVolume& scv) const | ||
107 | { | ||
108 |
1/2✓ Branch 0 taken 23976 times.
✗ Branch 1 not taken.
|
82680 | BoundaryTypes values; |
109 | |||
110 | if constexpr (ParentType::isMomentumProblem()) | ||
111 | { | ||
112 | 117408 | auto fvGeometry = localView(this->gridGeometry()); | |
113 | 58704 | fvGeometry.bindElement(element); | |
114 | |||
115 |
4/4✓ Branch 0 taken 384368 times.
✓ Branch 1 taken 10236 times.
✓ Branch 2 taken 384368 times.
✓ Branch 3 taken 10236 times.
|
736888 | for (const auto& scvf : scvfs(fvGeometry)) |
116 | { | ||
117 |
8/8✓ Branch 0 taken 93438 times.
✓ Branch 1 taken 290930 times.
✓ Branch 2 taken 93438 times.
✓ Branch 3 taken 290930 times.
✓ Branch 4 taken 93438 times.
✓ Branch 5 taken 290930 times.
✓ Branch 6 taken 24492 times.
✓ Branch 7 taken 68946 times.
|
1973136 | if (fvGeometry.scv(scvf.insideScvIdx()).dofIndex() == scv.dofIndex() && scvf.boundary()) |
118 | { | ||
119 |
4/4✓ Branch 0 taken 24098 times.
✓ Branch 1 taken 394 times.
✓ Branch 2 taken 23704 times.
✓ Branch 3 taken 394 times.
|
75906 | if (isOutlet_(scvf) || isInlet_(scvf)) |
120 | values.setAllNeumann(); | ||
121 | else | ||
122 | values.setAllDirichlet(); | ||
123 | |||
124 | break; | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | else | ||
129 |
2/4✓ Branch 0 taken 23976 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23976 times.
✗ Branch 3 not taken.
|
47952 | values.setNeumann(Indices::conti0EqIdx); |
130 | |||
131 | 58704 | return values; | |
132 | } | ||
133 | |||
134 | /*! | ||
135 | * \brief Evaluates the boundary conditions for a Dirichlet control volume. | ||
136 | * | ||
137 | * \param globalPos The center of the finite volume which ought to be set. | ||
138 | */ | ||
139 | ✗ | DirichletValues dirichletAtPos(const GlobalPosition& globalPos) const | |
140 | { | ||
141 | // no-flow/no-slip | ||
142 | 23704 | return DirichletValues(0.0); | |
143 | } | ||
144 | |||
145 | /*! | ||
146 | * \brief Evaluates the boundary conditions for a Neumann control volume. | ||
147 | * | ||
148 | * \param element The element for which the Neumann boundary condition is set | ||
149 | * \param fvGeometry The fvGeometry | ||
150 | * \param elemVolVars The element volume variables | ||
151 | * \param elemFaceVars The element face variables | ||
152 | * \param scvf The boundary sub control volume face | ||
153 | */ | ||
154 | template<class ElementVolumeVariables, class ElementFluxVariablesCache> | ||
155 | 660568 | BoundaryFluxes neumann(const Element& element, | |
156 | const FVElementGeometry& fvGeometry, | ||
157 | const ElementVolumeVariables& elemVolVars, | ||
158 | const ElementFluxVariablesCache& elemFluxVarsCache, | ||
159 | const SubControlVolumeFace& scvf) const | ||
160 | { | ||
161 | 660568 | BoundaryFluxes values(0.0); | |
162 | if constexpr (ParentType::isMomentumProblem()) | ||
163 | { | ||
164 |
4/4✓ Branch 0 taken 4776 times.
✓ Branch 1 taken 4376 times.
✓ Branch 2 taken 4376 times.
✓ Branch 3 taken 400 times.
|
27856 | if (isOutlet_(scvf) || isInlet_(scvf)) |
165 | { | ||
166 |
2/2✓ Branch 0 taken 4376 times.
✓ Branch 1 taken 4376 times.
|
17504 | const auto p = isInlet_(scvf) ? deltaP_ : 0.0; |
167 | 52512 | values.axpy(-p, scvf.unitOuterNormal()); | |
168 | } | ||
169 | } | ||
170 | else | ||
171 | { | ||
172 |
4/4✓ Branch 0 taken 315647 times.
✓ Branch 1 taken 5485 times.
✓ Branch 2 taken 5485 times.
✓ Branch 3 taken 310162 times.
|
1273558 | if (isInlet_(scvf) || isOutlet_(scvf)) |
173 | { | ||
174 | 54488 | const auto insideDensity = elemVolVars[scvf.insideScvIdx()].density(); | |
175 | 65820 | values[Indices::conti0EqIdx] = this->faceVelocity(element, fvGeometry, scvf) * insideDensity * scvf.unitOuterNormal(); | |
176 | } | ||
177 | } | ||
178 | |||
179 | 660568 | return values; | |
180 | } | ||
181 | |||
182 | template<class ScvOrScvf> | ||
183 | Scalar density(const Element&, | ||
184 | const FVElementGeometry&, | ||
185 | const ScvOrScvf&, | ||
186 | const bool isPreviousTimeStep = false) const | ||
187 | { | ||
188 | 1635768 | return density_; | |
189 | } | ||
190 | |||
191 | template<class ScvOrScvf> | ||
192 | ✗ | Scalar effectiveViscosity(const Element&, | |
193 | const FVElementGeometry&, | ||
194 | const ScvOrScvf&) const | ||
195 | { | ||
196 | ✗ | return viscosity_; | |
197 | } | ||
198 | |||
199 | template<class VelSolutionVector> | ||
200 | 3 | void computeFluxes(const VelSolutionVector& sol) | |
201 | { | ||
202 | 3 | Scalar influx = 0.0; | |
203 | 3 | Scalar outflux = 0.0; | |
204 | 6 | auto fvGeometry = localView(this->gridGeometry()); | |
205 |
4/4✓ Branch 3 taken 14899 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 14899 times.
✓ Branch 6 taken 3 times.
|
14908 | for (const auto& element : elements(this->gridGeometry().gridView())) |
206 | { | ||
207 | 14899 | fvGeometry.bind(element); | |
208 |
4/4✓ Branch 0 taken 156410 times.
✓ Branch 1 taken 14899 times.
✓ Branch 2 taken 156410 times.
✓ Branch 3 taken 14899 times.
|
186208 | for (const auto& scvf : scvfs(fvGeometry)) |
209 | { | ||
210 |
2/2✓ Branch 0 taken 12918 times.
✓ Branch 1 taken 143492 times.
|
156410 | if (scvf.boundary()) |
211 | { | ||
212 |
2/2✓ Branch 0 taken 217 times.
✓ Branch 1 taken 12701 times.
|
12918 | if (isInlet_(scvf)) |
213 | 1302 | influx += scvf.area() * (sol[fvGeometry.scv(scvf.insideScvIdx()).dofIndex()] * scvf.unitOuterNormal()); | |
214 | |||
215 |
2/2✓ Branch 0 taken 217 times.
✓ Branch 1 taken 12484 times.
|
12701 | else if (isOutlet_(scvf)) |
216 | 1302 | outflux += scvf.area() * (sol[fvGeometry.scv(scvf.insideScvIdx()).dofIndex()] * scvf.unitOuterNormal()); | |
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | 12 | std::cout << "Influx: " << influx << " m^3/s" << std::endl; | |
222 | 9 | std::cout << "Outflux: " << outflux << " m^3/s" << std::endl; | |
223 | 9 | std::cout << "Balance: " << outflux+influx << " m^3/s" << std::endl; | |
224 | |||
225 | 9 | std::cout << "Transmissibility: " << outflux / deltaP_ << " m^3/(s*Pa)" << std::endl; | |
226 | 3 | } | |
227 | |||
228 | #if HAVE_DUNE_FOAMGRID | ||
229 | // Compute the wall shear stress | ||
230 | template<class VelSolutionVector, class GridVariables, class CouplingManager, class Assembler> | ||
231 | 3 | void computeWallShearStress( | |
232 | const VelSolutionVector& curSol, | ||
233 | const GridVariables& gridVariables, | ||
234 | CouplingManager& couplingManager, | ||
235 | const Assembler& assembler | ||
236 | ){ | ||
237 | 3 | const auto& gg = this->gridGeometry(); | |
238 | 3 | const auto& gv = gg.gridView(); | |
239 | |||
240 | using Grid = Dune::FoamGrid<dim-1, dimWorld>; | ||
241 | 3 | Dune::GridFactory<Grid> factory; | |
242 | { | ||
243 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | std::vector<std::vector<std::vector<unsigned int>>> elems; |
244 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | elems.reserve(gg.numBoundaryScvf()); |
245 |
1/2✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
|
9 | std::vector<bool> insertedVertex(gv.size(dim), false); |
246 |
2/6✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
|
9 | std::vector<int> vertexIndexMap(gv.size(dim), -1); |
247 |
3/6✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
|
9 | std::vector<Dune::FieldVector<double, 3>> points; |
248 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | points.reserve(gg.numBoundaryScvf()*4); |
249 | 3 | std::size_t boundaryElementIndex = 0; | |
250 |
6/8✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14899 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 14899 times.
✓ Branch 6 taken 3 times.
✓ Branch 8 taken 14899 times.
✗ Branch 9 not taken.
|
29801 | for (const auto& element : elements(gv)) |
251 | { | ||
252 |
8/14✓ Branch 1 taken 14899 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14899 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 14899 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 86645 times.
✗ Branch 10 not taken.
✓ Branch 15 taken 14899 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 32412 times.
✓ Branch 18 taken 39334 times.
✓ Branch 20 taken 71746 times.
✗ Branch 21 not taken.
|
148855 | for (const auto& intersection : intersections(gv, element)) |
253 | { | ||
254 |
2/2✓ Branch 0 taken 32412 times.
✓ Branch 1 taken 39334 times.
|
71746 | if (intersection.boundary()) |
255 | { | ||
256 |
1/2✓ Branch 1 taken 7890 times.
✗ Branch 2 not taken.
|
7890 | const auto insideIdx = intersection.indexInInside(); |
257 |
1/2✓ Branch 1 taken 7890 times.
✗ Branch 2 not taken.
|
7890 | const auto refElement = referenceElement(element); |
258 | 7890 | const auto numVertices = refElement.size(insideIdx, 1, dim); | |
259 |
2/2✓ Branch 0 taken 5028 times.
✓ Branch 1 taken 2862 times.
|
7890 | if (numVertices == 3) |
260 |
7/16✓ Branch 1 taken 5028 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5028 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5028 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 5028 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 5028 times.
✓ Branch 14 taken 5028 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5028 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
|
20112 | elems.push_back({std::vector<unsigned int>{}}); |
261 |
1/2✓ Branch 0 taken 2862 times.
✗ Branch 1 not taken.
|
2862 | else if (numVertices == 4) |
262 |
8/18✓ Branch 1 taken 2862 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2862 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2862 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2862 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 2862 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 5724 times.
✓ Branch 17 taken 2862 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 5724 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
|
17172 | elems.push_back({std::vector<unsigned int>{}, |
263 | std::vector<unsigned int>{}}); // add two triangles | ||
264 | else | ||
265 | ✗ | DUNE_THROW(Dune::NotImplemented, | |
266 | "Wall shear stress for boundary type with " << numVertices << " corners" | ||
267 | ); | ||
268 | |||
269 | |||
270 |
2/2✓ Branch 0 taken 26532 times.
✓ Branch 1 taken 7890 times.
|
34422 | for (int i = 0; i < numVertices; ++i) |
271 | { | ||
272 | 26532 | const auto localVIdx = refElement.subEntity(insideIdx, 1, i, dim); | |
273 |
1/2✓ Branch 1 taken 26532 times.
✗ Branch 2 not taken.
|
26532 | const auto& vertex = element.template subEntity<dim>(localVIdx); |
274 |
2/4✓ Branch 1 taken 26532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 26532 times.
✗ Branch 5 not taken.
|
53064 | const auto vIdx = gg.vertexMapper().index(vertex); |
275 |
6/6✓ Branch 0 taken 5382 times.
✓ Branch 1 taken 21150 times.
✓ Branch 2 taken 5382 times.
✓ Branch 3 taken 21150 times.
✓ Branch 4 taken 5382 times.
✓ Branch 5 taken 21150 times.
|
79596 | if (!insertedVertex[vIdx]) |
276 | { | ||
277 |
2/4✓ Branch 1 taken 5382 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5382 times.
✗ Branch 5 not taken.
|
10764 | vertexIndexMap[vIdx] = points.size(); |
278 |
3/6✓ Branch 1 taken 5382 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5382 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5382 times.
✗ Branch 8 not taken.
|
10764 | points.push_back(vertex.geometry().corner(0)); |
279 | 16146 | insertedVertex[vIdx] = true; | |
280 | } | ||
281 | |||
282 | |||
283 |
2/2✓ Branch 0 taken 15084 times.
✓ Branch 1 taken 11448 times.
|
26532 | if (numVertices == 3) |
284 |
3/6✓ Branch 1 taken 15084 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15084 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 15084 times.
✗ Branch 8 not taken.
|
45252 | elems[boundaryElementIndex][0].push_back(vertexIndexMap[vIdx]); |
285 | |||
286 |
1/2✓ Branch 0 taken 11448 times.
✗ Branch 1 not taken.
|
11448 | else if (numVertices == 4) |
287 | { | ||
288 | // add two triangles | ||
289 |
2/2✓ Branch 0 taken 2862 times.
✓ Branch 1 taken 8586 times.
|
11448 | if (i == 0) |
290 |
3/6✓ Branch 1 taken 2862 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2862 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2862 times.
✗ Branch 8 not taken.
|
8586 | elems[boundaryElementIndex][0].push_back(vertexIndexMap[vIdx]); |
291 |
2/2✓ Branch 0 taken 5724 times.
✓ Branch 1 taken 2862 times.
|
8586 | else if (i == 1 || i == 2) |
292 | { | ||
293 |
3/6✓ Branch 1 taken 5724 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5724 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5724 times.
✗ Branch 8 not taken.
|
17172 | elems[boundaryElementIndex][0].push_back(vertexIndexMap[vIdx]); |
294 |
4/8✓ Branch 1 taken 5724 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5724 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5724 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 5724 times.
✗ Branch 11 not taken.
|
22896 | elems[boundaryElementIndex][1].push_back(vertexIndexMap[vIdx]); |
295 | } | ||
296 | else | ||
297 |
4/8✓ Branch 1 taken 2862 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2862 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2862 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2862 times.
✗ Branch 11 not taken.
|
11448 | elems[boundaryElementIndex][1].push_back(vertexIndexMap[vIdx]); |
298 | } | ||
299 | else | ||
300 | ✗ | DUNE_THROW(Dune::NotImplemented, | |
301 | "Wall shear stress for boundary type with " << numVertices << " corners" | ||
302 | ); | ||
303 | } | ||
304 | |||
305 | 7890 | ++boundaryElementIndex; | |
306 | } | ||
307 | } | ||
308 | } | ||
309 | |||
310 |
4/4✓ Branch 0 taken 5382 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5382 times.
✓ Branch 3 taken 3 times.
|
5391 | for (const auto& p : points) |
311 |
1/2✓ Branch 1 taken 5382 times.
✗ Branch 2 not taken.
|
5382 | factory.insertVertex(p); |
312 |
4/4✓ Branch 0 taken 7890 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 7890 times.
✓ Branch 3 taken 3 times.
|
7899 | for (const auto& e : elems) |
313 |
4/4✓ Branch 0 taken 10752 times.
✓ Branch 1 taken 7890 times.
✓ Branch 2 taken 10752 times.
✓ Branch 3 taken 7890 times.
|
45174 | for (const auto& ee : e) |
314 |
1/4✓ Branch 1 taken 10752 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
10752 | factory.insertElement(Dune::GeometryTypes::simplex(dim-1), ee); |
315 | } | ||
316 | |||
317 |
1/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
6 | auto bGrid = factory.createGrid(); |
318 | |||
319 | using ElementSet = GridViewGeometricEntitySet<typename Grid::LeafGridView, 0>; | ||
320 | using Tree = BoundingBoxTree<ElementSet>; | ||
321 |
7/16✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 3 times.
✓ Branch 17 taken 3 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
15 | Tree tree(std::make_shared<ElementSet>(bGrid->leafGridView())); |
322 | |||
323 |
2/4✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
|
15 | std::vector<GlobalPosition> wallShearStress(bGrid->leafGridView().size(0)); |
324 | |||
325 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | auto fvGeometry = localView(gg); |
326 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
6 | auto elemVolVars = localView(gridVariables.curGridVolVars()); |
327 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
6 | auto elemFluxVarsCache = localView(gridVariables.gridFluxVarsCache()); |
328 |
7/10✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14899 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 14899 times.
✓ Branch 6 taken 3 times.
✓ Branch 8 taken 14899 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 14899 times.
✗ Branch 12 not taken.
|
14902 | for (const auto& element : elements(gv)) |
329 | { | ||
330 |
2/4✓ Branch 1 taken 14899 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14899 times.
✗ Branch 5 not taken.
|
29798 | const auto h = diameter(element.geometry()); |
331 | 14899 | couplingManager.bindCouplingContext( | |
332 | CouplingManager::freeFlowMomentumIndex, element, assembler | ||
333 | ); | ||
334 |
1/2✓ Branch 1 taken 14899 times.
✗ Branch 2 not taken.
|
14899 | fvGeometry.bind(element); |
335 |
1/2✓ Branch 1 taken 14899 times.
✗ Branch 2 not taken.
|
14899 | elemVolVars.bind(element, fvGeometry, curSol); |
336 |
1/2✓ Branch 1 taken 14899 times.
✗ Branch 2 not taken.
|
14899 | elemFluxVarsCache.bind(element, fvGeometry, elemVolVars); |
337 | |||
338 |
4/4✓ Branch 0 taken 156410 times.
✓ Branch 1 taken 14899 times.
✓ Branch 2 taken 156410 times.
✓ Branch 3 taken 14899 times.
|
186208 | for (const auto& scvf : scvfs(fvGeometry)) |
339 | { | ||
340 |
2/2✓ Branch 0 taken 12918 times.
✓ Branch 1 taken 143492 times.
|
156410 | if (scvf.boundary()) |
341 | { | ||
342 | 12918 | const auto ip = scvf.ipGlobal(); | |
343 | |||
344 | // assemble wss = sigma*n - (sigma*n*n)*n | ||
345 | 12918 | const auto& fluxVarCache = elemFluxVarsCache[scvf]; | |
346 | using Tensor = Dune::FieldMatrix<Scalar, dim>; | ||
347 | 12918 | Tensor sigma(0.0); | |
348 |
4/4✓ Branch 0 taken 64938 times.
✓ Branch 1 taken 12918 times.
✓ Branch 2 taken 64938 times.
✓ Branch 3 taken 12918 times.
|
90774 | for (const auto& scv : scvs(fvGeometry)) |
349 | { | ||
350 | 64938 | const auto& volVars = elemVolVars[scv]; | |
351 |
2/2✓ Branch 0 taken 194814 times.
✓ Branch 1 taken 64938 times.
|
259752 | for (int dir = 0; dir < dim; ++dir) |
352 | 974070 | sigma[dir].axpy(volVars.velocity(dir), fluxVarCache.gradN(scv.indexInElement())); | |
353 | } | ||
354 | 12918 | sigma += getTransposed(sigma); | |
355 | 12918 | sigma *= -this->effectiveViscosity(element, fvGeometry, scvf); | |
356 |
2/2✓ Branch 0 taken 38754 times.
✓ Branch 1 taken 12918 times.
|
51672 | for (int dir = 0; dir < dim; ++dir) |
357 |
1/2✓ Branch 1 taken 38754 times.
✗ Branch 2 not taken.
|
38754 | sigma[dir][dir] += this->pressure(element, fvGeometry, scvf); |
358 | |||
359 | 25836 | const auto sigman = mv(sigma, scvf.unitOuterNormal()); | |
360 | 38754 | const auto normalStress = (sigman * scvf.unitOuterNormal())*scvf.unitOuterNormal(); | |
361 | 12918 | const auto wss = sigman - normalStress; | |
362 | |||
363 | // make sure we hit all triangles of this face | ||
364 |
3/8✓ Branch 1 taken 12918 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12918 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12918 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
51672 | const auto points = EmbeddedCoupling::circlePoints(ip, scvf.unitOuterNormal(), 0.05*h, 4); |
365 |
4/4✓ Branch 0 taken 51672 times.
✓ Branch 1 taken 12918 times.
✓ Branch 2 taken 51672 times.
✓ Branch 3 taken 12918 times.
|
142098 | for (const auto& p : points) |
366 |
6/8✓ Branch 1 taken 51672 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51672 times.
✓ Branch 4 taken 51672 times.
✓ Branch 5 taken 51672 times.
✓ Branch 6 taken 51672 times.
✓ Branch 7 taken 51672 times.
✗ Branch 8 not taken.
|
206688 | for (auto b : intersectingEntities(p, tree)) |
367 | 103344 | wallShearStress[b] = wss; | |
368 | } | ||
369 | } | ||
370 | } | ||
371 | |||
372 |
4/12✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 3 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
9 | Dune::MultipleCodimMultipleGeomTypeMapper<typename Grid::LeafGridView> bMapper( |
373 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
6 | bGrid->leafGridView(), Dune::mcmgLayout(Dune::Codim<0>()) |
374 | ); | ||
375 | using Field = Dumux::Vtk::Field<typename Grid::LeafGridView>; | ||
376 |
3/6✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
|
9 | Dune::VTKWriter<typename Grid::LeafGridView> writer(bGrid->leafGridView()); |
377 |
8/22✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 3 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 3 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 3 times.
✓ Branch 20 taken 3 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
|
12 | writer.addCellData(Field( |
378 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
6 | bGrid->leafGridView(), bMapper, wallShearStress, "wallShearStress", dimWorld |
379 | ).get()); | ||
380 |
5/12✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 3 times.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
12 | writer.write(this->name() + "_wall_shear_stress"); |
381 | 3 | } | |
382 | #endif | ||
383 | |||
384 | private: | ||
385 | bool isInlet_(const SubControlVolumeFace& scvf) const | ||
386 | 1115028 | { return gridData_->getBoundaryDomainMarker(scvf.boundaryFlag()) == 1; } | |
387 | |||
388 | bool isOutlet_(const SubControlVolumeFace& scvf) const | ||
389 | 1085976 | { return gridData_->getBoundaryDomainMarker(scvf.boundaryFlag()) == 2; } | |
390 | |||
391 | static constexpr Scalar eps_ = 1e-10; | ||
392 | Scalar deltaP_, density_, viscosity_; | ||
393 | |||
394 | std::shared_ptr<GridData<typename GridGeometry::GridView::Grid>> gridData_; | ||
395 | }; | ||
396 | |||
397 | } // end namespace Dumux | ||
398 | |||
399 | #endif | ||
400 |