KASKADE 7 development version
mllgeometry.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2002-2020 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef MLLGEOMETRY_HH
14#define MLLGEOMETRY_HH
15
22#include <limits>
23#include <stack>
24
25#include "dune/common/fmatrix.hh"
26#include <dune/geometry/referenceelements.hh>
27
28#include "fem/fixdune.hh"
29
30namespace Kaskade
31{
49 template <class Grid>
51 {
52 typedef typename Grid::GlobalIdSet::IdType Id;
53 typedef typename Grid::template Codim<0>::Entity Cell;
54
55 protected:
57
58 private:
59
60 // Changed in DUNE 2.1
61 // typename Grid::template Codim<0>::GlobalIdSet const& idSet;
62 typename Grid::GlobalIdSet const& idSet;
63 int spanwidth;
64 bool geometricallyNested, transformViaGlobal;
65
66 public:
67
71 };
72
74 typedef typename Grid::template Codim<0>::Entity Entity;
75
76
77 private:
78
79 Direction dir;
80
81 typedef typename Grid::ctype ctype;
82 static int const dim = Grid::dimension;
83 static int const dimw = Grid::dimensionworld;
84
85 public:
86
110 MultiLevelLocalGeometry(Grid const &grid,
111 Cell const& child_,
112 Cell const& ancestor_,
114 bool geometricallyNested_= (dim==dimw),
115 ctype tol_=-100):
116 child(child_),
117 ancestor(ancestor_),
118 idSet(grid.globalIdSet()),
119 geometricallyNested(geometricallyNested_),
120 dir(direction_),
121 tol(tol_<=-100? 100*std::numeric_limits<ctype>::epsilon(): tol_)
122 {
123 Cell ci(child);
124 spanwidth = 0;
125 while (idSet.id(ci) != idSet.id(ancestor))
126 {
127 ci = ci.father();
128 spanwidth++;
129 }
130 transformViaGlobal = geometricallyNested && (spanwidth >= 3);
131 }
132
134 Entity const& localEntity() const { return dir==ChildIsGlobal? ancestor: *child; }
135
136
138 void global(std::vector<Dune::FieldVector<ctype,dim> > & x,
139 std::vector<int> &componentsInside) const
140 {
141 if (dir==ChildIsGlobal) {
142 if(transformViaGlobal) childToFatherViaGlobal(x);
143 else childToFather(x);
144 }
145 else {
146 if(transformViaGlobal) fatherToChildViaGlobal(x,componentsInside);
147 else fatherToChild(x,componentsInside);
148 }
149 }
150
170 std::vector<int>& componentsInside) const
171 {
172 if (dir==FatherIsGlobal) {
173 if(transformViaGlobal) fatherToChildViaGlobal(x,componentsInside);
174 else fatherToChild(x,componentsInside);
175 }
176 else {
177 if(transformViaGlobal) childToFatherViaGlobal(x);
178 else childToFather(x);
179 }
180 }
181
189 {
190 if (transformViaGlobal)
191 if (dir==FatherIsGlobal) {
192 Dune::FieldVector<ctype,dim> xGlobal = ancestor.geometry().local(child.geometry().global(xLocal));
193 return ancestor.geometry().jacobianTransposed(xGlobal) * child.geometry().jacobianInverseTransposed(xLocal);
194 } else {
195 Dune::FieldVector<ctype,dim> xGlobal = child.geometry().local(ancestor.geometry().global(xLocal));
196 Dune::FieldMatrix<ctype,dim,dim> Jct = child.geometry().jacobianInverseTransposed(xGlobal);
197 Jct.invert();
198 return Jct * ancestor.geometry().jacobianInverseTransposed(xLocal);
199 }
200 else {
201 Dune::FieldMatrix<ctype,dim,dim> invt = unitMatrix<ctype,dim>();
203 Cell ci(child);
204 if (dir==FatherIsGlobal) {
205 while(idSet.id(ci) != idSet.id(ancestor)) {
206 invt.leftmultiply(ci.geometryInFather().jacobianInverseTransposed(x));
207 x = ci.geometryInFather().global(x);
208 }
209 } else {
210 std::stack<Cell> stack;
211 while(idSet.id(ci) != idSet.id(ancestor)) {
212 stack.push(ci);
213 ci = ci.father();
214 }
215 while (!stack.empty()) {
216 x = stack.top()->geometryInFather().local(x);
217 // TODO: throw exception if x not in ci
218 invt.rightmultiply(stack.top()->geometryInFather().jacobianInverseTransposed(x));
219 stack.pop();
220 }
221 invt.invert();
222 }
223 return invt;
224 }
225 }
226
227 private:
228
232 void childToFather(std::vector< Dune::FieldVector<ctype,dim> >& x) const
233 {
234 Cell ci(child);
235 while(idSet.id(ci) != idSet.id(ancestor))
236 {
237 auto const& geo = ci.geometryInFather();
238 for(auto& xi: x)
239 xi = geo.global(xi);
240 ci = ci.father();
241 }
242 }
243
244 void childToFatherViaGlobal(std::vector<Dune::FieldVector<ctype,dim>>& x) const
245 {
246 auto const& geoChild = child.geometry();
247 auto const& geoAnces = ancestor.geometry();
248 for(auto& xi: x)
249 xi = geoAnces.local(geoChild.global(xi));
250 }
251
259 void fatherToChild(std::vector<Dune::FieldVector<ctype,dim>>& x,
260 std::vector<int>& componentsInside) const
261 {
262 assert(x.size()==componentsInside.size());
263
264 // We need to go from father cells up to child cells. However, we can only obtain the father
265 // directly. Thus we have to traverse from child to ancestor and store the whole line
266 // of fathers to be traced back in reverse direction.
267 Cell ci(child);
268 std::stack<Cell> ciStack;
269 while(idSet.id(ci) != idSet.id(ancestor))
270 {
271 ciStack.push(ci);
272 ci = ci.father();
273 }
274 // Now ciStack.top()->father is ancestor.
275
276 // Trace back the line from ancestor to child and transform the coordinates given in x
277 // to the childrens' local coordinates on the way.
278 while(!ciStack.empty())
279 {
280 ci = ciStack.top();
281 auto vi = x.begin();
282 auto compi = componentsInside.begin();
283 while (vi!=x.end())
284 {
285 *vi = ci.geometryInFather().local(*vi);
286 if (checkInside(ci.type(),*vi)<tol) // (probably) inside:
287 { // go to next location
288 ++vi;
289 ++compi;
290 }
291 else // (almost sure) outside:
292 { // remove the location
293 vi = x.erase(vi);
294 compi = componentsInside.erase(compi);
295 }
296 }
297 ciStack.pop();
298 }
299 }
300
301 void fatherToChildViaGlobal(std::vector<Dune::FieldVector<ctype,dim>>& x,
302 std::vector<int>& componentsInside) const
303 {
304 for(auto& xi: x)
305 xi = child.geometry().local(ancestor.geometry().global(xi));
306
307 auto vi = x.begin();
308 auto compi = componentsInside.begin();
309 while (vi!=x.end()) {
310 if (checkInside(child.type(),*vi)<tol) { // (probably) inside
311 ++vi;
312 ++compi;
313 } else { // (almost sure) outside
314 vi = x.erase(vi);
315 compi = componentsInside.erase(compi);
316 }
317 }
318 }
319
320 private:
321 ctype tol;
322 };
323
327 template<class Grid>
329 {
330 typedef typename Grid::template Codim<0>::Entity Cell;
331 typedef typename Grid::ctype ctype;
332 static int const dim = Grid::dimension;
333 public:
334
336 Cell const& child,
337 bool geometricallyNested=false) :
338 MultiLevelLocalGeometry<Grid>(grid,child,coarseGridAncestor(child),MultiLevelLocalGeometry<Grid>::ChildIsGlobal,geometricallyNested)
339 {
340 }
341
344 {
345 std::vector<Dune::FieldVector<ctype,dim> > xi(1,x);
346 std::vector<int> isi(1,0);
348 return xi[0];
349 }
350
351 Cell const& getFather() const { return this->ancestor; }
352
353 private:
354
355 static Cell coarseGridAncestor(Cell const& child)
356 {
358
359 while (ancestor.level()>0)
360 ancestor = ancestor.father();
361 return ancestor;
362 }
363 };
364} // end of namespace Kaskade
365
366#endif
Dune::FieldVector< ctype, dim > global(Dune::FieldVector< ctype, dim >const &x) const
Transformation from local to global.
Definition: mllgeometry.hh:343
LocalGeometryInCoarseGridAncestor(Grid const &grid, Cell const &child, bool geometricallyNested=false)
Definition: mllgeometry.hh:335
Transformation of coordinates between ancestor and child.
Definition: mllgeometry.hh:51
void local(std::vector< Dune::FieldVector< ctype, dim > > &x, std::vector< int > &componentsInside) const
Transformation from global to local.
Definition: mllgeometry.hh:169
Grid::template Codim< 0 >::Entity Entity
The entity type between which this geometry object maps.
Definition: mllgeometry.hh:74
MultiLevelLocalGeometry(Grid const &grid, Cell const &child_, Cell const &ancestor_, MultiLevelLocalGeometry< Grid >::Direction direction_, bool geometricallyNested_=(dim==dimw), ctype tol_=-100)
Constructor.
Definition: mllgeometry.hh:110
void global(std::vector< Dune::FieldVector< ctype, dim > > &x, std::vector< int > &componentsInside) const
Transformation from local to global.
Definition: mllgeometry.hh:138
Entity const & localEntity() const
A reference to the local entity.
Definition: mllgeometry.hh:134
Dune::FieldMatrix< ctype, dim, dim > jacobianInverseTransposed(Dune::FieldVector< ctype, dim > const &xLocal) const
inverse of transposed Jacobian.
Definition: mllgeometry.hh:188
This file contains various utility functions that augment the basic functionality of Dune.
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
Definition: gridBasics.hh:35
LocalCoordinate::field_type checkInside(Dune::GeometryType const &gt, LocalCoordinate const &x)
Checks whether a point is inside or outside the reference element, and how much.
Definition: fixdune.hh:741