9#ifndef DUNE_MMESH_REMESHING_LONGESTEDGEREFINEMENT_HH
10#define DUNE_MMESH_REMESHING_LONGESTEDGEREFINEMENT_HH
12#include <dune/common/exceptions.hh>
13#include <dune/grid/common/partitionset.hh>
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;
41 template <
class Element>
43 ctype longest = -1e100;
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) {
55 const auto& longestEdge = element.template subEntity<edgeCodim>(longestIdx);
56 return std::make_pair(longestEdge, longestEdge.geometry().center());
64 template <
class Element>
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);
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();
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();
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;
92 std::sort(vertices.begin(), vertices.end(), [&](
auto a,
auto b) {
94 if (a.first.impl().hostEntity()->info().insertionLevel <
95 b.first.impl().hostEntity()->info().insertionLevel)
99 if (a.second < b.second - 1e-14) return true;
102 auto constrained = [&](auto v) {
103 return v.impl().isInterface() || atBoundary(v);
105 if (!constrained(a.first) and constrained(b.first))
return true;
112 return vertices[0].first;
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;
126 if (v.impl().boundaryFlag() == -1) {
127 v.impl().hostEntity()->info().boundaryFlag = 0;
130 std::vector<Vertex> incidentAtBoundary;
131 for (
const auto& vertex : incidentVertices(v))
132 if (atBoundary(vertex)) incidentAtBoundary.push_back(vertex);
136 if (incidentAtBoundary.size() > 2)
return 0;
138 assert(incidentAtBoundary.size() == 2);
139 auto d1 = v.geometry().center();
141 d1 -= incidentAtBoundary[0].geometry().center();
142 d2 -= incidentAtBoundary[1].geometry().center();
145 if ((d1 + d2).two_norm() > 1e-8 && (d1 - d2).two_norm() > 1e-8)
146 v.impl().hostEntity()->info().boundaryFlag = 1;
150 return v.impl().boundaryFlag();
154 template <
class Vertex>
157 for (
const auto& edge : incidentInterfaceElements(vertex)) {
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