4#ifndef DUNE_PDELAB_CONSTRAINTS_HANGINGNODEMANAGER_HH
5#define DUNE_PDELAB_CONSTRAINTS_HANGINGNODEMANAGER_HH
7#include<dune/grid/common/grid.hh>
11#include"../common/geometrywrapper.hh"
16 template<
class Gr
id,
class BoundaryFunction>
21 enum{ verbosity = 2 };
23 enum{ verbosity = 0 };
25 typedef typename Grid::LeafIndexSet::IndexType IndexType;
32 unsigned short minimum_level;
35 unsigned short maximum_level;
38 unsigned short minimum_touching_level;
42 void addLevel(
unsigned short level)
44 minimum_level =
std::min(minimum_level,level);
45 maximum_level =
std::max(maximum_level,level);
48 void addTouchingLevel(
unsigned short level)
50 minimum_touching_level =
std::min(minimum_touching_level,level);
74 inline bool isHanging()
const {
return is_hanging; }
83 enum {
dim = GridView::dimension};
88 typedef typename GridView::Grid::ctype
ctype;
103 const typename GridView::IndexSet& indexSet =
grid.
leafGridView().indexSet();
110 for(
const auto& cell : elements(gv)) {
115 const unsigned short level = cell.level();
118 const IndexType v_size = reference_element.size(
dim);
123 for(IndexType i=0; i<v_size; ++i){
124 const IndexType v_globalindex = indexSet.
subIndex(cell,i,
dim);
125 NodeInfo& ni = node_info[v_globalindex];
133 std::cout <<
" v_globalindex = " << v_globalindex;
134 std::cout <<
" maximum_level = " << ni.maximum_level;
135 std::cout <<
" minimum_level = " << ni.minimum_level;
147 unsigned int intersection_index = 0;
148 for(
const auto& intersection : intersections(gv,cell)) {
149 ++intersection_index;
153 const int eLocalIndex = intersection.indexInInside();
154 const int e_level = intersection.inside().level();
157 const int e_v_size = reference_element.size(eLocalIndex,1,
dim);
159 if(intersection.boundary()) {
162 for(
int i=0; i<e_v_size;++i){
163 const int e_v_index = reference_element.subEntity(eLocalIndex,1,i,
dim);
164 const IndexType v_globalindex = indexSet.
subIndex(cell,e_v_index,
dim);
166 const FacePoint facelocal_position = reference_face_element.position(i,
dim-1);
178 NodeInfo& ni = node_info[v_globalindex];
180 ni.addTouchingLevel(e_level);
187 const int f_level = intersection.outside().level();
190 if(intersection.conforming())
194 assert(e_level != f_level);
198 if(e_level < f_level)
202 for(
int i=0; i<e_v_size;++i){
203 const int e_v_index = reference_element.subEntity(eLocalIndex,1,i,
dim);
204 const IndexType v_globalindex = indexSet.
subIndex(cell,e_v_index,
dim);
206 node_info[v_globalindex].addTouchingLevel(f_level);
222 const typename GridView::IndexSet& indexSet =
grid.
leafGridView().indexSet();
228 const IndexType v_size = reference_element.size(
dim);
231 is_hanging.
resize(v_size);
236 for(IndexType i=0; i<v_size; ++i){
237 const IndexType v_globalindex = indexSet.
subIndex(e,i,
dim);
242 const NodeInfo & v_info = node_info[v_globalindex];
243 if(v_info.minimum_touching_level < v_info.minimum_level){
244 is_hanging[i].is_hanging =
true;
245 is_hanging[i].is_boundary = v_info.is_boundary;
256 is_hanging[i].is_hanging =
false;
257 is_hanging[i].is_boundary = v_info.is_boundary;
269 const typename GridView::IndexSet& indexSet =
grid.
leafGridView().indexSet();
271 size_t iterations(0);
277 size_t refinements(0);
283 for(
const auto& cell : elements(gv)) {
290 const unsigned short level = cell.level();
295 const IndexType v_size = reference_element.size(
dim);
300 for(IndexType i=0; i<v_size; ++i){
302 const IndexType v_globalindex = indexSet.
subIndex(cell,i,
dim);
304 const NodeInfo & v_info = node_info[v_globalindex];
308 const unsigned short level_diff = v_info.maximum_level - level;
319 std::cout <<
" v_globalindex = " << v_globalindex;
322 <<
" to isolate hanging nodes. Level diff = "
323 << v_info.maximum_level <<
" - " << level<<
std::endl;
330 if( cell.geometry().type().isSimplex() ){
341 bool bJumpOut =
false;
344 for(
const auto& intersection : intersections(gv,cell)) {
347 if(!intersection.boundary()) {
349 const int e_level = intersection.inside().level();
350 const int f_level = intersection.outside().level();
352 if( f_level > e_level ){
358 const int eLocalIndex = intersection.indexInInside();
365 int nEdgeCenters = 0;
387 for(
int counter=0; counter<nEdgeCenters; ++counter){
389 int cornerIndex1 = counter %
dim;
390 int cornerIndex2 = (counter+1) %
dim;
392 const int e_v_index_1 =
393 reference_element.subEntity(eLocalIndex,1,cornerIndex1,
dim);
395 const int e_v_index_2 =
396 reference_element.subEntity(eLocalIndex,1,cornerIndex2,
dim);
398 auto vertex1 = cell.template subEntity<dim>(e_v_index_1);
400 auto vertex2 = cell.template subEntity<dim>(e_v_index_2);
402 edgecenter[counter] += vertex1.geometry().center();
403 edgecenter[counter] += vertex2.geometry().center();
404 edgecenter[counter] /=
ctype( 2 );
411 auto nb_reference_element =
referenceElement(intersection.outside().geometry());
414 const IndexType nb_v_size = nb_reference_element.size(
dim);
417 for(IndexType i=0; i<nb_v_size; ++i){
419 auto nb_vertex = intersection.outside().template subEntity<dim>(i);
421 bool doExtraCheck =
false;
425 center_diff -= nb_vertex.geometry().center();
439 const IndexType nb_v_globalindex = indexSet.
index(nb_vertex);
441 const NodeInfo & nb_v_info = node_info[nb_v_globalindex];
443 const unsigned short level_diff = nb_v_info.maximum_level - level;
458 <<
" to isolate hanging nodes. Level diff = "
459 << nb_v_info.maximum_level <<
" - " << level<<
std::endl;
466 if( bJumpOut )
break;
468 if( bJumpOut )
break;
474 if( bJumpOut )
break;
495 std::cout <<
"In iteration " << iterations <<
" there were "
496 << refinements <<
" grid cells to be refined additionally to isolate hanging nodes." <<
std::endl;
unspecified value type referenceElement(T &&... t)
const GlobalIndex & global() const
For backward compatibility – Do not use this!
Grid< dim, dimworld, ct, GridFamily >::LeafGridView leafGridView(const Grid< dim, dimworld, ct, GridFamily > &grid)
MCMGLayout mcmgElementLayout()
constexpr FieldTraits< value_type >::real_type two_norm2() const
auto size(GeometryType type) const
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
LeafGridView leafGridView() const
bool mark(int refCount, const typename Codim< 0 >::Entity &e)
Index index(const EntityType &e) const
void update(const GV &gridView)
Wrap intersection.
Definition geometrywrapper.hh:57
Definition hangingnodemanager.hh:18
const BoundaryFunction & boundaryFunction
Definition hangingnodemanager.hh:95
const std::vector< NodeState > hangingNodes(const Cell &e) const
Definition hangingnodemanager.hh:220
Dune::MultipleCodimMultipleGeomTypeMapper< GridView > CellMapper
Definition hangingnodemanager.hh:92
Dune::FieldVector< ctype, dim-1 > FacePoint
Definition hangingnodemanager.hh:90
Grid::LeafGridView GridView
Definition hangingnodemanager.hh:82
void adaptToIsolatedHangingNodes()
Definition hangingnodemanager.hh:264
GridView::IntersectionIterator IntersectionIterator
Definition hangingnodemanager.hh:87
GridView::template Codim< 0 >::Entity Cell
Definition hangingnodemanager.hh:84
CellMapper cell_mapper
Definition hangingnodemanager.hh:96
GridView::template Codim< 0 >::Iterator Iterator
Definition hangingnodemanager.hh:86
Dune::FieldVector< ctype, dim > Point
Definition hangingnodemanager.hh:89
HangingNodeManager(Grid &_grid, const BoundaryFunction &_boundaryFunction)
Definition hangingnodemanager.hh:214
Grid & grid
Definition hangingnodemanager.hh:94
@ dim
Definition hangingnodemanager.hh:83
GridView::Grid::ctype ctype
Definition hangingnodemanager.hh:88
void analyzeView()
Definition hangingnodemanager.hh:100
Definition hangingnodemanager.hh:65
NodeState()
Definition hangingnodemanager.hh:76
bool isHanging() const
Definition hangingnodemanager.hh:74
bool isBoundary() const
Definition hangingnodemanager.hh:73