diff --git a/dune/grid/uggrid/uggridindexsets.hh b/dune/grid/uggrid/uggridindexsets.hh index 1eafd1187f2bb40f7e26fe0ad8ffe24e15520c17..fb12e379ca4cb5b94e5f95b40fe1e108c0f04b99 100644 --- a/dune/grid/uggrid/uggridindexsets.hh +++ b/dune/grid/uggrid/uggridindexsets.hh @@ -10,6 +10,7 @@ #include #include +#include #include namespace Dune { @@ -48,40 +49,110 @@ namespace Dune { return UG_NS::levelIndex(grid_->getRealImplementation(e).getTarget()); } - //! get index of subEntity of a codim 0 entity + /** \brief Get index of subEntity of a codim cc entity + * \param codim Codimension WITH RESPECT TO THE GRID of the subentity whose index we want + */ template unsigned int subIndex (const typename GridImp::Traits::template Codim::Entity& e, int i, unsigned int codim) const { + // The entity is a vertex, so each subentity must be a vertex too (anything else is not supported) if (cc==dim) + { + assert(codim==dim); return UG_NS::levelIndex(grid_->getRealImplementation(e).getTarget()); + } - if (codim==dim) - return UG_NS::levelIndex(UG_NS::Corner(grid_->getRealImplementation(e).getTarget(), - UGGridRenumberer::verticesDUNEtoUG(i,e.type()))); - - if (codim==0) - return UG_NS::levelIndex(grid_->getRealImplementation(e).getTarget()); - - if (codim==dim-1) { + // The following block is for 2d grids + Hybrid::ifElse(Std::bool_constant(), [&](auto id) + { + // The entity is an element + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + // Element indices + if (codim==0) + return UG_NS::levelIndex(grid_->getRealImplementation(e).getTarget()); + + // Edge indices + if (codim==1) + { + auto a=ReferenceElements::general(e.type()).subEntity(i,dim-1,0,dim); + auto b=ReferenceElements::general(e.type()).subEntity(i,dim-1,1,dim); + return UG_NS::levelIndex(UG_NS::GetEdge(UG_NS::Corner(grid_->getRealImplementation(e).getTarget(), + UGGridRenumberer::verticesDUNEtoUG(a,e.type())), + UG_NS::Corner(grid_->getRealImplementation(e).getTarget(), + UGGridRenumberer::verticesDUNEtoUG(b,e.type())))); + } + + // Vertex indices + if (codim==dim) + return UG_NS::levelIndex(UG_NS::Corner(grid_->getRealImplementation(e).getTarget(), + UGGridRenumberer::verticesDUNEtoUG(i,e.type()))); + }); + + // The entity is an edge + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + DUNE_THROW(NotImplemented, "Subindices of an element edge"); + return (unsigned int)0; + }); + + return (unsigned int)0; + }); + + // The following block is for 3d grids + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + // The entity is an element + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + // Element indices + if (codim==0) + return UG_NS::levelIndex(grid_->getRealImplementation(e).getTarget()); + + // Face indices + if (codim==1) + return UG_NS::levelIndex(UG_NS::SideVector(grid_->getRealImplementation(e).getTarget(), + UGGridRenumberer::facesDUNEtoUG(i,e.type()))); + + // Edge indices + if (codim==2) + { + auto a=ReferenceElements::general(e.type()).subEntity(i,dim-1,0,dim); + auto b=ReferenceElements::general(e.type()).subEntity(i,dim-1,1,dim); + return UG_NS::levelIndex(UG_NS::GetEdge(UG_NS::Corner(grid_->getRealImplementation(e).getTarget(), + UGGridRenumberer::verticesDUNEtoUG(a,e.type())), + UG_NS::Corner(grid_->getRealImplementation(e).getTarget(), + UGGridRenumberer::verticesDUNEtoUG(b,e.type())))); + } + + // Vertex indices + assert (codim==dim); + return UG_NS::levelIndex(UG_NS::Corner(grid_->getRealImplementation(e).getTarget(), + UGGridRenumberer::verticesDUNEtoUG(i,e.type()))); + }); + + // The entity is a face + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + DUNE_THROW(NotImplemented, "Subindices of an element face"); + return 0; + }); - int a=ReferenceElements::general(e.type()).subEntity(i,dim-1,0,dim); - int b=ReferenceElements::general(e.type()).subEntity(i,dim-1,1,dim); - return UG_NS::levelIndex(UG_NS::GetEdge(UG_NS::Corner(grid_->getRealImplementation(e).getTarget(), - UGGridRenumberer::verticesDUNEtoUG(a,e.type())), - UG_NS::Corner(grid_->getRealImplementation(e).getTarget(), - UGGridRenumberer::verticesDUNEtoUG(b,e.type())))); - } + // The entity is an edge + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + DUNE_THROW(NotImplemented, "Subindices of an element edge"); + return 0; + }); - if (codim==1) - return UG_NS::levelIndex(UG_NS::SideVector(grid_->getRealImplementation(e).getTarget(), - UGGridRenumberer::facesDUNEtoUG(i,e.type()))); + return (unsigned int)0; + }); - DUNE_THROW(GridError, "UGGrid<" << dim << "," << dim << ">::subIndex isn't implemented for codim==" << codim ); + DUNE_THROW(GridError, "UGGrid<" << dim << ">::subIndex isn't implemented for codim==" << codim ); } - //! get number of entities of given codim, type and on this level int size (int codim) const { if (codim==0) @@ -206,33 +277,100 @@ namespace Dune { int i, unsigned int codim) const { + // The entity is a vertex, so each subentity must be a vertex too (anything else is not supported) if (cc==dim) + { + assert(codim==dim); return UG_NS::leafIndex(grid_.getRealImplementation(e).getTarget()); + } - if (codim==0) - return UG_NS::leafIndex(grid_.getRealImplementation(e).getTarget()); - - const GeometryType type = e.type(); - - if (codim==dim) - return UG_NS::leafIndex(UG_NS::Corner(grid_.getRealImplementation(e).getTarget(), - UGGridRenumberer::verticesDUNEtoUG(i,type))); - - if (codim==dim-1) { + // The following block is for 2d grids + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + // The entity is an element + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + // Element indices + if (codim==0) + return UG_NS::leafIndex(grid_.getRealImplementation(e).getTarget()); + + // Edge indices + if (codim==1) + { + auto a=ReferenceElements::general(e.type()).subEntity(i,dim-1,0,dim); + auto b=ReferenceElements::general(e.type()).subEntity(i,dim-1,1,dim); + return UG_NS::leafIndex(UG_NS::GetEdge(UG_NS::Corner(grid_.getRealImplementation(e).getTarget(), + UGGridRenumberer::verticesDUNEtoUG(a,e.type())), + UG_NS::Corner(grid_.getRealImplementation(e).getTarget(), + UGGridRenumberer::verticesDUNEtoUG(b,e.type())))); + } + + // Vertex indices + if (codim==dim) + return UG_NS::leafIndex(UG_NS::Corner(grid_.getRealImplementation(e).getTarget(), + UGGridRenumberer::verticesDUNEtoUG(i,e.type()))); + }); + + // The entity is an edge + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + DUNE_THROW(NotImplemented, "Subindices of an element edge"); + return (unsigned int)0; + }); + + return (unsigned int)0; + }); + + // The following block is for 3d grids + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + // The entity is an element + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + // Element indices + if (codim==0) + return UG_NS::leafIndex(grid_.getRealImplementation(e).getTarget()); + + // Face indices + if (codim==1) + return UG_NS::leafIndex(UG_NS::SideVector(grid_.getRealImplementation(e).getTarget(), + UGGridRenumberer::facesDUNEtoUG(i,e.type()))); + + // Edge indices + if (codim==2) + { + auto a=ReferenceElements::general(e.type()).subEntity(i,dim-1,0,dim); + auto b=ReferenceElements::general(e.type()).subEntity(i,dim-1,1,dim); + return UG_NS::leafIndex(UG_NS::GetEdge(UG_NS::Corner(grid_.getRealImplementation(e).getTarget(), + UGGridRenumberer::verticesDUNEtoUG(a,e.type())), + UG_NS::Corner(grid_.getRealImplementation(e).getTarget(), + UGGridRenumberer::verticesDUNEtoUG(b,e.type())))); + } + + // Vertex indices + assert (codim==dim); + return UG_NS::leafIndex(UG_NS::Corner(grid_.getRealImplementation(e).getTarget(), + UGGridRenumberer::verticesDUNEtoUG(i,e.type()))); + }); + + // The entity is a face + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + DUNE_THROW(NotImplemented, "Subindices of an element face"); + return 0; + }); - int a=ReferenceElements::general(type).subEntity(i,dim-1,0,dim); - int b=ReferenceElements::general(type).subEntity(i,dim-1,1,dim); - return UG_NS::leafIndex(UG_NS::GetEdge(UG_NS::Corner(grid_.getRealImplementation(e).getTarget(), - UGGridRenumberer::verticesDUNEtoUG(a,type)), - UG_NS::Corner(grid_.getRealImplementation(e).getTarget(), - UGGridRenumberer::verticesDUNEtoUG(b,type)))); - } + // The entity is an edge + Hybrid::ifElse(Std::bool_constant(), [&](auto id) -> unsigned int + { + DUNE_THROW(NotImplemented, "Subindices of an element edge"); + return 0; + }); - if (codim==1) - return UG_NS::leafIndex(UG_NS::SideVector(grid_.getRealImplementation(e).getTarget(), - UGGridRenumberer::facesDUNEtoUG(i,type))); + return (unsigned int)0; + }); - DUNE_THROW(GridError, "UGGrid<" << dim << "," << dim << ">::subLeafIndex isn't implemented for codim==" << codim ); + DUNE_THROW(GridError, "UGGrid<" << dim << "> leaf index set subIndex isn't implemented for codim==" << codim ); } //! get number of entities of given codim and type