7#ifndef DUNE_FUFEM_IMPROVEGRID_HH
8#define DUNE_FUFEM_IMPROVEGRID_HH
21namespace Dune::Fufem::Impl {
27 r[0] = a[1] * b[2] - a[2] * b[1];
28 r[1] = a[2] * b[0] - a[0] * b[2];
29 r[2] = a[0] * b[1] - a[1] * b[0];
35template <
class EntityType>
38 if (!entity.type().isTetrahedron())
41 const int dim = EntityType::dimension;
43 namespace Impl = Dune::Fufem::Impl;
44 typename EntityType::Geometry geometry = entity.geometry();
63 + circumRadiusNumerator1 + circumRadiusNumerator2;
65 double circumRadius = circumRadiusNumerator.
two_norm() / (2*(ba*Impl::crossProduct(ca,da)));
67 double volume = Impl::crossProduct(ba,ca) * da / 6;
69 double area = Impl::crossProduct(ba,ca).
two_norm()/2;
70 area += Impl::crossProduct(da,ba).two_norm()/2;
71 area += Impl::crossProduct(da,ca).two_norm()/2;
74 double inRadius = 3*volume/area;
77 return std::abs(circumRadius / inRadius);
87template <
class Gr
idType>
90 const int dim = GridType::dimension;
92 const auto& indexSet = levelView.indexSet();
109 double edgeMidPoints[6][3] = {{0.5,0,0},
116 for (
const auto& e : elements(levelView)) {
118 const auto& father = e.father();
120 const auto geometryInFather = e.geometryInFather();
121 for (
size_t i=0; i<e.subEntities(
dim); i++) {
123 const auto& positionInFather = geometryInFather.corner(i);
125 for (
int j=0; j<6; j++) {
126 if ( std::abs(positionInFather[0]-edgeMidPoints[j][0]) < 0.1
127 && std::abs(positionInFather[1]-edgeMidPoints[j][1]) < 0.1
128 && std::abs(positionInFather[2]-edgeMidPoints[j][2]) < 0.1) {
130 isNewOnThisLevel[indexSet.
subIndex(e,i,
dim)][0] =
true;
131 bisectionPosition[indexSet.
subIndex(e,i,
dim)] = father.geometry().global(positionInFather);
136 if ( std::abs(positionInFather[0]-0.25) < 0.1
137 && std::abs(positionInFather[1]-0.25) < 0.1
138 && std::abs(positionInFather[2]-0.25) < 0.1) {
140 isNewOnThisLevel[indexSet.
subIndex(e,i,
dim)][0] =
true;
141 isTetMidPoint[indexSet.
subIndex(e,i,
dim)][0] =
true;
142 bisectionPosition[indexSet.
subIndex(e,i,
dim)] = father.geometry().global(positionInFather);
151 for (
const auto& e : elements(levelView)){
156 if (indicator > threshold || e.geometry().jacobianInverseTransposed(dummy).determinant() < 0) {
159 for (
size_t i=0; i<e.subEntities(
dim); i++){
160 if (boundary.containsVertex(indexSet.
subIndex(e,i,
dim)) || isTetMidPoint[indexSet.
subIndex(e,i,
dim)][0]) {
168 for (
const auto& v : vertices(levelView)) {
171 int vIdx = indexSet.
index(v);
173 if (!isNewOnThisLevel[vIdx][0] || !badVertices[vIdx][0])
176 grid.setPosition(v, bisectionPosition[vIdx]);
179 return badVertices.
count();
182template <
class Gr
idType>
185 const int dim = GridType::dimension;
196 for(
int i=0;i<maxIter;++i) {
198 int nBadVertices = 0;
200 for(
int level=
maxLevel; level>0; --level) {
203 std::cout << nBadVertices <<
" bad vertices were detected in grid improvement iteration " << i <<
"." <<
std::endl;
204 if(nBadVertices==0)
break;
209template <
class Gr
idView>
215 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:218
void improveGrid(GridType &grid, double threshold, int maxIter=10)
Definition improvegrid.hh:183
int improveGridLevel(GridType &grid, double threshold, int level)
Improve maximal aspect ratio of the grid by moving vertices.
Definition improvegrid.hh:88
double aspectRatio(const EntityType &entity)
Definition improvegrid.hh:36
void printAspectRatios(const GridView &gridView)
Definition improvegrid.hh:210
Contains a methods which prolongs a boundary patch defined on grid level zero to all other levels.