Dune-Fufem 2.11-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
279template <class GridView, class CoefficientVectorType>
280class
282 public Dune::DiscreteCoordFunction<typename GridView::ctype, GridView::dimension,
284{
285 enum {dim = GridView::dimension};
286
287 typedef typename GridView::ctype ctype;
290public:
292
293 [[deprecated("This class is deprecated and will be removed after 2.11. Use Dune::Fufen::Experimental::DeformationFunction instead.")]]
294 DeformationFunction(const GridView& gridView)
295 {
296 gridView_ = std::unique_ptr<GridView>(new GridView(gridView));
297 deformation_.resize(gridView_->size(dim));
298 deformation_ = 0;
299 }
300
301
302 [[deprecated("This class is deprecated and will be removed after 2.11. Use Dune::Fufen::Experimental::DeformationFunction instead.")]]
303 DeformationFunction(const GridView& gridView,
304 const CoefficientVectorType& deformation)
305 : deformation_(deformation)
306 {
307 gridView_ = std::unique_ptr<GridView>(new GridView(gridView));
308
309 if(gridView_->size(dim) != deformation_.size())
310 DUNE_THROW(Dune::Exception,"The deformation coefficient vector doesn't match the gridview!");
311 }
312
314
315 virtual void setGridView(const GridView& gridView) {
316 gridView_ = std::unique_ptr<GridView>(new GridView(gridView));
317 }
318
320 void setDeformation(const CoefficientVectorType& deformation)
321 {
322 if (deformation_.size() != deformation.size())
323 std::cout<<"Warning chanign deformation size "<<deformation_.size()<<" to "<<deformation.size()<<std::endl;
324 deformation_ = deformation;
325 }
326
328 virtual void evaluate ( const typename GridView::template Codim<dim>::Entity& hostVertex, unsigned int corner,
330 {
331 const typename GridView::IndexSet& indexSet = gridView_->indexSet();
332 int idx = indexSet.index(hostVertex);
333
334 y = hostVertex.geometry().corner(0) + deformation_[idx];
335 }
336
338 virtual void evaluate (const typename GridView::template Codim<0>::Entity& hostEntity, unsigned int corner,
339 typename Base::RangeVector& y ) const
340 {
341 const typename GridView::IndexSet& indexSet = gridView_->indexSet();
342 int idx = indexSet.subIndex(hostEntity, corner,dim);
343 y = hostEntity.geometry().corner(corner) + deformation_[idx];
344 }
345
347 void adapt() {
348 if ((int) deformation_.size() != gridView_->size(dim)) {
349 std::cout<<"Warning removing all data from DeformationFunction! \n";
350 deformation_.resize(gridView_->size(dim));
351 deformation_ = 0;
352 }
353 }
354
355 const CoefficientVectorType& getDeformation() {return deformation_;}
356protected:
359
361 CoefficientVectorType deformation_;
362};
363
364
372template <class GridView, class CoefficientVectorType>
373class
374[[deprecated("This class is deprecated and will be removed after 2.11. Use Dune::Fufen::Experimental::DeformationFunction instead.")]]
377{
378 enum {dim = GridView::dimension};
379
380 typedef typename GridView::ctype ctype;
381 typedef typename CoefficientVectorType::field_type field_type;
383public:
384
385 DeformationHierarchyFunction(const GridView& gridView) :
386 Base(gridView)
387 {
388 setupIndexMapping();
389 }
390
391
392 DeformationHierarchyFunction(const GridView& gridView,
393 const CoefficientVectorType& deformation) :
394 Base(gridView, deformation)
395 {
396 setupIndexMapping();
397 }
398
399 virtual void setGridView(const GridView& gridView) {
400 Base::setGridView(gridView);
401 setupIndexMapping();
402 }
403 // TODO Implement evaluate method for corners...
404
406 void evaluate (const typename GridView::template Codim<0>::Entity& hostEntity, unsigned int corner,
407 typename Base::RangeVector& y ) const
408 {
409 if (hostEntity.isLeaf()) {
410 Base::evaluate(hostEntity,corner,y);
411 return;
412 }
413 const auto& indexSet = this->gridView_->grid().levelIndexSet(hostEntity.level());
414
415 int idx = indexSet.subIndex(hostEntity, corner,dim);
416 y = hostEntity.geometry().corner(corner) + this->deformation_[fineIndex_[hostEntity.level()][idx]];
417 }
418
419private:
421 std::vector<std::vector<int> > fineIndex_;
422
424 void setupIndexMapping() {
425
426 int maxLevel = this->gridView_->grid().maxLevel();
427
428 // all elements are leaf
429 if (maxLevel==0)
430 return;
431
432 fineIndex_.resize(maxLevel+1);
433
434 const typename GridView::IndexSet& leafIndex = this->gridView_->indexSet();
435
436 // A factory for the P1 shape functions
437 typedef typename Dune::LagrangeLocalFiniteElementCache<ctype, field_type, dim, 1> P1FECache;
438 typedef typename P1FECache::FiniteElementType FEType;
439 P1FECache p1FECache;
440
441 const typename GridView::Grid& grid = this->gridView_->grid();
442 typedef typename GridView::Grid::LevelGridView::template Codim<0>::Iterator LevelElementIterator;
443 typedef typename LevelElementIterator::Entity EntityType;
444 typedef typename EntityType::HierarchicIterator HierarchicIterator;
445
446 for (int i=maxLevel; i>=0; i--) {
447 fineIndex_[i].resize(grid.size(i,dim),-1);
448
449 const auto& levelIndex = grid.levelIndexSet(i);
450 int fineLevel = (i==maxLevel) ? i : (i+1);
451 const auto& fineIndex = grid.levelIndexSet(fineLevel);
452
453 const auto& lv = grid.levelGridView(i);
454 for (const auto& e: elements(lv)) {
455
456 // all vertices of leaf elements are leaf
457 if (e.isLeaf()) {
458
459 auto ref
460 = Dune::ReferenceElements<ctype, dim>::general(e.type());
461 for (int j=0; j<ref.size(dim); j++)
462 fineIndex_[i][levelIndex.subIndex(e,j,dim)] = leafIndex.subIndex(e,j,dim);
463 continue;
464 }
465
466 // Get local finite element
467 const FEType& coarseBaseSet = p1FECache.get(e.type());
468
469 const size_t numCoarseBaseFct = coarseBaseSet.localBasis().size();
470
471 // preallocate vector for function evaluations
472 std::vector<Dune::FieldVector<field_type,1> > values(numCoarseBaseFct);
473
474 HierarchicIterator fIt = e.hbegin(i+1);
475 HierarchicIterator fEndIt = e.hend(i+1);
476
477 for (; fIt != fEndIt; ++fIt) {
478
479 if (fIt->level()==i)
480 continue;
481
482 auto fineRefElement
483 = Dune::ReferenceElements<ctype, dim>::general(fIt->type());
484
485 const auto& fGeometryInFather = fIt->geometryInFather();
486
487 // Get local finite element
488 const FEType& fineBaseSet = p1FECache.get(fIt->type());
489
490 const size_t numFineBaseFct = fineBaseSet.localBasis().size();
491
492 for (size_t j=0; j<numFineBaseFct; j++)
493 {
494 //compute position of child element node in father element
495 const Dune::LocalKey& jLocalKey = fineBaseSet.localCoefficients().localKey(j);
496
497 int globalLeaf = fineIndex_[fineLevel][fineIndex.subIndex(*fIt, jLocalKey.subEntity(), dim)];
498
499 Dune::FieldVector<ctype, dim> fineBasePosition = fineRefElement.position(jLocalKey.subEntity(), dim);
500 Dune::FieldVector<ctype, dim> local = fGeometryInFather.global(fineBasePosition);
501
502 // Evaluate coarse grid base functions
503 coarseBaseSet.localBasis().evaluateFunction(local, values);
504
505 for (size_t k=0; k<numCoarseBaseFct; k++)
506 {
507 if (values[k] > 0.9999)
508 {
509 const Dune::LocalKey& coarseKey = coarseBaseSet.localCoefficients().localKey(k);
510 int globalCoarse = levelIndex.subIndex(e, coarseKey.subEntity(), dim);
511 fineIndex_[i][globalCoarse] = globalLeaf;
512 }
513 }
514 }
515
516 }
517 }
518 }
519 }
520};
521
522
523
524
525#endif
int id()
int maxLevel() const
unspecified value type referenceElement(T &&... t)
void interpolate(const B &basis, C &&coeff, const F &f, const BV &bv, const NTRE &nodeToRangeEntry)
int size() const
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
size_type dim() const
#define DUNE_THROW(E,...)
LocalIndex & local()
Definition deformationfunction.hh:33
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)
constexpr unsigned int subEntity() const noexcept
IndexType subIndex(const typename Traits::template Codim< cc >::Entity &e, int i, unsigned int codim) const
IndexType index(const typename Traits::template Codim< cc >::Entity &e) const
const LevelIndexSet & levelIndexSet(int level) const
int size(int level, int codim) const
LevelGridView levelGridView(int level) const
Base::RangeVector RangeVector
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
Function that computes the deformed position from a given host gridview. This can be used inside of G...
Definition deformationfunction.hh:284
virtual void setGridView(const GridView &gridView)
Definition deformationfunction.hh:315
void adapt()
Adapt to changes in the host grid.
Definition deformationfunction.hh:347
CoefficientVectorType deformation_
The coefficient vector of the displacements of the vertices of the gridview.
Definition deformationfunction.hh:361
Base::RangeVector RangeVector
Definition deformationfunction.hh:291
const CoefficientVectorType & getDeformation()
Definition deformationfunction.hh:355
virtual void evaluate(const typename GridView::template Codim< dim >::Entity &hostVertex, unsigned int corner, Dune::FieldVector< ctype, dim > &y) const
Evaluate function at a host vertex (corner param is redundant but prescribed by the interface....
Definition deformationfunction.hh:328
std::unique_ptr< GridView > gridView_
The gridview of the undeformed grid.
Definition deformationfunction.hh:358
DeformationFunction(const GridView &gridView)
Definition deformationfunction.hh:294
void setDeformation(const CoefficientVectorType &deformation)
Change the deformation vector.
Definition deformationfunction.hh:320
DeformationFunction(const GridView &gridView, const CoefficientVectorType &deformation)
Definition deformationfunction.hh:303
virtual void evaluate(const typename GridView::template Codim< 0 >::Entity &hostEntity, unsigned int corner, typename Base::RangeVector &y) const
Evaluate function at a corner of a host entity.
Definition deformationfunction.hh:338
virtual ~DeformationFunction()
Definition deformationfunction.hh:313
Function that computes the deformed position from a given host gridview. This can be used inside of G...
Definition deformationfunction.hh:377
DeformationHierarchyFunction(const GridView &gridView, const CoefficientVectorType &deformation)
Definition deformationfunction.hh:392
DeformationHierarchyFunction(const GridView &gridView)
Definition deformationfunction.hh:385
void evaluate(const typename GridView::template Codim< 0 >::Entity &hostEntity, unsigned int corner, typename Base::RangeVector &y) const
Evaluate function at a corner of a host entity.
Definition deformationfunction.hh:406
virtual void setGridView(const GridView &gridView)
Definition deformationfunction.hh:399
T clear(T... args)
T endl(T... args)
T max(T... args)
T resize(T... args)