3.5-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
evalsolution.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 *****************************************************************************/
24#ifndef DUMUX_DISCRETIZATION_EVAL_SOLUTION_HH
25#define DUMUX_DISCRETIZATION_EVAL_SOLUTION_HH
26
27#include <iterator>
28#include <algorithm>
29#include <type_traits>
30#include <memory>
31
32#include <dune/localfunctions/lagrange/pqkfactory.hh>
33
38
39namespace Dumux {
40
41// some implementation details
42namespace Detail {
43
45template<class ElementSolution>
46bool allStatesEqual(const ElementSolution& elemSol, std::true_type hasState)
47{
48 // determine if all states are the same at all vertices
49 auto firstState = elemSol[0].state();
50 for (std::size_t i = 1; i < elemSol.size(); ++i)
51 if (elemSol[i].state() != firstState)
52 return false;
53
54 return true;
55}
56
58template<class ElementSolution>
59bool allStatesEqual(const ElementSolution& elemSol, std::false_type hasState)
60{
61 return true;
62}
63
65template<class Geometry, class ElementSolution>
66auto minDistVertexSol(const Geometry& geometry, const typename Geometry::GlobalCoordinate& globalPos,
67 const ElementSolution& elemSol)
68{
69 // calculate the distances from the evaluation point to the vertices
70 std::vector<typename Geometry::ctype> distances(geometry.corners());
71 for (int i = 0; i < geometry.corners(); ++i)
72 distances[i] = (geometry.corner(i) - globalPos).two_norm2();
73
74 // determine the minimum distance and corresponding vertex
75 auto minDistanceIt = std::min_element(distances.begin(), distances.end());
76 return elemSol[std::distance(distances.begin(), minDistanceIt)];
77}
78
79} // end namespace Detail
80
94template<class Element, class FVElementGeometry, class PrimaryVariables>
95PrimaryVariables evalSolution(const Element& element,
96 const typename Element::Geometry& geometry,
97 const typename FVElementGeometry::GridGeometry& gridGeometry,
99 const typename Element::Geometry::GlobalCoordinate& globalPos,
100 bool ignoreState = false)
101{
102 // determine if all states are the same at all vertices
103 using HasState = decltype(isValid(Detail::hasState())(elemSol[0]));
104 bool allStatesEqual = ignoreState || Detail::allStatesEqual(elemSol, HasState{});
105
106 if (allStatesEqual)
107 {
108 using Scalar = typename PrimaryVariables::value_type;
109
110 // interpolate the solution
111 const auto& localBasis = gridGeometry.feCache().get(geometry.type()).localBasis();
112
113 // evaluate the shape functions at the scv center
114 const auto localPos = geometry.local(globalPos);
115 std::vector< Dune::FieldVector<Scalar, 1> > shapeValues;
116 localBasis.evaluateFunction(localPos, shapeValues);
117
118 PrimaryVariables result(0.0);
119 for (int i = 0; i < geometry.corners(); ++i)
120 {
121 auto value = elemSol[i];
122 value *= shapeValues[i][0];
123 result += value;
124 }
125
126 // set an arbitrary state if the model requires a state (models constexpr if)
127 if constexpr (HasState{})
128 if (!ignoreState)
129 result.setState(elemSol[0].state());
130
131 return result;
132 }
133 else
134 {
135 static bool warnedAboutUsingMinDist = false;
136 if (!warnedAboutUsingMinDist)
137 {
138 std::cout << "Warning: Using nearest-neighbor interpolation in evalSolution"
139 << "\nbecause not all states are equal and ignoreState is false!"
140 << std::endl;
141 warnedAboutUsingMinDist = true;
142 }
143
144 return Detail::minDistVertexSol(geometry, globalPos, elemSol);
145 }
146}
147
162template<class Element, class FVElementGeometry, class PrimaryVariables>
163PrimaryVariables evalSolution(const Element& element,
164 const typename Element::Geometry& geometry,
166 const typename Element::Geometry::GlobalCoordinate& globalPos,
167 bool ignoreState = false)
168{
169 // determine if all states are the same at all vertices
170 using HasState = decltype(isValid(Detail::hasState())(elemSol[0]));
171 bool allStatesEqual = ignoreState || Detail::allStatesEqual(elemSol, HasState{});
172
173 if (allStatesEqual)
174 {
175 using Scalar = typename PrimaryVariables::value_type;
176 using CoordScalar = typename Element::Geometry::GlobalCoordinate::value_type;
177 static constexpr int dim = Element::Geometry::mydimension;
178
179 // The box scheme always uses linear Ansatz functions
180 using FEFactory = Dune::PQkLocalFiniteElementFactory<CoordScalar, Scalar, dim, 1>;
181 using FiniteElement = typename FEFactory::FiniteElementType;
182 std::unique_ptr<FiniteElement> fe(FEFactory::create(geometry.type()));
183 const auto& localBasis = fe->localBasis();
184
185 // evaluate the shape functions at the scv center
186 const auto localPos = geometry.local(globalPos);
187 using ShapeValue = typename FiniteElement::Traits::LocalBasisType::Traits::RangeType;
188 std::vector< ShapeValue > shapeValues;
189 localBasis.evaluateFunction(localPos, shapeValues);
190
191 PrimaryVariables result(0.0);
192 for (int i = 0; i < geometry.corners(); ++i)
193 {
194 auto value = elemSol[i];
195 value *= shapeValues[i][0];
196 result += value;
197 }
198
199 // set an arbitrary state if the model requires a state (models constexpr if)
200 if constexpr (HasState{})
201 if (!ignoreState)
202 result.setState(elemSol[0].state());
203
204 return result;
205 }
206 else
207 {
208 static bool warnedAboutUsingMinDist = false;
209 if (!warnedAboutUsingMinDist)
210 {
211 std::cout << "Warning: Using nearest-neighbor interpolation in evalSolution"
212 << "\nbecause not all states are equal and ignoreState is false!"
213 << std::endl;
214 warnedAboutUsingMinDist = true;
215 }
216
217 return Detail::minDistVertexSol(geometry, globalPos, elemSol);
218 }
219}
220
233template<class Element, class FVElementGeometry, class PrimaryVariables>
234PrimaryVariables evalSolution(const Element& element,
235 const typename Element::Geometry& geometry,
236 const typename FVElementGeometry::GridGeometry& gridGeometry,
238 const typename Element::Geometry::GlobalCoordinate& globalPos,
239 bool ignoreState = false)
240{
241 return elemSol[0];
242}
243
257template< class Element, class FVElementGeometry, class PrimaryVariables>
258PrimaryVariables evalSolution(const Element& element,
259 const typename Element::Geometry& geometry,
261 const typename Element::Geometry::GlobalCoordinate& globalPos,
262 bool ignoreState = false)
263{
264 return elemSol[0];
265}
266
267} // namespace Dumux
268
269#endif
Type traits to be used with matrix types.
A helper function for class member function introspection.
static ctype distance(const Dune::FieldVector< ctype, dimWorld > &a, const Dune::FieldVector< ctype, dimWorld > &b)
Compute the shortest distance between two points.
Definition: distance.hh:292
PrimaryVariables evalSolution(const Element &element, const typename Element::Geometry &geometry, const typename FVElementGeometry::GridGeometry &gridGeometry, const BoxElementSolution< FVElementGeometry, PrimaryVariables > &elemSol, const typename Element::Geometry::GlobalCoordinate &globalPos, bool ignoreState=false)
Interpolates a given box element solution at a given global position. Uses the finite element cache o...
Definition: evalsolution.hh:95
Definition: adapt.hh:29
constexpr auto isValid(const Expression &t)
A function that creates a test functor to do class member introspection at compile time.
Definition: isvalid.hh:93
auto minDistVertexSol(const Geometry &geometry, const typename Geometry::GlobalCoordinate &globalPos, const ElementSolution &elemSol)
return the solution at the closest dof
Definition: evalsolution.hh:66
bool allStatesEqual(const ElementSolution &elemSol, std::true_type hasState)
returns true if all states in an element solution are the same
Definition: evalsolution.hh:46
bool allStatesEqual(const ElementSolution &elemSol, std::false_type hasState)
overload if the solution is stateless
Definition: evalsolution.hh:59
helper struct detecting if a PrimaryVariables object has a state() function
Definition: state.hh:32
The element solution vector.
Definition: box/elementsolution.hh:39
The element solution vector.
Definition: cellcentered/elementsolution.hh:40
The local element solution class for the box method.
The local element solution class for cell-centered methods.