3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
test/freeflow/navierstokes/channel/1d/problem.hh
Go to the documentation of this file.
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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
26#ifndef DUMUX_DONEA_TEST_PROBLEM_HH
27#define DUMUX_DONEA_TEST_PROBLEM_HH
28
29#include <dune/common/fmatrix.hh>
30#include <dune/grid/yaspgrid.hh>
31
34
38#include "../../l2error.hh"
39
40
41namespace Dumux {
42template <class TypeTag>
43class NavierStokesAnalyticProblem;
44
45namespace Properties {
46// Create new type tags
47namespace TTag {
48struct NavierStokesAnalytic { using InheritsFrom = std::tuple<NavierStokes, StaggeredFreeFlowModel>; };
49} // end namespace TTag
50
51// the fluid system
52template<class TypeTag>
53struct FluidSystem<TypeTag, TTag::NavierStokesAnalytic>
54{
57};
58
59// Set the grid type
60template<class TypeTag>
61struct Grid<TypeTag, TTag::NavierStokesAnalytic> { using type = Dune::YaspGrid<1>; };
62
63// Set the problem property
64template<class TypeTag>
65struct Problem<TypeTag, TTag::NavierStokesAnalytic> { using type = Dumux::NavierStokesAnalyticProblem<TypeTag> ; };
66
67template<class TypeTag>
68struct EnableGridGeometryCache<TypeTag, TTag::NavierStokesAnalytic> { static constexpr bool value = true; };
69
70template<class TypeTag>
71struct EnableGridFluxVariablesCache<TypeTag, TTag::NavierStokesAnalytic> { static constexpr bool value = true; };
72template<class TypeTag>
73struct EnableGridVolumeVariablesCache<TypeTag, TTag::NavierStokesAnalytic> { static constexpr bool value = true; };
74
75template<class TypeTag>
76struct NormalizePressure<TypeTag, TTag::NavierStokesAnalytic> { static constexpr bool value = false; };
77} // end namespace Properties
78
87template <class TypeTag>
89{
90 using ParentType = NavierStokesProblem<TypeTag>;
91
100
101 static constexpr auto dimWorld = GetPropType<TypeTag, Properties::GridView>::dimensionworld;
102 using Element = typename GridGeometry::GridView::template Codim<0>::Entity;
103 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
104 using DimVector = GlobalPosition;
105 using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
106
107public:
108 NavierStokesAnalyticProblem(std::shared_ptr<const GridGeometry> gridGeometry)
109 : ParentType(gridGeometry), eps_(1e-6)
110 {
111 printL2Error_ = getParam<bool>("Problem.PrintL2Error");
112 density_ = getParam<Scalar>("Component.LiquidDensity");
113 kinematicViscosity_ = getParam<Scalar>("Component.LiquidKinematicViscosity");
114 createAnalyticalSolution_();
115 }
116
120 // \{
121
123 {
124 return false;
125 }
126
127 void printL2Error(const SolutionVector& curSol) const
128 {
129 if(printL2Error_)
130 {
132 const auto l2error = L2Error::calculateL2Error(*this, curSol);
133 const int numCellCenterDofs = this->gridGeometry().numCellCenterDofs();
134 const int numFaceDofs = this->gridGeometry().numFaceDofs();
135 std::cout << std::setprecision(8) << "** L2 error (abs/rel) for "
136 << std::setw(6) << numCellCenterDofs << " cc dofs and " << numFaceDofs << " face dofs (total: " << numCellCenterDofs + numFaceDofs << "): "
137 << std::scientific
138 << "L2(p) = " << l2error.first[Indices::pressureIdx] << " / " << l2error.second[Indices::pressureIdx]
139 << " , L2(vx) = " << l2error.first[Indices::velocityXIdx] << " / " << l2error.second[Indices::velocityXIdx]
140 << std::endl;
141 }
142 }
143
149 Scalar temperature() const
150 { return 298.0; }
151
157 NumEqVector sourceAtPos(const GlobalPosition &globalPos) const
158 {
159 NumEqVector source(0.0);
160
161 // mass balance - term div(rho*v)
162 for (unsigned int dimIdx = 0; dimIdx < dimWorld; ++dimIdx)
163 {
164 source[Indices::conti0EqIdx] += dvdx(globalPos)[dimIdx][dimIdx];
165 }
166 source[Indices::conti0EqIdx] *= density_;
167
168 // momentum balance
169 for (unsigned int velIdx = 0; velIdx < dimWorld; ++velIdx)
170 {
171 for (unsigned int dimIdx = 0; dimIdx < dimWorld; ++dimIdx)
172 {
173 // inertia term
174 if (this->enableInertiaTerms())
175 source[Indices::velocity(velIdx)] += density_ * dv2dx(globalPos)[velIdx][dimIdx];
176
177 // viscous term (molecular)
178 source[Indices::velocity(velIdx)] -= density_ * kinematicViscosity_* dvdx2(globalPos)[velIdx][dimIdx];
179 static const bool enableUnsymmetrizedVelocityGradient = getParam<bool>("FreeFlow.EnableUnsymmetrizedVelocityGradient", false);
180 if (!enableUnsymmetrizedVelocityGradient)
181 source[Indices::velocity(velIdx)] -= density_ * kinematicViscosity_* dvdx2(globalPos)[dimIdx][velIdx];
182 }
183 // pressure term
184 source[Indices::velocity(velIdx)] += dpdx(globalPos)[velIdx];
185
186 // gravity term
187 static const bool enableGravity = getParam<bool>("Problem.EnableGravity");
188 if (enableGravity)
189 {
190 source[Indices::velocity(velIdx)] -= density_ * this->gravity()[velIdx];
191 }
192 }
193
194 return source;
195 }
196 // \}
200 // \{
201
208 BoundaryTypes boundaryTypesAtPos(const GlobalPosition& globalPos) const
209 {
210 BoundaryTypes values;
211
212 // set Dirichlet values for the velocity everywhere
213 values.setDirichlet(Indices::momentumXBalanceIdx);
214
215 return values;
216 }
217
226 bool isDirichletCell(const Element& element,
227 const typename GridGeometry::LocalView& fvGeometry,
228 const typename GridGeometry::SubControlVolume& scv,
229 int pvIdx) const
230 {
231 // set a fixed pressure in all cells at the boundary
232 for (const auto& scvf : scvfs(fvGeometry))
233 if (scvf.boundary())
234 return true;
235
236 return false;
237 }
238
244 PrimaryVariables dirichletAtPos(const GlobalPosition& globalPos) const
245 {
246 // use the values of the analytical solution
247 return analyticalSolution(globalPos);
248 }
249
255 PrimaryVariables analyticalSolution(const GlobalPosition& globalPos) const
256 {
257 PrimaryVariables values;
258 values[Indices::pressureIdx] = p(globalPos);
259 values[Indices::velocityXIdx] = v(globalPos);
260 return values;
261 }
262
264 const DimVector v(const DimVector& globalPos) const
265 {
266 DimVector v(0.0);
267 v[0] = 2.0 * globalPos[0] * globalPos[0] * globalPos[0];
268 return v;
269 }
270
272 const DimMatrix dvdx(const DimVector& globalPos) const
273 {
274 DimMatrix dvdx(0.0);
275 dvdx[0][0] = 6.0 * globalPos[0] * globalPos[0];
276 return dvdx;
277 }
278
280 const DimMatrix dv2dx(const DimVector& globalPos) const
281 {
282 DimMatrix dv2dx;
283 for (unsigned int velIdx = 0; velIdx < dimWorld; ++velIdx)
284 {
285 for (unsigned int dimIdx = 0; dimIdx < dimWorld; ++dimIdx)
286 {
287 dv2dx[velIdx][dimIdx] = dvdx(globalPos)[velIdx][dimIdx] * v(globalPos)[dimIdx]
288 + dvdx(globalPos)[dimIdx][dimIdx] * v(globalPos)[velIdx];
289 }
290 }
291 return dv2dx;
292 }
293
295 const DimMatrix dvdx2(const DimVector& globalPos) const
296 {
297 DimMatrix dvdx2(0.0);
298 dvdx2[0][0] = 12.0 * globalPos[0];
299 return dvdx2;
300 }
301
303 const Scalar p(const DimVector& globalPos) const
304 { return 2.0 - 2.0 * globalPos[0]; }
305
307 const DimVector dpdx(const DimVector& globalPos) const
308 {
309 DimVector dpdx(0.0);
310 dpdx[0] = -2.0;
311 return dpdx;
312 }
313
314 // \}
315
319 // \{
320
326 PrimaryVariables initialAtPos(const GlobalPosition& globalPos) const
327 {
328 return analyticalSolution(globalPos);
329 }
330
335 {
336 return analyticalPressure_;
337 }
338
343 {
344 return analyticalVelocity_;
345 }
346
351 {
352 return analyticalVelocityOnFace_;
353 }
354
355private:
356
362 void createAnalyticalSolution_()
363 {
364 analyticalPressure_.resize(this->gridGeometry().numCellCenterDofs());
365 analyticalVelocity_.resize(this->gridGeometry().numCellCenterDofs());
366 analyticalVelocityOnFace_.resize(this->gridGeometry().numFaceDofs());
367
368 for (const auto& element : elements(this->gridGeometry().gridView()))
369 {
370 auto fvGeometry = localView(this->gridGeometry());
371 fvGeometry.bindElement(element);
372 for (auto&& scv : scvs(fvGeometry))
373 {
374 auto ccDofIdx = scv.dofIndex();
375 auto ccDofPosition = scv.dofPosition();
376 auto analyticalSolutionAtCc = analyticalSolution(ccDofPosition);
377
378 // velocities on faces
379 for (auto&& scvf : scvfs(fvGeometry))
380 {
381 const auto faceDofIdx = scvf.dofIndex();
382 const auto faceDofPosition = scvf.center();
383 const auto dirIdx = scvf.directionIndex();
384 const auto analyticalSolutionAtFace = analyticalSolution(faceDofPosition);
385 analyticalVelocityOnFace_[faceDofIdx][dirIdx] = analyticalSolutionAtFace[Indices::velocity(dirIdx)];
386 }
387
388 analyticalPressure_[ccDofIdx] = analyticalSolutionAtCc[Indices::pressureIdx];
389
390 for(int dirIdx = 0; dirIdx < ModelTraits::dim(); ++dirIdx)
391 analyticalVelocity_[ccDofIdx][dirIdx] = analyticalSolutionAtCc[Indices::velocity(dirIdx)];
392 }
393 }
394 }
395
396 Scalar eps_;
397 bool printL2Error_;
398 Scalar density_;
399 Scalar kinematicViscosity_;
400 std::vector<Scalar> analyticalPressure_;
401 std::vector<GlobalPosition> analyticalVelocity_;
402 std::vector<GlobalPosition> analyticalVelocityOnFace_;
403};
404} // end namespace Dumux
405
406#endif
Setting constant fluid properties via the input file.
A liquid phase consisting of a single component.
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:149
The DUNE grid type.
Definition: common/properties.hh:57
Property to specify the type of a problem which has to be solved.
Definition: common/properties.hh:69
Definition: common/properties.hh:169
If disabled, the volume variables are not stored (reduces memory, but is slower)
Definition: common/properties.hh:178
specifies if data on flux vars should be saved (faster, but more memory consuming)
Definition: common/properties.hh:188
The type of the fluid system to use.
Definition: common/properties.hh:223
Returns whether to normalize the pressure term in the momentum balance or not.
Definition: common/properties.hh:346
Navier-Stokes problem base class.
Definition: dumux/freeflow/navierstokes/problem.hh:63
const GravityVector & gravity() const
Returns the acceleration due to gravity.
Definition: dumux/freeflow/navierstokes/problem.hh:134
bool enableInertiaTerms() const
Returns whether interia terms should be considered.
Definition: dumux/freeflow/navierstokes/problem.hh:140
A liquid phase consisting of a single component.
Definition: 1pliquid.hh:46
Test for the 1-D Navier-Stokes model with an analytical solution.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:89
const DimMatrix dvdx(const DimVector &globalPos) const
The velocity gradient.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:272
NumEqVector sourceAtPos(const GlobalPosition &globalPos) const
Returns the sources within the domain.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:157
NavierStokesAnalyticProblem(std::shared_ptr< const GridGeometry > gridGeometry)
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:108
const Scalar p(const DimVector &globalPos) const
The pressure.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:303
bool shouldWriteRestartFile() const
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:122
const DimMatrix dv2dx(const DimVector &globalPos) const
The gradient of the velocity squared (using product rule -> nothing to do here)
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:280
PrimaryVariables analyticalSolution(const GlobalPosition &globalPos) const
Returns the analytical solution of the problem at a given position.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:255
auto & getAnalyticalVelocitySolutionOnFace() const
Returns the analytical solution for the velocity at the faces.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:350
const DimVector dpdx(const DimVector &globalPos) const
The pressure gradient.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:307
PrimaryVariables initialAtPos(const GlobalPosition &globalPos) const
Evaluates the initial value for a control volume.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:326
auto & getAnalyticalPressureSolution() const
Returns the analytical solution for the pressure.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:334
Scalar temperature() const
Returns the temperature within the domain in [K].
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:149
BoundaryTypes boundaryTypesAtPos(const GlobalPosition &globalPos) const
Specifies which kind of boundary condition should be used for which equation on a given boundary cont...
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:208
bool isDirichletCell(const Element &element, const typename GridGeometry::LocalView &fvGeometry, const typename GridGeometry::SubControlVolume &scv, int pvIdx) const
Returns whether a fixed Dirichlet value shall be used at a given cell.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:226
auto & getAnalyticalVelocitySolution() const
Returns the analytical solution for the velocity.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:342
PrimaryVariables dirichletAtPos(const GlobalPosition &globalPos) const
Returns Dirichlet boundary values at a given position.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:244
const DimVector v(const DimVector &globalPos) const
The velocity.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:264
const DimMatrix dvdx2(const DimVector &globalPos) const
The gradient of the velocity gradient.
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:295
void printL2Error(const SolutionVector &curSol) const
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:127
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:48
std::tuple< NavierStokes, StaggeredFreeFlowModel > InheritsFrom
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:48
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:55
Dune::YaspGrid< 1 > type
Definition: test/freeflow/navierstokes/channel/1d/problem.hh:61
Routines to calculate the discrete L2 error.
Definition: l2error.hh:38
Defines a type tag and some properties for ree-flow models using the staggered scheme....
A single-phase, isothermal Navier-Stokes model.