version 3.11-dev
Loading...
Searching...
No Matches
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// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_DISCRETIZATION_EVAL_SOLUTION_HH
13#define DUMUX_DISCRETIZATION_EVAL_SOLUTION_HH
14
15#include <iterator>
16#include <algorithm>
17#include <type_traits>
18#include <memory>
19
20#include <dune/localfunctions/lagrange/pqkfactory.hh>
21
27
28namespace Dumux {
29
30// some implementation details
31namespace Detail {
32
34template<class ElementSolution>
35bool allStatesEqual(const ElementSolution& elemSol, std::true_type hasState)
36{
37 // determine if all states are the same at all vertices
38 auto firstState = elemSol[0].state();
39 for (std::size_t i = 1; i < elemSol.size(); ++i)
40 if (elemSol[i].state() != firstState)
41 return false;
42
43 return true;
44}
45
47template<class ElementSolution>
48bool allStatesEqual(const ElementSolution& elemSol, std::false_type hasState)
49{
50 return true;
51}
52
54template<class Geometry, class ElementSolution>
55auto minDistVertexSol(const Geometry& geometry, const typename Geometry::GlobalCoordinate& globalPos,
56 const ElementSolution& elemSol)
57{
58 // calculate the distances from the evaluation point to the vertices
59 std::vector<typename Geometry::ctype> distances(geometry.corners());
60 for (int i = 0; i < geometry.corners(); ++i)
61 distances[i] = (geometry.corner(i) - globalPos).two_norm2();
62
63 // determine the minimum distance and corresponding vertex
64 auto minDistanceIt = std::min_element(distances.begin(), distances.end());
65 return elemSol[std::distance(distances.begin(), minDistanceIt)];
66}
67
69template<class Element, class GridGeometry, class ElementSolution>
70auto minDistDofSol(const Element& element,
71 const GridGeometry& gridGeometry,
72 const typename Element::Geometry::LocalCoordinate& localPos,
73 const ElementSolution& elemSol)
74{
75 using DofHelper = GridGeometry::Cache::DofHelper;
76 const auto& localCoeffs = gridGeometry.feCache().get(element.type()).localCoefficients();
77 // calculate the distances from the evaluation point to the local positions of dofs
78 std::vector<typename Element::Geometry::ctype> distances(localCoeffs.size());
79 for (int idx = 0; idx < localCoeffs.size(); ++idx)
80 {
81 const auto& localDofPos = DofHelper::localDofPosition(element.type(), localCoeffs.localKey(idx));
82 distances[idx] = (localPos - localDofPos).two_norm2();
83 }
84
85 // determine the minimum distance and corresponding vertex
86 auto minDistanceIt = std::min_element(distances.begin(), distances.end());
87 return elemSol[std::distance(distances.begin(), minDistanceIt)];
88}
89
103template<class Element, class GridGeometry, class CVFEElemSol>
104typename CVFEElemSol::PrimaryVariables
105evalCVFESolutionAtLocalPos(const Element& element,
106 const typename Element::Geometry& geometry,
107 const GridGeometry& gridGeometry,
108 const CVFEElemSol& elemSol,
109 const typename Element::Geometry::LocalCoordinate& localPos,
110 bool ignoreState = false)
111{
112 // determine if all states are the same at all vertices
113 using HasState = decltype(isValid(Detail::hasState())(elemSol[0]));
114 bool allStatesEqual = ignoreState || Detail::allStatesEqual(elemSol, HasState{});
115
116 if (allStatesEqual)
117 {
118 // interpolate the solution
119 const auto& localBasis = gridGeometry.feCache().get(geometry.type()).localBasis();
120
121 // evaluate the shape functions at the scv center
122 using ShapeValue = typename std::decay_t<decltype(localBasis)>::Traits::RangeType;
123 std::vector<ShapeValue> shapeValues;
124 localBasis.evaluateFunction(localPos, shapeValues);
125
126 typename CVFEElemSol::PrimaryVariables result(0.0);
127 for (int i = 0; i < shapeValues.size(); ++i)
128 {
129 auto value = elemSol[i];
130 value *= shapeValues[i][0];
131 result += value;
132 }
133
134 // set an arbitrary state if the model requires a state (models constexpr if)
135 if constexpr (HasState{})
136 if (!ignoreState)
137 result.setState(elemSol[0].state());
138
139 return result;
140 }
141 else
142 {
143 static bool warnedAboutUsingMinDist = false;
144 if (!warnedAboutUsingMinDist)
145 {
146 std::cout << "Warning: Using nearest-neighbor interpolation in evalSolution"
147 << "\nbecause not all states are equal and ignoreState is false!"
148 << std::endl;
149 warnedAboutUsingMinDist = true;
150 }
151
152 return Detail::minDistDofSol(element, gridGeometry, localPos, elemSol);
153 }
154}
155
156} // end namespace Detail
157
171template<class Element, class FVElementGeometry, class PrimaryVariables>
172PrimaryVariables evalSolutionAtLocalPos(const Element& element,
173 const typename Element::Geometry& geometry,
174 const typename FVElementGeometry::GridGeometry& gridGeometry,
176 const typename Element::Geometry::LocalCoordinate& localPos,
177 bool ignoreState = false)
178{
179 return Detail::evalCVFESolutionAtLocalPos(element, geometry, gridGeometry, elemSol, localPos, ignoreState);
180}
181
182
196template<class Element, class FVElementGeometry, class PrimaryVariables>
197PrimaryVariables evalSolution(const Element& element,
198 const typename Element::Geometry& geometry,
199 const typename FVElementGeometry::GridGeometry& gridGeometry,
201 const typename Element::Geometry::GlobalCoordinate& globalPos,
202 bool ignoreState = false)
203{
204 const auto& localPos = geometry.local(globalPos);
205 return evalSolutionAtLocalPos(element, geometry, gridGeometry, elemSol, localPos, ignoreState);
206}
207
222template<class Element, class FVElementGeometry, class PrimaryVariables>
223PrimaryVariables evalSolution(const Element& element,
224 const typename Element::Geometry& geometry,
226 const typename Element::Geometry::GlobalCoordinate& globalPos,
227 bool ignoreState = false)
228{
229 static_assert(FVElementGeometry::GridGeometry::discMethod == DiscretizationMethods::box, "Only implemented for the Box method");
230
231 // determine if all states are the same at all vertices
232 using HasState = decltype(isValid(Detail::hasState())(elemSol[0]));
233 bool allStatesEqual = ignoreState || Detail::allStatesEqual(elemSol, HasState{});
234
235 if (allStatesEqual)
236 {
237 using CoordScalar = typename Element::Geometry::GlobalCoordinate::value_type;
238 static constexpr int dim = Element::Geometry::mydimension;
239
240 // The box scheme always uses linear Ansatz functions (real-valued also for complex-valued solutions)
241 using FEFactory = Dune::PQkLocalFiniteElementFactory<CoordScalar, CoordScalar, dim, 1>;
242 using FiniteElement = typename FEFactory::FiniteElementType;
243 std::unique_ptr<FiniteElement> fe(FEFactory::create(geometry.type()));
244 const auto& localBasis = fe->localBasis();
245
246 // evaluate the shape functions at the scv center
247 const auto localPos = geometry.local(globalPos);
248 using ShapeValue = typename FiniteElement::Traits::LocalBasisType::Traits::RangeType;
249 std::vector< ShapeValue > shapeValues;
250 localBasis.evaluateFunction(localPos, shapeValues);
251
252 PrimaryVariables result(0.0);
253 for (int i = 0; i < geometry.corners(); ++i)
254 {
255 auto value = elemSol[i];
256 value *= shapeValues[i][0];
257 result += value;
258 }
259
260 // set an arbitrary state if the model requires a state (models constexpr if)
261 if constexpr (HasState{})
262 if (!ignoreState)
263 result.setState(elemSol[0].state());
264
265 return result;
266 }
267 else
268 {
269 static bool warnedAboutUsingMinDist = false;
270 if (!warnedAboutUsingMinDist)
271 {
272 std::cout << "Warning: Using nearest-neighbor interpolation in evalSolution"
273 << "\nbecause not all states are equal and ignoreState is false!"
274 << std::endl;
275 warnedAboutUsingMinDist = true;
276 }
277
278 return Detail::minDistVertexSol(geometry, globalPos, elemSol);
279 }
280}
281
294template<class Element, class FVElementGeometry, class PrimaryVariables>
295PrimaryVariables evalSolution(const Element& element,
296 const typename Element::Geometry& geometry,
297 const typename FVElementGeometry::GridGeometry& gridGeometry,
299 const typename Element::Geometry::GlobalCoordinate& globalPos,
300 bool ignoreState = false)
301{
302 return elemSol[0];
303}
304
317template<class Element, class FVElementGeometry, class PrimaryVariables>
318PrimaryVariables evalSolutionAtLocalPos(const Element& element,
319 const typename Element::Geometry& geometry,
320 const typename FVElementGeometry::GridGeometry& gridGeometry,
322 const typename Element::Geometry::LocalCoordinate& localPos,
323 bool ignoreState = false)
324{
325 return elemSol[0];
326}
327
328
342template< class Element, class FVElementGeometry, class PrimaryVariables>
343PrimaryVariables evalSolution(const Element& element,
344 const typename Element::Geometry& geometry,
346 const typename Element::Geometry::GlobalCoordinate& globalPos,
347 bool ignoreState = false)
348{
349 return elemSol[0];
350}
351
352} // namespace Dumux
353
354#endif
The local element solution class for cell-centered methods.
The element solution vector.
Definition cellcentered/elementsolution.hh:28
The element solution vector.
Definition cvfe/elementsolution.hh:48
The local element solution class for control-volume finite element methods.
PrimaryVariables evalSolution(const Element &element, const typename Element::Geometry &geometry, const typename FVElementGeometry::GridGeometry &gridGeometry, const CVFEElementSolution< 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:197
CVFEElemSol::PrimaryVariables evalCVFESolutionAtLocalPos(const Element &element, const typename Element::Geometry &geometry, const GridGeometry &gridGeometry, const CVFEElemSol &elemSol, const typename Element::Geometry::LocalCoordinate &localPos, bool ignoreState=false)
Interpolates a given control-volume finite element solution at a given global position....
Definition evalsolution.hh:105
PrimaryVariables evalSolutionAtLocalPos(const Element &element, const typename Element::Geometry &geometry, const typename FVElementGeometry::GridGeometry &gridGeometry, const CVFEElementSolution< FVElementGeometry, PrimaryVariables > &elemSol, const typename Element::Geometry::LocalCoordinate &localPos, bool ignoreState=false)
Interpolates a given cvfe element solution at a given local position. Uses the finite element cache o...
Definition evalsolution.hh:172
constexpr auto isValid(const Expression &t)
A function that creates a test functor to do class member introspection at compile time.
Definition isvalid.hh:81
A helper function for class member function introspection.
The available discretization methods in Dumux.
Definition cvfelocalresidual.hh:25
auto minDistVertexSol(const Geometry &geometry, const typename Geometry::GlobalCoordinate &globalPos, const ElementSolution &elemSol)
return the solution at the closest vertex dof
Definition evalsolution.hh:55
bool allStatesEqual(const ElementSolution &elemSol, std::true_type hasState)
returns true if all states in an element solution are the same
Definition evalsolution.hh:35
auto minDistDofSol(const Element &element, const GridGeometry &gridGeometry, const typename Element::Geometry::LocalCoordinate &localPos, const ElementSolution &elemSol)
return the solution at the closest dof
Definition evalsolution.hh:70
constexpr Box box
Definition method.hh:176
Definition adapt.hh:17
Type traits to be used with matrix types.
helper struct detecting if a PrimaryVariables object has a state() function
Definition state.hh:21