9#ifndef DUNE_MMESH_REMESHING_LONGESTEDGEREFINEMENT_HH
10#define DUNE_MMESH_REMESHING_LONGESTEDGEREFINEMENT_HH
13#include <dune/common/exceptions.hh>
14#include <dune/grid/common/partitionset.hh>
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;
43 template<
class Element>
46 ctype longest = -1e100;
49 for( std::size_t i = 0; i < element.subEntities(edgeCodim); ++i )
51 const ctype edgeLength = element.template subEntity<edgeCodim>(i).geometry().volume();
52 if (edgeLength > longest)
59 const auto& longestEdge = element.template subEntity<edgeCodim>(longestIdx);
60 return std::make_pair( longestEdge, longestEdge.geometry().center() );
68 template<
class Element>
72 if constexpr ( Grid::dimension != Grid::dimensionworld )
74 for( std::size_t i = 0; i < element.subEntities(vertexCodim); ++i )
76 const Vertex& v = element.template subEntity<vertexCodim>(i);
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();
88 for( std::size_t i = 0; i < element.subEntities(edgeCodim); ++i )
90 const auto& edge = element.template subEntity<edgeCodim>(i);
91 const ctype edgeLength = edge.geometry().volume();
93 for( std::size_t j = 0; j < 2; ++j )
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;
102 std::sort(vertices.begin(), vertices.end(), [&](
auto a,
auto b){
104 if (a.first.impl().hostEntity()->info().insertionLevel < b.first.impl().hostEntity()->info().insertionLevel)
108 if (a.second < b.second - 1e-14)
112 auto constrained = [&](auto v){ return v.impl().isInterface() || atBoundary(v); };
113 if (!constrained(a.first) and constrained(b.first))
121 return vertices[0].first;
127 const auto& hostgrid = v.impl().grid().getHostGrid();
128 for (
const auto& vertex : incidentVertices( v,
true ) )
129 if ( hostgrid.is_infinite( vertex.impl().hostEntity() ) )
138 if ( v.impl().boundaryFlag() == -1 )
140 v.impl().hostEntity()->info().boundaryFlag = 0;
141 if ( atBoundary( v ) )
144 std::vector< Vertex > incidentAtBoundary;
145 for (
const auto& vertex : incidentVertices( v ) )
146 if ( atBoundary( vertex ) )
147 incidentAtBoundary.push_back( vertex );
150 if( incidentAtBoundary.size() > 2 )
153 assert( incidentAtBoundary.size() == 2 );
154 auto d1 = v.geometry().center();
156 d1 -= incidentAtBoundary[0].geometry().center();
157 d2 -= incidentAtBoundary[1].geometry().center();
160 if ( ( d1 + d2 ).two_norm() > 1e-8 && ( d1 - d2 ).two_norm() > 1e-8 )
161 v.impl().hostEntity()->info().boundaryFlag = 1;
165 return v.impl().boundaryFlag();
169 template<
class Vertex >
173 for (
const auto& edge : incidentInterfaceElements( vertex ) )
179 return ( count == 2 );
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