8#include "kernel/geometry/intern/congruency_sampler.hpp"
9#include "kernel/geometry/intern/face_index_mapping.hpp"
10#include <kernel/geometry/intern/adaptive_mesh_storage.hpp>
11#include <kernel/shape.hpp>
20 template<
typename MeshStorage_,
typename QueryShape_>
30 typename TemplateSet_,
34 friend class AdaptiveMesh;
37 static constexpr int dimension = QueryShape_::dimension;
40 using MeshStorage = MeshStorage_;
43 using Topology =
typename MeshStorage::template ElementTopologyByDim<dimension>;
46 using Children =
typename MeshStorage::template ElementChildrenByDim<dimension>;
49 using TemplateSet =
typename MeshStorage::TemplateSet;
53 using QueryShape = QueryShape_;
56 using VertexType =
typename MeshStorage_::VertexType;
59 using VertexCoordinateArray = std::array<VertexType, Shape::FaceTraits<QueryShape_, 0>::count>;
63 using TopologyByDim =
typename MeshStorage::template ElementTopologyByDim<dim_>;
67 using RefByDim =
typename MeshStorage::template ElementRefByDim<dim_>;
71 using OrientedRefByDim =
typename MeshStorage::template OrientedElementRefByDim<dim_>;
74 using OrientedVertex = OrientedRefByDim<0>;
76 using OrientedEdge = OrientedRefByDim<1>;
78 using OrientedFace = OrientedRefByDim<2>;
81 using VertexRef = RefByDim<0>;
83 using EdgeRef = RefByDim<1>;
85 using FaceRef = RefByDim<2>;
87 using CellRef = RefByDim<3>;
91 MeshStorage& _storage;
104 MeshQuery(MeshStorage& storage, Topology& topology, Children& children) :
112 MeshQuery() =
delete;
122 VertexCoordinateArray vertex_coordinates()
const
124 VertexCoordinateArray result;
126 auto& vertices = _topology.template by_dim<0>();
127 for(
int i{0}; i < _topology.template size<0>(); i++)
129 result[i] = _storage[vertices[i]].vertex;
143 typename TemplateSet::template RefinementTypeByDim<dim_> type(RefByDim<dim_> ref)
const
145 return _storage[ref].type;
151 template<
int topo_dim_,
int entity_dim_>
152 int orientation(
const TopologyByDim<topo_dim_>& topology,
int elem)
const
154 static_assert(entity_dim_ < topo_dim_);
156 using TopoShape =
typename Shape::FaceTraits<QueryShape, topo_dim_>::ShapeType;
157 using EntityShape =
typename Shape::FaceTraits<QueryShape, entity_dim_>::ShapeType;
159 using LocalMapping = Intern::FaceIndexMapping<TopoShape, entity_dim_, 0>;
160 using CongruencySampler = Intern::CongruencySampler<EntityShape>;
162 static constexpr int num_vertices = Shape::FaceTraits<EntityShape, 0>::count;
164 std::array<RefByDim<0>, num_vertices> local;
165 std::array<RefByDim<0>, num_vertices> foreign;
167 const auto& entity = _storage[topology.template key_by_dim<entity_dim_>(elem)];
169 for(
int i(0); i < num_vertices; i++)
171 local[i] = topology.template key_by_dim<0>(LocalMapping::map(elem, i)).key;
172 foreign[i] = entity.topology.template key_by_dim<0>(i).key;
175 int result = CongruencySampler::compare(local.data(), foreign.data());
178 for(
int i(0); i < num_vertices; ++i)
180 for(
int j(0); j < num_vertices; ++j)
182 std::cout <<
"Comparing:\n";
183 std::cout <<
" Local: " << local[i] <<
"\n";
184 std::cout <<
" Foreign: " << foreign[j] <<
"\n";
188 XABORTM(
"Invalid orientation found.");
201 Index topology_size()
const
203 return Shape::FaceTraits<QueryShape, dim_>::count;
218 OrientedRefByDim<dim_> topology(Index idx)
const
220 static_assert(dim_ >= 0,
"Invalid shape dimension in MeshQuery::get_from_topology()!");
221 static_assert(dim_ <= 3,
"Invalid shape dimension in MeshQuery::get_from_topology()!");
223 return _topology.template key_by_dim<dim_>(idx);
239 template<
int parent_dim_,
int child_dim_>
240 RefByDim<child_dim_> boundary(Index parent_idx, Index child_idx)
const
242 static_assert(child_dim_ <= parent_dim_);
243 static_assert(child_dim_ >= 0);
245 auto&
parent = _storage[topology<parent_dim_>(parent_idx).key];
246 return parent.children.template by_dim<child_dim_>()[child_idx];
261 RefByDim<dim_> sibling(Index sibling_idx)
const
263 static_assert(dim_ >= 0,
"Invalid shape dimension in MeshQuery::get_from_topology()!");
264 static_assert(dim_ <= 3,
"Invalid shape dimension in MeshQuery::get_from_topology()!");
266 return _children.template by_dim<dim_>()[sibling_idx];
288 Index num_entities(
const MeshQuery& query);
300 typename MeshQuery_::VertexType_ vertex(
const MeshQuery_& query, Index vertex_idx)
314 using Topology =
typename MeshQuery_::template TopologyByDim<dim_>;
323 Index num_entities(
const MeshQuery& query);
333 Topology topology(
const MeshQuery& query, Index idx)
343 SubdivisionLevelTuple levels(
const MeshQuery_& , Index edge_idx)
346 _level_spread[_template.template vertex_of<1>(edge_idx, 0)],
347 _level_spread[_template.template vertex_of<1>(edge_idx, 1)],
363 static constexpr std::uint8_t zero_refinement_type = 0;
365 static constexpr std::uint8_t full_refinement_type = 0b11111111;
376 template<
typename Shape_>
377 static constexpr bool is_shape_compatible();
387 template<
int template_dim_,
int child_dim_>
388 static constexpr int max_children();
400 static std::uint8_t refinement_type(
const Geometry::SubdivisionLevelTuple<n>& levels);
415 template<
typename Mesh_>
416 static void convert(
const Mesh_& mesh, Geometry::SubdivisionLevels& sdls);
431 template<
int template_dim_,
int child_dim_>
432 static Index num_children(std::uint8_t type);
447 template<
typename MeshQuery_>
448 static TemplateQuery<MeshQuery_, 0> get_query(
449 const MeshQuery_& query,
450 Geometry::SubdivisionLevelTuple<Shape::FaceTraits<typename MeshQuery_::QueryShape, 0>::count> levels);
475 static NextQuery advance_query(
const MeshQuery_& query, PreviousQuery&& template_query)
#define XABORTM(msg)
Abortion macro definition with custom message.
@ parent
indicates that the level is a parent level
std::uint64_t Index
Index data type.