version 3.9
velocityreconstruction.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// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_NAVIERSTOKES_STAGGERED_VELOCITYRECONSTRUCTION_HH
13#define DUMUX_NAVIERSTOKES_STAGGERED_VELOCITYRECONSTRUCTION_HH
14
15#include <numeric>
16#include <algorithm>
17#include <dune/common/reservedvector.hh>
19
20namespace Dumux {
21
27{
29 template<class VelocityHelper, class FVElementGeometry>
30 static auto cellCenterVelocity(const VelocityHelper& getFaceVelocity,
31 const FVElementGeometry& fvGeometry)
32 {
33 static_assert(FVElementGeometry::GridGeometry::discMethod == DiscretizationMethods::cctpfa);
34 using VelocityVector = typename FVElementGeometry::GridGeometry::GlobalCoordinate;
35 VelocityVector result(0.0);
36
37 const auto directionIndex = [&](const auto& vector)
38 {
39 return std::find_if(vector.begin(), vector.end(), [](const auto& x) { return std::abs(x) > 1e-8; } ) - vector.begin();
40 };
41
42 for (const auto& scvf : scvfs(fvGeometry))
43 {
44 const auto dirIdx = directionIndex(scvf.unitOuterNormal());
45 result[dirIdx] += 0.5*getFaceVelocity(fvGeometry, scvf)[dirIdx];
46 }
47 return result;
48 }
49
51 template<class SubControlVolume, class FVElementGeometry, class VelocityHelper>
52 static auto faceVelocity(const SubControlVolume& scv,
53 const FVElementGeometry& fvGeometry,
54 const VelocityHelper& getNormalVelocityDofValue)
55 {
56 int axis = scv.dofAxis();
57 const int dim = FVElementGeometry::GridGeometry::GridView::dimension;
58 using Scalar = typename SubControlVolume::Traits::Scalar;
59 using GlobalPosition = typename FVElementGeometry::GridGeometry::GlobalCoordinate;
60 using VelocityVector = typename FVElementGeometry::GridGeometry::GlobalCoordinate;
61 VelocityVector faceVelocityVector(0.0);
62
63 // per dimension, we have at max two velocities from which we'll compute an average
64 std::array<Dune::ReservedVector<Scalar, 2>, dim> normalVelocities;
65 if (scv.boundary() && !fvGeometry.gridGeometry().dofOnPeriodicBoundary(scv.dofIndex()))
66 {
67 // iterate through the inner lateral velocities,
68 for (const auto& scvf : scvfs(fvGeometry, scv))
69 {
70 if (scvf.isFrontal())
71 continue;
72
73 // at a lateral velocity, find the inner and outer normal velocities
74 const auto& orthogonalScvf = fvGeometry.lateralOrthogonalScvf(scvf);
75 const auto& lateralScv = fvGeometry.scv(orthogonalScvf.insideScvIdx());
76 auto lateralAxis = lateralScv.dofAxis();
77 normalVelocities[lateralAxis].push_back( getNormalVelocityDofValue(lateralScv) ) ;
78 }
79 }
80 else
81 {
82 // Find the location of interpolation, if periodic, from both sides
83 const GlobalPosition selfPosition = scv.dofPosition();
84 GlobalPosition outsideSelfPosition = selfPosition;
85 if (fvGeometry.gridGeometry().dofOnPeriodicBoundary(scv.dofIndex()))
86 outsideSelfPosition = fvGeometry.outsidePeriodicScv(scv).dofPosition();
87
88 // iterate through the lateral velocities to get to the normal locations
89 for (const auto& scvf : scvfs(fvGeometry, scv))
90 {
91 if (scvf.isFrontal())
92 continue;
93
94 // at a lateral velocity, find the inner and outer normal velocities
95 const auto& orthogonalScvf = fvGeometry.lateralOrthogonalScvf(scvf);
96 const auto& insideLateralScv = fvGeometry.scv(orthogonalScvf.insideScvIdx());
97 const auto& outsideLateralScv = fvGeometry.scv(orthogonalScvf.outsideScvIdx());
98 const auto& lateralAxis = insideLateralScv.dofAxis();
99
100 // Find the inside normal velocities
101 const auto& insideNormalVelocity = getNormalVelocityDofValue(insideLateralScv);
102 const auto& insideNormalPosition = insideLateralScv.dofPosition()[axis];
103
104 // Find the outside normal velocities
105 const auto& outsideNormalVelocity = getNormalVelocityDofValue(outsideLateralScv);
106 const auto& outsideNormalPosition = outsideLateralScv.dofPosition()[axis];
107
108 // Linear interpolation at the face plane and add to normal velocity collection
109 const auto& innerDistance = std::abs(insideNormalPosition - selfPosition[axis]);
110 const auto& totalDistance = std::abs(outsideNormalPosition - outsideSelfPosition[axis]) + innerDistance;
111 const auto& velDiff = outsideNormalVelocity - insideNormalVelocity;
112
113 normalVelocities[lateralAxis].push_back(insideNormalVelocity + (velDiff * innerDistance / totalDistance));
114 }
115 }
116
117 for (int i = 0; i < faceVelocityVector.size(); i++)
118 {
119 if (i == axis)
120 faceVelocityVector[i] = getNormalVelocityDofValue(scv);
121 else
122 faceVelocityVector[i] = std::accumulate(normalVelocities[i].begin(), normalVelocities[i].end(), 0.0) / normalVelocities[i].size();
123 }
124
125 return faceVelocityVector;
126 }
127
128};
129
130} // end namespace Dumux
131
132#endif // DUMUX_NAVIERSTOKES_STAGGERED_VELOCITYRECONSTRUCTION_HH
static unsigned int directionIndex(Vector &&vector)
Returns the direction index of the facet (0 = x, 1 = y, 2 = z)
Definition: staggeredgeometryhelper.hh:121
The available discretization methods in Dumux.
constexpr CCTpfa cctpfa
Definition: method.hh:145
Definition: adapt.hh:17
Helper class for reconstructing the velocity.
Definition: velocityreconstruction.hh:27
static auto cellCenterVelocity(const VelocityHelper &getFaceVelocity, const FVElementGeometry &fvGeometry)
Return the velocity vector at the center of the primal grid.
Definition: velocityreconstruction.hh:30
static auto faceVelocity(const SubControlVolume &scv, const FVElementGeometry &fvGeometry, const VelocityHelper &getNormalVelocityDofValue)
Return the velocity vector at dof position given an scv.
Definition: velocityreconstruction.hh:52