7#ifndef DUNE_FUFEM_IMPROVEGRID_HH
8#define DUNE_FUFEM_IMPROVEGRID_HH
20namespace Dune::Fufem::Impl {
26 r[0] = a[1] * b[2] - a[2] * b[1];
27 r[1] = a[2] * b[0] - a[0] * b[2];
28 r[2] = a[0] * b[1] - a[1] * b[0];
34template <
class EntityType>
37 if (!entity.type().isTetrahedron())
40 const int dim = EntityType::dimension;
42 namespace Impl = Dune::Fufem::Impl;
43 typename EntityType::Geometry geometry = entity.geometry();
62 + circumRadiusNumerator1 + circumRadiusNumerator2;
64 double circumRadius = circumRadiusNumerator.
two_norm() / (2*(ba*Impl::crossProduct(ca,da)));
66 double volume = Impl::crossProduct(ba,ca) * da / 6;
68 double area = Impl::crossProduct(ba,ca).
two_norm()/2;
69 area += Impl::crossProduct(da,ba).two_norm()/2;
70 area += Impl::crossProduct(da,ca).two_norm()/2;
73 double inRadius = 3*volume/area;
76 return std::abs(circumRadius / inRadius);
86template <
class Gr
idType>
89 const int dim = GridType::dimension;
91 const auto& indexSet = levelView.indexSet();
108 double edgeMidPoints[6][3] = {{0.5,0,0},
115 for (
const auto& e : elements(levelView)) {
117 const auto& father = e.father();
119 const auto geometryInFather = e.geometryInFather();
120 for (
size_t i=0; i<e.subEntities(
dim); i++) {
122 const auto& positionInFather = geometryInFather.corner(i);
124 for (
int j=0; j<6; j++) {
125 if ( std::abs(positionInFather[0]-edgeMidPoints[j][0]) < 0.1
126 && std::abs(positionInFather[1]-edgeMidPoints[j][1]) < 0.1
127 && std::abs(positionInFather[2]-edgeMidPoints[j][2]) < 0.1) {
129 isNewOnThisLevel[indexSet.
subIndex(e,i,
dim)][0] =
true;
130 bisectionPosition[indexSet.
subIndex(e,i,
dim)] = father.geometry().global(positionInFather);
135 if ( std::abs(positionInFather[0]-0.25) < 0.1
136 && std::abs(positionInFather[1]-0.25) < 0.1
137 && std::abs(positionInFather[2]-0.25) < 0.1) {
139 isNewOnThisLevel[indexSet.
subIndex(e,i,
dim)][0] =
true;
140 isTetMidPoint[indexSet.
subIndex(e,i,
dim)][0] =
true;
141 bisectionPosition[indexSet.
subIndex(e,i,
dim)] = father.geometry().global(positionInFather);
150 for (
const auto& e : elements(levelView)){
155 if (indicator > threshold || e.geometry().jacobianInverseTransposed(dummy).determinant() < 0) {
158 for (
size_t i=0; i<e.subEntities(
dim); i++){
159 if (boundary.containsVertex(indexSet.
subIndex(e,i,
dim)) || isTetMidPoint[indexSet.
subIndex(e,i,
dim)][0]) {
167 for (
const auto& v : vertices(levelView)) {
170 int vIdx = indexSet.
index(v);
172 if (!isNewOnThisLevel[vIdx][0] || !badVertices[vIdx][0])
175 grid.setPosition(v, bisectionPosition[vIdx]);
178 return badVertices.
count();
181template <
class Gr
idType>
184 const int dim = GridType::dimension;
195 for(
int i=0;i<maxIter;++i) {
197 int nBadVertices = 0;
199 for(
int level=
maxLevel; level>0; --level) {
202 std::cout << nBadVertices <<
" bad vertices were detected in grid improvement iteration " << i <<
"." <<
std::endl;
203 if(nBadVertices==0)
break;
208template <
class Gr
idView>
214 for (
const auto& e : elements(gridView)) {
#define DUNE_THROW(E,...)
constexpr FieldTraits< value_type >::real_type two_norm() const
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
LevelGridView levelGridView(int level) const
Encapsulate a part of a grid boundary.
Definition boundarypatch.hh:217
void improveGrid(GridType &grid, double threshold, int maxIter=10)
Definition improvegrid.hh:182
int improveGridLevel(GridType &grid, double threshold, int level)
Improve maximal aspect ratio of the grid by moving vertices.
Definition improvegrid.hh:87
double aspectRatio(const EntityType &entity)
Definition improvegrid.hh:35
void printAspectRatios(const GridView &gridView)
Definition improvegrid.hh:209
Contains a methods which prolongs a boundary patch defined on grid level zero to all other levels.