Dune-Fufem 2.12-git
Loading...
Searching...
No Matches
deformationfunction.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
3
4#ifndef DEFORMATION_FUNCTION_HH
5#define DEFORMATION_FUNCTION_HH
6
7#include <cstddef>
8#include <iostream>
9#include <limits>
10#include <memory>
11#include <vector>
12
16
17#include <dune/istl/bvector.hh>
18
20
22
25
30
31
32
34
35
36
49template<class HG, std::size_t deformedDim, class ct = double>
51 : public Dune::DiscreteCoordFunction<ct, deformedDim, Dune::Fufem::Experimental::DeformationFunction<HG, deformedDim, ct>>
52{
53 static constexpr int dim = HG::dimension;
54
55 using HostLeafGridView = typename HG::LeafGridView;
59 deformedDim>;
60
61public:
62
63 using HostGrid = HG;
64 using Domain = typename HostGrid::template Codim<dim>::Geometry::GlobalCoordinate;
65 using ctype = ct;
69
70private:
71
72 // Generic evaluate implementation. Since this is templated
73 // is virtual, we have to redirect the virtual interface methods
74 // here manually.
75 template<unsigned int codim>
76 void evaluateImpl(const typename HostGrid::template Codim<codim>::Entity& entity, unsigned int corner, Range& y) const
77 {
78 if (hostGrid_->leafIndexSet().contains(entity))
79 {
80 const auto& leafIndexSet = hostGrid_->leafIndexSet();
81 y = coefficients_[leafIndexSet.subIndex(entity, corner, dim)];
82 }
83 else
84 {
85 auto level = entity.level();
86 const auto& levelIndexSet = hostGrid_->levelIndexSet(level);
87 y = coefficients_[leafIndices_[level][levelIndexSet.subIndex(entity, corner, dim)]];
88 }
89 }
90
91public:
92
97 DeformationFunction(const HostGrid& hostGrid, Dune::index_constant<deformedDim> deformedDimConstant = {})
98 : hostGrid_(&hostGrid)
101 {
103 }
104
110 template<class F>
111 DeformationFunction(const HostGrid& hostGrid, const F& f, Dune::index_constant<deformedDim> deformedDimConstant = {})
112 : DeformationFunction(hostGrid)
113 {
114 interpolate(f);
115 }
116
118 {}
119
121 virtual void evaluate(const typename HostGrid::template Codim<0>::Entity& entity, unsigned int corner, Range& y) const
122 {
123 evaluateImpl<0>(entity, corner, y);
124 }
125
127 virtual void evaluate(const typename HostGrid::template Codim<dim>::Entity& entity, unsigned int corner, Range& y) const
128 {
129 evaluateImpl<dim>(entity, corner, y);
130 }
131
133 void adapt()
134 {
135 DUNE_THROW(Dune::NotImplemented, "DeformationFunction::adapt() is not implemented");
136 }
137
143 const Basis& basis() const
144 {
145 return basis_;
146 }
147
155 {
156 return coefficients_;
157 }
158
166 {
167 return coefficients_;
168 }
169
178 template<class F>
179 void interpolate(const F& f)
180 {
182 }
183
184protected:
185
187 {
188 constexpr std::size_t unsetIndex = std::numeric_limits<std::size_t>::max();
189
190 const auto& leafIndexSet = hostGrid_->leafIndexSet();
191 const auto& idSet = hostGrid_->localIdSet();
192
193 // Progress fine to coarse to compute all level-index to leaf-index map
194 leafIndices_.resize(hostGrid_->maxLevel());
195 for (int level=hostGrid_->maxLevel()-1; level>=0; --level)
196 {
197 const auto& levelGridView = hostGrid_->levelGridView(level);
198 const auto& levelIndexSet = hostGrid_->levelIndexSet(level);
199 const auto& fineLevelIndexSet = hostGrid_->levelIndexSet(level+1);
200
201 leafIndices_[level].clear();
202 leafIndices_[level].resize(levelIndexSet.size(dim), unsetIndex);
203
204 for (const auto& element: elements(levelGridView))
205 {
206 const auto& re = Dune::referenceElement(element);
207 // If the element is leaf, we can directly query the leaf-indexset
208 if (element.isLeaf())
209 {
210 for (auto i : Dune::range(re.size(dim)))
211 leafIndices_[level][levelIndexSet.subIndex(element, i, dim)] = leafIndexSet.subIndex(element, i, dim);
212 continue;
213 }
214 else
215 {
216 // Loop over all direct children
217 for(const auto& childElement : descendantElements(element, level+1))
218 {
219 if (childElement.level() == level)
220 DUNE_THROW(Dune::RangeError, "HierarchicIterator visited element on the same level");
221 // Loop over all vertices of the element
222 const auto& childRe = Dune::referenceElement(childElement);
223 for (auto i : Dune::range(re.size(dim)))
224 {
225 auto levelIndex = levelIndexSet.subIndex(element, i, dim);
226 if (leafIndices_[level][levelIndex] == unsetIndex)
227 {
228 // Find child vertex with the same id
229 auto id = idSet.subId(element, i, dim);
230 for (auto j : Dune::range(childRe.size(dim)))
231 {
232 if (idSet.subId(element, j, dim) == id)
233 {
234 if (childElement.isLeaf())
235 leafIndices_[level][levelIndex] = leafIndexSet.subIndex(childElement, j, dim);
236 else
237 {
238 auto fineLevelIndex = levelIndexSet.subIndex(childElement, j, dim);
239 leafIndices_[level][levelIndex] = leafIndices_[level+1][fineLevelIndex];
240 }
241 continue;
242 }
243 }
244 }
245 }
246 }
247 }
248 }
249 }
250 }
251
256};
257
258
259
260template<class HostGrid, class F>
261DeformationFunction(const HostGrid& hostGrid, const F& f)
263
264
265
266} // end namespace Dune::Fufem::Experimental
267
268
269
270#endif
unspecified value type referenceElement(T &&... t)
int id()
int size() const
static constexpr IntegralRange< T > range(T from, T to) noexcept
size_type dim() const
#define DUNE_THROW(E,...)
Grid< dim, dimworld, ct, GridFamily >::LeafGridView leafGridView(const Grid< dim, dimworld, ct, GridFamily > &grid)
Grid< dim, dimworld, ct, GridFamily >::LevelGridView levelGridView(const Grid< dim, dimworld, ct, GridFamily > &grid, int level)
A discrete coordinate function for Dune::GeometryGrid.
Definition deformationfunction.hh:52
virtual void evaluate(const typename HostGrid::template Codim< dim >::Entity &entity, unsigned int corner, Range &y) const
Evaluate function at a corner of a host element.
Definition deformationfunction.hh:127
const Basis & basis() const
Access basis for deformation function.
Definition deformationfunction.hh:143
HG HostGrid
Definition deformationfunction.hh:63
virtual void evaluate(const typename HostGrid::template Codim< 0 >::Entity &entity, unsigned int corner, Range &y) const
Evaluate function at a host vertex (corner param is redundant but prescribed by the interface....
Definition deformationfunction.hh:121
void interpolate(const F &f)
Reset the deformation to the interpolate of the given function.
Definition deformationfunction.hh:179
Basis basis_
Definition deformationfunction.hh:254
std::vector< std::vector< std::size_t > > leafIndices_
Definition deformationfunction.hh:252
const HostGrid * hostGrid_
Definition deformationfunction.hh:253
const CoefficientVector & coefficients() const
Const access to coefficient vector.
Definition deformationfunction.hh:165
CoefficientVector & coefficients()
Mutable access to coefficient vector.
Definition deformationfunction.hh:154
CoefficientVector coefficients_
Definition deformationfunction.hh:255
void setupLeafIndices()
Definition deformationfunction.hh:186
DeformationFunction(const HostGrid &hostGrid, Dune::index_constant< deformedDim > deformedDimConstant={})
Create a deformation function on given HostGrid.
Definition deformationfunction.hh:97
void adapt()
Adapt to changes in the host grid.
Definition deformationfunction.hh:133
DeformationFunction(const HostGrid &hostGrid, const F &f, Dune::index_constant< deformedDim > deformedDimConstant={})
Create a deformation function on given HostGrid from given function.
Definition deformationfunction.hh:111
ct ctype
Definition deformationfunction.hh:65
virtual ~DeformationFunction()
Definition deformationfunction.hh:117
typename HostGrid::template Codim< dim >::Geometry::GlobalCoordinate Domain
Definition deformationfunction.hh:64
T clear(T... args)
T max(T... args)
Definition deformationfunction.hh:33
void interpolate(const B &basis, C &&coeff, const F &f, const BV &bv, const NTRE &nodeToRangeEntry)
T resize(T... args)