10#include <kernel/geometry/intern/congruency_sampler.hpp>
11#include <kernel/geometry/intern/congruency_mapping.hpp>
12#include <kernel/geometry/intern/face_index_mapping.hpp>
13#include <kernel/geometry/index_set.hpp>
25 template<
typename Shape_>
26 class FacetCongruencySampler
29 static constexpr int facet_dim = Shape_::dimension-1;
30 typedef typename Shape::FaceTraits<Shape_, facet_dim>::ShapeType FacetType;
32 template<
typename Outer_>
40 explicit CompIndexMap(
const Outer_& outer,
int idx) : _outer(outer), _idx(idx) {}
42 Index operator[](
int i)
const
44 return _outer[Geometry::Intern::FaceIndexMapping<Shape_, facet_dim, 0>::map(_idx,i)];
48 template<
typename VertsAtFace_,
typename VertsAtShape_,
typename FacesAtShape_>
49 static int compare(
const VertsAtFace_& verts_at_face,
const VertsAtShape_& verts_at_shape,
50 const FacesAtShape_& faces_at_shape,
const Index shape_idx,
const int local_face)
52 CompIndexMap<typename VertsAtShape_::IndexTupleType> cim(verts_at_shape[shape_idx], local_face);
54 int code = CongruencySampler<FacetType>::compare(verts_at_face[faces_at_shape(shape_idx, local_face)], cim);
55 int loc_ori = CongruencySampler<FacetType>::orientation(code);
56 int ref_ori = Shape::ReferenceCell<Shape_>::facet_orientation(local_face);
57 return loc_ori * ref_ori;
61 template<
typename Facet_,
int codim_ = Facet_::dimension>
62 class FacetFlipRecurser
65 static constexpr int subdim = Facet_::dimension - codim_;
67 static void flip(IndexSetWrapper<Facet_, Facet_::dimension-1>& isw, Index ifacet)
69 FacetFlipRecurser<Facet_, codim_-1>::flip(isw, ifacet);
70 auto& idx_set = isw.template get_index_set<subdim>();
71 Intern::CongruencyMapping<Facet_, subdim>::flip(idx_set[ifacet]);
75 template<
typename Facet_>
76 class FacetFlipRecurser<Facet_, 0>
79 template<
typename ISW_>
80 static void flip(ISW_&, Index)
93 template<
typename Shape_>
97 static_assert(Shape_::dimension > 1,
"invalid shape dimension");
104 static constexpr int shape_dim = Shape_::dimension;
108 auto& facet_isw = ish.template get_index_set_wrapper<shape_dim-1>();
109 const auto& verts_at_face = ish.template get_index_set<shape_dim-1, 0>();
110 const auto& faces_at_elem = ish.template get_index_set<shape_dim, shape_dim-1>();
111 const auto& verts_at_elem = ish.template get_index_set<shape_dim, 0>();
114 const Index num_faces = verts_at_face.get_num_entities();
115 const Index num_elems = verts_at_elem.get_num_entities();
118 std::vector<int> nfaces(num_faces, 0);
119 for(
Index ielem(0); ielem < num_elems; ++ielem)
121 for(
int loc_face(0); loc_face < faces_at_elem.num_indices; ++loc_face)
123 ++nfaces.at(faces_at_elem(ielem, loc_face));
128 for(
Index ielem(0); ielem < num_elems; ++ielem)
131 for(
int loc_face(0); loc_face < faces_at_elem.num_indices; ++loc_face)
134 const Index iface = faces_at_elem(ielem, loc_face);
135 if(nfaces.at(iface) > 1)
139 int ori = Intern::FacetCongruencySampler<Shape_>::compare(
140 verts_at_face, verts_at_elem, faces_at_elem, ielem, loc_face);
147 XASSERTM(ori == -1,
"invalid facet orientation");
150 Intern::FacetFlipRecurser<FacetType>::flip(facet_isw, iface);
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Helper class for reorienting boundary facets to be positive.
static void reorient(IndexSetHolder< Shape_ > &ish)
Reorients the boundary facets in the index set holder to be positive.
std::uint64_t Index
Index data type.
Face traits tag struct template.