13#ifndef INTERPOLATION_TOOLS_HH
14#define INTERPOLATION_TOOLS_HH
38 namespace Capabilities
41 template<
class Gr
id >
44 static const bool v =
false;
47 template<
class Gr
id >
60 namespace InterpolationTools
73 if(
vec.size() == 0)
throw DetailedException(
"Cannot detect maximum value in empty vector." , __FILE__, __LINE__);
75 std::for_each(++(
vec.begin()),
vec.end(), [&](Type
const& entry) { if(result < entry) result = entry; });
82 bool contains(Type
const entry, std::vector< Type >
const&
vec)
84 for(
size_t i=0; i<
vec.size(); ++i)
85 if(
vec[i] == entry)
return true;
93 template<
class Scalar_,
int dim_>
95 static int const dim = dim_;
103 *
this = std::move(other);
106 std::ostream&
print(std::ostream& os = std::cout)
const
108 os << std::boolalpha <<
"Relevant: " <<
isRelevant << std::endl;
109 for(
int i=0; i<
normals.size(); ++i) os <<
"normal: " <<
normals[i] <<
", material id: " <<
phaseIds[i] << std::endl;
141 normals = std::move(other.normals);
142 weights = std::move(other.normals);
143 phaseIds = std::move(other.phaseIds);
144 ids = std::move(other.ids);
148 other.onBoundary =
false;
149 other.isRelevant =
true;
154 os << std::boolalpha <<
"is relevant: " <<
isRelevant << std::endl;
155 os <<
"normals:" << std::endl;
162 return collection.
print(os);
171 template <
bool inVertex,
class NormalCollection>
176 if(collection.
normals.size() == 0 || (collection.
normals.size() > 4 && !inVertex) ){
190 std::vector<int> idCount;
191 for(
size_t i=0; i<collection.
ids.size(); ++i){
196 else idCount.push_back( collection.
ids[i] );
201 std::vector<bool> materials;
203 materials = std::vector<bool>(1,
true);
207 for(
size_t i=0; i<collection.
normals.size(); ++i)
208 materials[collection.
phaseIds[i]] =
true;
212 std::vector<int> reducedMaterialList;
213 std::vector<typename NormalCollection::Vector> reducedNormalList;
214 for(
size_t i=0; i<materials.size(); ++i){
216 if(!materials[i])
continue;
219 reducedMaterialList.push_back(i);
220 std::vector<typename NormalCollection::Vector> tmp;
222 for(
size_t j=0; j<collection.
normals.size(); ++j)
228 for(
size_t j=0; j<tmp.size(); ++j)
229 meanNormal += tmp[j];
233 reducedNormalList.push_back(meanNormal);
236 collection.
normals = reducedNormalList;
237 collection.
phaseIds = reducedMaterialList;
251 template<
class Scalar,
class Gr
id,
int dim>
252 struct ChoiceOfShapeFunctionSet
254 typedef typename std::conditional<
260 ChoiceOfShapeFunctionSet() : shapeFunctionSet(3){}
262 type
const shapeFunctionSet;
273 Empty(
const Empty&) =
delete;
274 Empty& operator=(
const Empty&) =
delete;
282 template<
class Scalar,
int dim>
286 template<
class Scalar>
291 explicit NormalContainer(
size_t numberOfVertices=0) : vertexNormals(numberOfVertices) {}
293 template <
class Gr
idView>
294 explicit NormalContainer(GridView
const& gridView) : vertexNormals(gridView.size(GridView::dimension))
301 vertexNormals = std::move(other.vertexNormals);
304 std::ostream&
print(std::ostream& os)
const
307 for(
EntryType const& entry : vertexNormals)
309 std::cout <<
"entry nr. " <<
id++ << std::endl;
321 template<
class Scalar>
326 explicit NormalContainer(
size_t numberOfVertices=0,
size_t numberOfEdges=0) : vertexNormals(numberOfVertices), edgeNormals(numberOfEdges) {}
328 template <
class Gr
idView>
329 explicit NormalContainer(GridView
const& gridView) : vertexNormals(gridView.size(GridView::dimension)), edgeNormals(gridView.size(GridView::dimension-1))
336 vertexNormals = std::move(other.vertexNormals);
337 edgeNormals = std::move(other.edgeNormals);
340 std::ostream&
print(std::ostream& os)
const
343 for(
EntryType const& entry : vertexNormals)
345 std::cout <<
"entry nr. " <<
id++ << std::endl;
349 for(
EntryType const& entry : edgeNormals)
351 std::cout <<
"entry nr. " <<
id++ << std::endl;
384 template<
class IdVector,
bool skipSpecifiedIds = false>
393 for(
size_t i=0; i<specifiedInterfaces.size(); ++i)
addInterface( specifiedInterfaces[i] );
398 if(ids.first == ids.second) std::cout <<
"Ignoring interface between same material ids (id: " << ids.first <<
")" << std::endl;
399 else specifiedInterfaces_.push_back(std::make_pair(
std::min(ids.first,ids.second),
std::max(ids.first,ids.second)));
410 if(tissue == tissueNeighbour)
return true;
411 int const tmp1 =
std::min(tissue, tissueNeighbour),
412 tmp2 =
std::max(tissue, tissueNeighbour);
413 bool contains = std::find( specifiedInterfaces_.begin(), specifiedInterfaces_.end(), std::make_pair(tmp1, tmp2) ) != specifiedInterfaces_.end();
414 return (
contains == skipSpecifiedIds);
418 std::vector<std::pair<int,int> > specifiedInterfaces_;
427 template <
class Face>
433 template <
class Face>
442 template<
class IdVector,
bool skipSpecifiedIds = false>
450 boundaryIds_(boundaryIds), considerFace_(InterpolationTools::
getMaximumValue(specifiedIds) + 1, skipSpecifiedIds)
452 for(
size_t i=0; i<specifiedIds.size(); ++i)
453 considerFace_[specifiedIds[i]] = !skipSpecifiedIds;
460 unsigned int index = face.boundarySegmentIndex();
461 if(index < boundaryIds_.size())
return considerFace_[boundaryIds_[index]];
462 else return !skipSpecifiedIds;
468 IdVector
const& boundaryIds_;
469 std::vector<bool> considerFace_;
476 template <
class Scalar>
487 template <
class Scalar>
494 if(threshold_ < 0)
return;
495 if(fabs(gradient) > threshold_)
510 template <
class Scalar>
515 template <
class PhaseElement>
516 explicit NoPhaseInfo(PhaseElement
const&){}
518 template <
class Entity>
519 Scalar phaseId(Entity
const& entity)
const {
return 0; }
526 template<
class PhaseElement>
527 struct PhaseAsFSElement
529 explicit PhaseAsFSElement(PhaseElement
const& phase_) : phase(phase_){}
531 PhaseAsFSElement(PhaseAsFSElement
const& other) : phase(other.phase){}
533 template<
class Entity>
534 typename PhaseElement::Scalar phaseId(Entity
const& entity)
const
539 PhaseElement
const& phase;
547 template <
class InterpolationPolynomial>
548 struct NoShapeFunctionSet{
549 typedef typename InterpolationPolynomial::GridView::Grid::template Codim<0>::Entity Entity;
551 template <
typename... Parameters>
552 InterpolationPolynomial init(Entity
const& entity,
typename InterpolationPolynomial::GridView
const& gridView, Parameters
const&... parameters)
554 return InterpolationPolynomial(entity, gridView, parameters...);
557 typename InterpolationPolynomial::range_type
558 evaluate(InterpolationPolynomial& polynomial,
typename InterpolationPolynomial::domain_type
const& x)
const
560 return polynomial.evaluate(x);
565 template <
class InterpolationPolynomial>
566 struct UseShapeFunctionSet
567 :
private InterpolationTools::ChoiceOfShapeFunctionSet<typename InterpolationPolynomial::Scalar, typename InterpolationPolynomial::GridView::Grid, InterpolationPolynomial::GridView::dimension>
569 typedef typename InterpolationPolynomial::GridView::Grid::template Codim<0>::Entity Entity;
571 template <
typename... Parameters>
572 InterpolationPolynomial init(Entity
const& entity,
typename InterpolationPolynomial::GridView
const& gridView, Parameters
const&... parameters)
574 return InterpolationPolynomial(entity, gridView, shapeFunctionSet, parameters...);
577 typename InterpolationPolynomial::range_type
578 evaluate(InterpolationPolynomial
const& polynomial,
typename InterpolationPolynomial::domain_type
const& x)
const
580 return polynomial.evaluate(x, shapeFunctionSet);
584 using InterpolationTools::ChoiceOfShapeFunctionSet<
typename InterpolationPolynomial::Scalar,
typename InterpolationPolynomial::GridView::Grid,InterpolationPolynomial::GridView::dimension>::shapeFunctionSet;
592 template <
class InterpolationPolynomial,
bool has_needsShapeFunctionSet>
593 struct ChooseShapeFunctionSetPolicy
595 typedef NoShapeFunctionSet<InterpolationPolynomial> type;
598 template <
class InterpolationPolynomial>
599 struct ChooseShapeFunctionSetPolicy<InterpolationPolynomial,true>
602 typedef typename std::conditional<InterpolationPolynomial::needsShapeFunctionSet,UseShapeFunctionSet<InterpolationPolynomial>,NoShapeFunctionSet<InterpolationPolynomial> >::type type;
606 template <
class InterpolationPolynomial>
607 struct ShapeFunctionSetPolicy :
public Detail::ChooseShapeFunctionSetPolicy<InterpolationPolynomial,Detail::Has_needsShapeFunctionSet<InterpolationPolynomial>::value>::type
613 template <
class Scalar>
619 template <
class Entity>
620 void init(Entity
const& entity)
622 initialVolume = entity.geometry().volume();
625 template <
class Entity>
626 bool operator()(Entity
const& entity, Scalar referenceVolume = -1.)
const
628 return (entity.geometry().volume() < ((referenceVolume<0) ? scale*initialVolume : referenceVolume ));
632 Scalar scale, initialVolume;
635 template <
class Scalar>
638 explicit ConstantDamping(Scalar
const dampingFactor_ = 0.9) : dampingFactor(dampingFactor_), exponent(0)
640 assert(dampingFactor > 0);
643 void increase() { (dampingFactor < 1) ? --exponent : ++exponent; }
645 void decrease() { (dampingFactor < 1) ? ++exponent : --exponent; }
655 Scalar
const dampingFactor;
664 explicit MergedPolicy(
const Policies&... policies) : Policies(policies)...{}
673 namespace InterpolationTools
681 template <
class Entity,
class Gr
idView>
684 std::vector<int> result(GridView::dimension+1,-1);
685 for(
size_t i=0; i<result.size(); ++i) result[i] = gridView.indexSet().subIndex(entity,i,GridView::dimension);
696 template <
class Entity>
699 Dune::GeometryType
const gt(entity.type().id(), Entity::dimension);
700 std::vector<int> result(2,0);
702 result[0] = Dune::GenericReferenceElements<typename Entity::ctype,Entity::dimension>::general(gt).subEntity(edgeId,Entity::dimension-1,0,Entity::dimension);
703 result[1] = Dune::GenericReferenceElements<typename Entity::ctype,Entity::dimension>::general(gt).subEntity(edgeId,Entity::dimension-1,1,Entity::dimension);
714 template <
class Entity,
class Gr
idView>
718 std::vector<int> result(2,0);
719 result[0] = gridView.indexSet().subIndex(entity,localIds[0],GridView::dimension);
720 result[1] = gridView.indexSet().subIndex(entity,localIds[1],GridView::dimension);
730 template <
class NormalCollection,
class Vector>
733 for(
int i=0; i<vid.size(); ++i){
734 for(
int j=0; j<vertexNormals[vid[i]].
normals.size(); ++j)
735 if(fabs(vertexNormals[vid[i]].phaseIds[j] - tissueId ) < 1e-9){
736 localNormals[i] = vertexNormals[vid[i]].
normals[0];
745 template <
class FaceIterator,
class Scalar,
int dim>
751 for(; iter!=iend; ++iter, ++counter)
753 normals[counter] = -1.*iter->centerUnitOuterNormal();
754 result[counter] = -1.*scalarProduct(x - iter->geometry().corner(0), normals[counter]);
755 assert(result[counter] <= 0);
760 template <
class Vector>
763 typedef typename Vector::field_type Scalar;
764 Vector edge = end - start;
768 Scalar alpha = p*edge;
775 template <
class Entity,
class Scalar,
int dim>
778 Scalar d =
dist(x, entity.geometry().corner(0), entity.geometry().corner(1));
779 Scalar tmp =
dist(x, entity.geometry().corner(1), entity.geometry().corner(2));
781 tmp =
dist(x, entity.geometry().corner(2), entity.geometry().corner(3));
786 template <
class Scalar>
787 inline Scalar
invert(Scalar
const entry){
return -1./entry; }
789 template <
class Scalar>
790 inline Scalar
invert2(Scalar
const entry){
return 1./(entry*entry); }
792 template <
class Scalar>
794 Scalar div = sqrt(pow(-1.*entry,1.8));
795 return (div > 1e-9) ? 1./div : 1e9;
799 template <
class Vector>
803 for(
int i=0; i<weights.size(); ++i) result[i] = 1.0 - weights[i];
807 template <
class Vector>
811 for(
int i=0; i<weights.size(); ++i) result[i] = fun(weights[i]);
816 template <
class Gr
idView,
class Entity,
class Vector,
class Deformation>
819 typedef typename Vector::field_type Scalar;
820 typedef typename GridView::IntersectionIterator FaceIterator;
821 int constexpr dim = GridView::dimension;
822 std::vector<Vector> normals(dim+1);
823 FaceIterator iter = gridView.ibegin(entity),
824 iend = gridView.iend(entity);
826 std::vector<Vector> localEvaluationPoints(dim+1);
827 for(
int i=0; i<dim+1; ++i) localEvaluationPoints[i] = entity.geometry().local(entity.geometry().global(x_local) + (weights[i])*normals[i]);
833 for(
size_t i=0; i<localEvaluationPoints.size(); ++i) result += normalizedWeights[i] * deformation.value(entity, localEvaluationPoints[i]);
837 template <
class Interpolation>
840 explicit Distance(Interpolation
const& interpolation_)
841 : interpolation(interpolation_)
844 template <
class Cell,
class Vector>
847 Vector const& c0 = cell.geometry().corner(0),
848 c1 = cell.geometry().corner(1),
849 c2 = cell.geometry().corner(2);
851 Vector pos = 0.5*(c0 + c1);
852 Vector def = interpolation.value(cell,cell.geometry().local(pos));
853 if(def*def > 1e-9)
return dist(x,c0,c1);
855 def = interpolation.value(cell,cell.geometry().local(pos));
856 if(def*def > 1e-9)
return dist(x,c1,c2);
858 def = interpolation.value(cell,cell.geometry().local(pos));
859 if(def*def > 1e-9)
return dist(x,c2,c0);
862 template <
class Cell,
class Vector=Dune::FieldVector<
double,Cell::dimension> >
865 Vector const& c0 = cell.geometry().corner(0),
866 c1 = cell.geometry().corner(1),
867 c2 = cell.geometry().corner(2);
869 Vector pos = 0.5*(c0 + c1);
870 Vector def = interpolation.value(cell,cell.geometry().local(pos));
871 if(def*def > 1e-9)
return getNormal(c0,c1);
873 def = interpolation.value(cell,cell.geometry().local(pos));
874 if(def*def > 1e-9)
return getNormal(c1,c2);
876 def = interpolation.value(cell,cell.geometry().local(pos));
877 if(def*def > 1e-9)
return getNormal(c2,c0);
881 template <
class Vector>
886 auto tmp = result[0];
887 result[0] = -result[1];
892 Interpolation
const& interpolation;
895 template <
class Distance,
class Cell,
class Vector,
class Scalar=
typename Vector::field_type>
898 Scalar r = rad*sqrt(h*h);
900 Scalar alpha = eta*h*(1+
distance(cell,x)/r);
907 template <
class Gr
id,
class Deformation,
class Vector,
class DeformationPolicy,
class DampingPolicy>
908 bool adjustDampingFactor(Grid& grid, Deformation
const& deformation,
Vector const& initialVolume, DeformationPolicy
const& deformationPolicy, DampingPolicy& dampingPolicy)
910 typedef typename Grid::ctype ctype;
911 typedef typename Grid::template Codim<0>::Entity
Cell;
915 std::for_each(grid.leafGridView().template begin<0>(), grid.leafGridView().template end<0>(), [&](
typename Grid::LeafGridView::template Codim<0>::Iterator::Entity
const& entity)
917 LocalGeometryInCoarseGridAncestor<Grid> lgcga(grid, Cell(entity));
918 typedef decltype(entity) EntityRef;
919 typedef typename std::remove_reference<EntityRef>::type Entity;
920 constexpr int dim = Entity::Geometry::dimension;
922 for(int i=0; i<entity.geometry().corners(); ++i)
924 typename Dune::template UGGridFamily<dim, dim>::Traits::template Codim<dim>::Entity e(entity.template subEntity<dim>(i));
926 Dune::FieldVector<ctype,dim> p(Dune::template GenericReferenceElements<ctype,dim>::general(entity.type()).position(i,dim));
927 Dune::FieldVector<ctype,dim> v(lgcga.global(p));
928 Dune::FieldVector<ctype,dim> w(lgcga.getFather()->geometry().global(v));
930 Dune::FieldVector<ctype,dim+1> baryInFatherCell = barycentric(v);
932 for(int i=0; i<dim+1; ++i) if(std::abs(baryInFatherCell[i]) < 1e-9) inCell = false;
934 w = lgcga.getFather()->geometry().global(v);
935 Distance<Deformation> distance(deformation);
937 w += dampingPolicy() * deformation.value(*(lgcga.getFather()),v);
938 else w += dampingPolicy() * interpolateDeformation(grid.levelView(0), *(lgcga.getFather()), v, deformation);
943 grid.setPosition(e,w);
949 auto cend = grid.leafGridView().template end<0>();
950 for(
auto ci = grid.leafGridView().template begin<0>(); ci!=cend; ++ci)
952 if(ci->geometry().volume()/initialVolume[grid.leafGridView().indexSet().index(*ci)] < minrel) minrel = ci->geometry().volume()/initialVolume[grid.leafGridView().indexSet().index(*ci)];
953 if(ci->geometry().volume() < minvol) minvol = ci->geometry().volume();
954 if(deformationPolicy(*ci, 0.3*initialVolume[grid.leafGridView().indexSet().index(*ci)]))
return false;
957 std::cout <<
"Minvol: " << minvol << std::endl;
958 std::cout <<
"Minrel: " << minrel << std::endl;
963 template<
class Gr
id,
class DefFunction,
template <
class>
class AcceptDeformationPolicy=Policy::RelativeDeformation,
template <
class>
class DampingPolicy = Policy::ConstantDamping >
964 void deformGrid(Grid& grid, DefFunction
const& deformation,
bool allCells,
bool doreset,
965 AcceptDeformationPolicy<typename Grid::ctype> deformationPolicy = AcceptDeformationPolicy<typename Grid::ctype>(),
966 DampingPolicy<typename Grid::ctype> dampingPolicy = DampingPolicy<typename Grid::ctype>())
968 typedef typename Grid::LeafGridView::template Codim<0>::Iterator CellIterator;
971 std::vector<typename Grid::ctype> initialVolume(grid.leafGridView().indexSet().size(0),0);
972 std::for_each(grid.leafGridView().template begin<0>(), grid.leafGridView().template end<0>(), [&initialVolume,&grid](
typename CellIterator::Entity
const& entity)
974 for(int i=0; i<entity.geometry().corners(); ++i) initialVolume[grid.leafGridView().indexSet().index(entity)] = entity.geometry().volume();
977 std::cout <<
"Initial damping factor: " << dampingPolicy() << std::endl;
978 while(!
adjustDampingFactor(grid,deformation,initialVolume,deformationPolicy,dampingPolicy))
981 dampingPolicy.decrease();
982 std::cout <<
"Damping factor: " << dampingPolicy() << std::endl;
A wrapper class for conveniently providing exceptions with context information.
A container of hierarchic shape functions (see HierarchicSimplexShapeFunction) up to a given nominal ...
A container of Lagrange shape functions of order Ord on the unit simplex of grid dimension....
Tools for transfer of data between grids.
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
typename GridView::Intersection Face
The type of faces in the grid view.
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Dune::FieldVector< T, n > min(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise minimum.
Hierarchic Finite Elements.
Lagrange Finite Elements.
#define KASKADE_CREATE_MEMBER_VARIABLE_CHECK(VARIABLE_TYPE, VARIABLE_NAME, NAME)
Necessary information for Dune::GeometryGrid.
Scalar distance(Point< Scalar, dim > const &first, Point< Scalar, dim > const &second)
Dune::FieldVector< Scalar, dim > Vector
void deformGrid(Grid &grid, DefFunction const &deformation, bool allCells, bool doreset, AcceptDeformationPolicy< typename Grid::ctype > deformationPolicy=AcceptDeformationPolicy< typename Grid::ctype >(), DampingPolicy< typename Grid::ctype > dampingPolicy=DampingPolicy< typename Grid::ctype >())
Dune::FieldVector< Scalar, dim+1 > getWeights(FaceIterator &iter, FaceIterator &iend, Dune::FieldVector< Scalar, dim > const &x, std::vector< Dune::FieldVector< Scalar, dim > > &normals)
Scalar invert(Scalar const entry)
Vector interpolateDeformation(GridView const &gridView, Entity const &entity, Vector const &x_local, Deformation const &deformation)
Vector getNormalizedWeights(Vector const &weights, typename Vector::field_type(*fun)(typename Vector::field_type const))
Vector::field_type dist(Vector const &point, Vector const &start, Vector const &end)
Scalar invert2(Scalar const entry)
Scalar invert3(Scalar const entry)
bool adjustDampingFactor(Grid &grid, Deformation const &deformation, Vector const &initialVolume, DeformationPolicy const &deformationPolicy, DampingPolicy &dampingPolicy)
void relaxVertex(Distance const &distance, Cell const &cell, Vector &x, Scalar const &h, Scalar eta=0.3, size_t rad=3)
Vector getLinearWeights(Vector const &weights, typename Vector::field_type(*fun)(typename Vector::field_type const))
Vector normal(Cell const &cell) const
Vector::field_type operator()(Cell const &cell, Vector const &x) const
Distance(Interpolation const &interpolation_)
Euclidean scalar product.
Threshold for feature detection.
void applyGradientThreshold(Scalar &gradient) const
ApplyGradientThreshold(Scalar const threshold=1.0)
Policy for inner boundaries. Considers all of them.
bool ignoreInnerBoundary(int tissue, int tissueNeighbour) const
Policy for inner boundaries. Considers all of them.
bool ignoreOuterBoundary(Face const &) const
Scalar operator()() const
ConstantDamping(Scalar const dampingFactor_=0.9)
Default policy for inner boundaries. Ignores them.
bool ignoreInnerBoundary(int tissue, int tissueNeighbour) const
Default policy for outer boundary. Ignores them.
bool ignoreOuterBoundary(Face const &) const
MergedPolicy(const Policies &... policies)
void applyGradientThreshold(Scalar &gradient) const
Allows to specify parts of the inner boundary. Inner boundaries are characterized by a change of the ...
SpecifyInnerBoundary(std::vector< std::pair< int, int > > specifiedInterfaces)
void addInterface(int first, int second)
Add interface specified by two material ids.
bool ignoreInnerBoundary(int tissue, int tissueNeighbour) const
Check if interface specified by two material ids should be ignored.
void addInterface(std::pair< int, int > ids)
Add interface specified by two material ids.
Allows to specify parts of the outer boundary.
bool ignoreOuterBoundary(Face const &face) const
Check if outer bounday face should be ignored.
SpecifyOuterBoundary(IdVector const &boundaryIds, IdVector const &specifiedIds)