dune-mmesh (unstable)

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