Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
prolongboundarypatch.hh
Go to the documentation of this file.
1// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set ts=8 sw=4 et sts=4:
3
4// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUFEM_PROLONG_BOUNDARY_PATCH_HH
8#define DUNE_FUFEM_PROLONG_BOUNDARY_PATCH_HH
9
14#include <vector>
15
16#include <dune/grid/common/grid.hh>
20
21#if HAVE_DUNE_UGGRID
23#include <dune/grid/uggrid.hh>
24#endif
25
26template <class GridType>
28public:
29
31 {
32 using namespace Dune;
33
34 const GridType& grid = patches[0].gridView().grid();
35 if (!&grid)
36 DUNE_THROW(Exception, "Coarsest boundary patch has not been set up correctly!");
37
38 assert(patches.size()>=grid.maxLevel()+1);
39
40 // Set array sizes correctly
41 for (int i=1; i<=grid.maxLevel(); i++)
42 patches[i].setup(grid.levelGridView(i));
43
44 // Loop over the boundary on level 0
45 typename GridType::LevelGridView levelView = grid.levelGridView(0);
46 for (const auto& e : elements(levelView)) {
47
48 // Loop over all neighbors
49 for (const auto& i : intersections(levelView,e)) {
50
51 // if the element is a boundary element
52 if (patches[0].contains(i)) {
53
54 // ///////////////////////////////////////////////////////////////
55 // This implementation doesn't use the UGGrid-specific method
56 // getChildrenOfSubface. Instead, it compares normals. Therefore
57 // it cannot be used with parametrized boundaries.
58 // //////////////////////////////////////////////////////////////
59 const int dim = GridType::dimension;
60 const int dimworld = GridType::dimensionworld;
61 typedef typename GridType::ctype ctype;
62 FieldVector<ctype,dim-1> dummy;
63 FieldVector<ctype,dimworld> level0Normal = i.unitOuterNormal(dummy);
64
65 // Find all boundary segments of the descendants of this element
66 for (const auto& h : descendantElements(e,grid.maxLevel())) {
67
68 if (h.level() == e.level())
69 continue;
70
71 typename GridType::LevelGridView hlevelView = grid.levelGridView(h.level());
72 for (const auto& hi : intersections(hlevelView,h)) {
73
74 if (hi.boundary()) {
75
76 // Test whether this boundary segment is contained in the
77 // level 0 boundary segment by comparing the normals.
79 FieldVector<ctype,dim-1> dummy;
80 if (0.95 < level0Normal*hi.unitOuterNormal(dummy))
81 patches[h.level()].addFace(hi);
82
83
84 }
85
86 }
87
88 }
89
90 }
91
92 }
93
94 }
95
96 }
97
100 {
101 const GridType& grid = coarsePatch.gridView().grid();
102
103 if (!&grid)
104 DUNE_THROW(Dune::Exception, "Coarsest boundary patch has not been set up correctly!");
105
106 // Set array sizes correctly
107 finePatch.setup(grid.leafGridView());
108
109 for (const auto& pIt : coarsePatch) {
110
111 const auto& inside = pIt.inside();
112
113 if (inside.isLeaf())
114 finePatch.addFace(inside, pIt.indexInInside());
115 else
116 {
117 Face<GridType> face(grid, inside, pIt.indexInInside());
118
119 typename Face<GridType>::HierarchicIterator it = face.hbegin(grid.maxLevel());
120 typename Face<GridType>::HierarchicIterator end = face.hend(grid.maxLevel());
121
122 for(; it!=end; ++it)
123 {
124 if (it->element().isLeaf())
125 finePatch.addFace(it->element(), it->index());
126 }
127 }
128 }
129 }
130
131};
132
133
134#if HAVE_DUNE_UGGRID
135template <int dim>
136class PatchProlongator<Dune::UGGrid<dim> > {
137public:
138
139 typedef typename Dune::UGGrid<dim> GridType;
140
142 {
143 using namespace Dune;
144
145 typedef typename GridType::template Codim<0>::Entity EntityType;
146
147 const GridType& grid = patches[0].gridView().grid();
148 if (!&grid)
149 DUNE_THROW(Exception, "Coarsest boundary patch has not been set up correctly!");
150
151 assert(patches.size()>=grid.maxLevel()+1);
152
153 // Set array sizes correctly
154 for (int i=1; i<=grid.maxLevel(); i++)
155 patches[i].setup(grid.levelGridView(i));
156
157 // Loop over the boundary on level 0
158 typename GridType::LevelGridView levelView = grid.levelGridView(0);
159 for (const auto& e : elements(levelView)) {
160
161 // Loop over all neighbors
162 for (const auto& i : intersections(levelView,e)) {
163
164 // if the element is a boundary element
165 if (patches[0].contains(i)) {
166
167 // /////////////////////////////////////////////////////////////////
168 // This version actually only works for UGGrids, but it works
169 // purely topologically. For the other grids we need to compare
170 // surface normals.
171 // /////////////////////////////////////////////////////////////////
172 std::vector<EntityType> childElements(0,*levelView.template begin<0>());
173 std::vector<unsigned char> childElementSides;
174 grid.getChildrenOfSubface(e, i.indexInInside(), grid.maxLevel(),
175 childElements, childElementSides);
176
177 for (size_t i=0; i<childElements.size(); i++) {
178 const int& level = childElements[i].level();
179 patches[level].addFace(childElements[i], childElementSides[i]);
180 }
181
182 }
183
184 }
185
186 }
187
188 }
189
190
191
192#if ENABLE_GENERIC_PATCHPROLONGATOR_FOR_UG
193 static void prolong(const BoundaryPatchBase<typename GridType::LevelGridView>& coarsePatch,
194 BoundaryPatchBase<typename GridType::LeafGridView>& finePatch)
195 {
196
197 const GridType& grid = coarsePatch.gridView().grid();
198
199 if (!&grid)
200 DUNE_THROW(Dune::Exception, "Coarsest boundary patch has not been set up correctly!");
201
202 // Set array sizes correctly
203 finePatch.setup(grid.leafGridView());
204
205 for (const auto& pIt : coarsePatch) {
206
207 const auto& inside = pIt.inside();
208 if (inside.isLeaf())
209 finePatch.addFace(inside, pIt.indexInInside());
210 else
211 {
212 Face<GridType> face(grid, inside, pIt.indexInInside());
213
214 typename Face<GridType>::HierarchicIterator it = face.hbegin(grid.maxLevel());
215 typename Face<GridType>::HierarchicIterator end = face.hend(grid.maxLevel());
216
217 for(; it!=end; ++it)
218 {
219 if (it->element().isLeaf())
220 finePatch.addFace(it->element(), it->index());
221 }
222 }
223 }
224 }
225
226
227
228 static void prolong_old(const BoundaryPatchBase<typename GridType::LevelGridView>& coarsePatch,
229 BoundaryPatchBase<typename GridType::LeafGridView>& finePatch)
230#else
231 static void prolong(const BoundaryPatch<typename GridType::LevelGridView>& coarsePatch,
233#endif
234 {
235 typedef typename GridType::template Codim<0>::Entity EntityType;
236
237 const GridType& grid = coarsePatch.gridView().grid();
238
239 if (!&grid)
240 DUNE_THROW(Dune::Exception, "Coarsest boundary patch has not been set up correctly!");
241
242 // Set array sizes correctly
243 finePatch.setup(grid.leafGridView());
244
245 // Loop over the boundary on level 0
246 typename GridType::LevelGridView levelView = grid.levelGridView(0);
247 for (const auto& e : elements(levelView)) {
248
249 // Loop over all neighbors
250 for (const auto& i : intersections(levelView,e)) {
251
252 // if the element is a boundary element
253 if (coarsePatch.contains(i)) {
254
255 // /////////////////////////////////////////////////////////////////
256 // This version actually only works for UGGrids, but it works
257 // purely topologically. For the other grids we need to compare
258 // surface normals.
259 // /////////////////////////////////////////////////////////////////
260 if (e.isLeaf())
261 finePatch.addFace(e, i.indexInInside());
262
263 std::vector<EntityType> childElements(0, *levelView.template begin<0>());
264 std::vector<unsigned char> childElementSides;
265 grid.getChildrenOfSubface(e, i.indexInInside(), grid.maxLevel(),
266 childElements, childElementSides);
267
268 for (size_t i=0; i<childElements.size(); i++) {
269
270 if (childElements[i].isLeaf())
271 finePatch.addFace(childElements[i], childElementSides[i]);
272
273 }
274
275 }
276
277 }
278
279 }
280
281 }
282
283};
284#endif
285
286#endif
iterator end()
static bool contains(const Type &attribute)
size_type dim() const
#define DUNE_THROW(E,...)
const Grid & grid() const
IteratorRange<... > intersections(const GV &gv, const Entity &e)
IteratorRange<... > elements(const GV &gv)
LeafGridView leafGridView() const
int maxLevel() const
LevelGridView levelGridView(int level) const
Encapsulate a part of a grid boundary.
Definition boundarypatch.hh:218
void addFace(const IntersectionIterator &nIt)
Add a boundary face to the patch.
Definition boundarypatch.hh:326
bool contains(const IntersectionIterator &nIt) const
Return true if the BoundaryPatch contains a certain boundary face.
Definition boundarypatch.hh:360
void setup(const GridView &gridView, bool insertAllBoundaryFaces=false)
Setup for a given grid view.
Definition boundarypatch.hh:282
const GridView & gridView() const
Return reference to the carrier grid view.
Definition domains/boundarypatch.hh:197
Class representing a face.
Definition facehierarchy.hh:120
HierarchicIterator hend(int maxLevel) const
Return end of HierarchicIterator to subfaces.
Definition facehierarchy.hh:206
HierarchicIterator hbegin(int maxLevel) const
Return HierarchicIterator to subfaces.
Definition facehierarchy.hh:197
A hierarchical iterator for faces.
Definition facehierarchy.hh:338
const Element element() const
Get element of current face.
Definition facehierarchy.hh:389
int index() const
Get index of current face within element.
Definition facehierarchy.hh:396
Definition prolongboundarypatch.hh:27
static void prolong(const BoundaryPatch< typename GridType::LevelGridView > &coarsePatch, BoundaryPatch< typename GridType::LeafGridView > &finePatch)
Definition prolongboundarypatch.hh:98
static void prolong(std::vector< BoundaryPatch< typename GridType::LevelGridView > > &patches)
Definition prolongboundarypatch.hh:30