Loading [MathJax]/extensions/tex2jax.js

dune-mmesh (1.4)

longestedgerefinement.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
9#ifndef DUNE_MMESH_REMESHING_LONGESTEDGEREFINEMENT_HH
10#define DUNE_MMESH_REMESHING_LONGESTEDGEREFINEMENT_HH
11
12#include <memory>
13#include <dune/common/exceptions.hh>
14#include <dune/grid/common/partitionset.hh>
15
16namespace Dune
17{
18
23template<class Grid>
25{
26 static constexpr int dim = Grid::dimension;
27 static constexpr int edgeCodim = dim - 1;
28 static constexpr int vertexCodim = dim;
29 using ctype = typename Grid::ctype;
30 using Element = typename Grid::Traits::template Codim<0>::Entity;
31 using Vertex = typename Grid::Traits::template Codim<vertexCodim>::Entity;
32
33public:
43 template<class Element>
44 static auto refinement (const Element& element)
45 {
46 ctype longest = -1e100;
47 int longestIdx = -1;
48
49 for( std::size_t i = 0; i < element.subEntities(edgeCodim); ++i )
50 {
51 const ctype edgeLength = element.template subEntity<edgeCodim>(i).geometry().volume();
52 if (edgeLength > longest)
53 {
54 longest = edgeLength;
55 longestIdx = i;
56 }
57 }
58
59 const auto& longestEdge = element.template subEntity<edgeCodim>(longestIdx);
60 return std::make_pair( longestEdge, longestEdge.geometry().center() );
61 }
62
68 template<class Element>
69 static Vertex coarsening (const Element& element)
70 {
71 // for interface any vertex is fine
72 if constexpr ( Grid::dimension != Grid::dimensionworld )
73 {
74 for( std::size_t i = 0; i < element.subEntities(vertexCodim); ++i )
75 {
76 const Vertex& v = element.template subEntity<vertexCodim>(i);
77 if ( isRemoveable( v ) )
78 return v;
79 }
80 return Vertex();
81 }
82
83 // return some non-interface vertex at the shortest edges
84 static constexpr int dimw = Grid::dimensionworld;
85 std::array<std::pair<Vertex, double>, dimw+1> vertices;
86 const auto& refElem = ReferenceElements< double, dimw >::simplex();
87
88 for( std::size_t i = 0; i < element.subEntities(edgeCodim); ++i )
89 {
90 const auto& edge = element.template subEntity<edgeCodim>(i);
91 const ctype edgeLength = edge.geometry().volume();
92
93 for( std::size_t j = 0; j < 2; ++j )
94 {
95 const auto& v = edge.impl().template subEntity<vertexCodim>(j);
96 const int vIdx = refElem.subEntity(i, dimw-1, j, vertexCodim);
97 vertices[vIdx].first = v;
98 vertices[vIdx].second += edgeLength;
99 }
100 }
101
102 std::sort(vertices.begin(), vertices.end(), [&](auto a, auto b){
103 // higher insertionLevel gives higher priority
104 if (a.first.impl().hostEntity()->info().insertionLevel < b.first.impl().hostEntity()->info().insertionLevel)
105 return true;
106
107 // lower edgeLength gives higher priority
108 if (a.second < b.second - 1e-14)
109 return true;
110
111 // give prio to non-constrained points
112 auto constrained = [&](auto v){ return v.impl().isInterface() || atBoundary(v); };
113 if (!constrained(a.first) and constrained(b.first))
114 return true;
115
116 // we consider a and b as equal
117 return false;
118 });
119
120 // return vertex with highest priority
121 return vertices[0].first;
122 }
123
125 static inline bool atBoundary( const Vertex& v )
126 {
127 const auto& hostgrid = v.impl().grid().getHostGrid();
128 for ( const auto& vertex : incidentVertices( v, true ) )
129 if ( hostgrid.is_infinite( vertex.impl().hostEntity() ) )
130 return true;
131 return false;
132 }
133
135 static inline int boundaryFlag( const Vertex& v )
136 {
137 // check if we have to initialize the boundary flag
138 if ( v.impl().boundaryFlag() == -1 )
139 {
140 v.impl().hostEntity()->info().boundaryFlag = 0;
141 if ( atBoundary( v ) )
142 {
143 // check that all incident vertices are in one plane
144 std::vector< Vertex > incidentAtBoundary;
145 for ( const auto& vertex : incidentVertices( v ) )
146 if ( atBoundary( vertex ) )
147 incidentAtBoundary.push_back( vertex );
148
149 // could be that there are more than two incident boundary vertices, e.g. in grid corners
150 if( incidentAtBoundary.size() > 2 )
151 return 0;
152
153 assert( incidentAtBoundary.size() == 2 );
154 auto d1 = v.geometry().center();
155 auto d2 = d1;
156 d1 -= incidentAtBoundary[0].geometry().center();
157 d2 -= incidentAtBoundary[1].geometry().center();
158 d1 /= d1.two_norm();
159 d2 /= d2.two_norm();
160 if ( ( d1 + d2 ).two_norm() > 1e-8 && ( d1 - d2 ).two_norm() > 1e-8 )
161 v.impl().hostEntity()->info().boundaryFlag = 1;
162 }
163 }
164
165 return v.impl().boundaryFlag();
166 }
167
169 template< class Vertex >
170 static inline bool isRemoveable ( const Vertex& vertex )
171 {
172 int count = 0;
173 for ( const auto& edge : incidentInterfaceElements( vertex ) )
174 {
175 std::ignore = edge;
176 count++;
177 }
178
179 return ( count == 2 );
180 }
181};
182
183} // end namespace Dune
184
185#endif
Class defining a longest edge refinement strategy.
Definition: longestedgerefinement.hh:25
static bool atBoundary(const Vertex &v)
return if vertex is incident to infinite vertex
Definition: longestedgerefinement.hh:125
static auto refinement(const Element &element)
Returns the refinement/coarsening point for each grid cell.
Definition: longestedgerefinement.hh:44
static int boundaryFlag(const Vertex &v)
return if vertex is removable at the boundary
Definition: longestedgerefinement.hh:135
static Vertex coarsening(const Element &element)
return coarsening vertex (vertex of shortest edge)
Definition: longestedgerefinement.hh:69
static bool isRemoveable(const Vertex &vertex)
return if interface vertex is neither a tip nor a junction
Definition: longestedgerefinement.hh:170
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Apr 6, 22:49, 2025)