FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
template_interface.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
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>
12
13namespace FEAT::Geometry
14{
20 template<typename MeshStorage_, typename QueryShape_>
21 class MeshQuery
22 {
23 // This class is in a strange place where it both requires access to
24 // low-level details of the adaptive mesh and is part of the public API. To
25 // avoid leaking implementation details directly most types are typedefed
26 // below. The constructor is marked private to avoid making the mesh storage
27 // part of the public API. AdaptiveMesh is marked as a friend to allow it to
28 // construct instances of MeshQuery.
29 template<
30 typename TemplateSet_,
31 typename Shape_,
32 int num_coords_,
33 typename Coord_>
34 friend class AdaptiveMesh;
35
37 static constexpr int dimension = QueryShape_::dimension;
38
40 using MeshStorage = MeshStorage_;
41
43 using Topology = typename MeshStorage::template ElementTopologyByDim<dimension>;
44
46 using Children = typename MeshStorage::template ElementChildrenByDim<dimension>;
47
49 using TemplateSet = typename MeshStorage::TemplateSet;
50
51 public:
53 using QueryShape = QueryShape_;
54
56 using VertexType = typename MeshStorage_::VertexType;
57
59 using VertexCoordinateArray = std::array<VertexType, Shape::FaceTraits<QueryShape_, 0>::count>;
60
62 template<int dim_>
63 using TopologyByDim = typename MeshStorage::template ElementTopologyByDim<dim_>;
64
66 template<int dim_>
67 using RefByDim = typename MeshStorage::template ElementRefByDim<dim_>;
68
70 template<int dim_>
71 using OrientedRefByDim = typename MeshStorage::template OrientedElementRefByDim<dim_>;
72
74 using OrientedVertex = OrientedRefByDim<0>;
76 using OrientedEdge = OrientedRefByDim<1>;
78 using OrientedFace = OrientedRefByDim<2>;
79
81 using VertexRef = RefByDim<0>;
83 using EdgeRef = RefByDim<1>;
85 using FaceRef = RefByDim<2>;
87 using CellRef = RefByDim<3>;
88
89 private:
91 MeshStorage& _storage;
93 Topology& _topology;
95 Children& _children;
96
104 MeshQuery(MeshStorage& storage, Topology& topology, Children& children) :
105 _storage(storage),
106 _topology(topology),
107 _children(children)
108 {
109 }
110
111 public:
112 MeshQuery() = delete;
113
122 VertexCoordinateArray vertex_coordinates() const
123 {
124 VertexCoordinateArray result;
125
126 auto& vertices = _topology.template by_dim<0>();
127 for(int i{0}; i < _topology.template size<0>(); i++)
128 {
129 result[i] = _storage[vertices[i]].vertex;
130 }
131 return result;
132 }
133
142 template<int dim_>
143 typename TemplateSet::template RefinementTypeByDim<dim_> type(RefByDim<dim_> ref) const
144 {
145 return _storage[ref].type;
146 }
147
151 template<int topo_dim_, int entity_dim_>
152 int orientation(const TopologyByDim<topo_dim_>& topology, int elem) const
153 {
154 static_assert(entity_dim_ < topo_dim_);
155
156 using TopoShape = typename Shape::FaceTraits<QueryShape, topo_dim_>::ShapeType;
157 using EntityShape = typename Shape::FaceTraits<QueryShape, entity_dim_>::ShapeType;
158
159 using LocalMapping = Intern::FaceIndexMapping<TopoShape, entity_dim_, 0>;
160 using CongruencySampler = Intern::CongruencySampler<EntityShape>;
161
162 static constexpr int num_vertices = Shape::FaceTraits<EntityShape, 0>::count;
163
164 std::array<RefByDim<0>, num_vertices> local;
165 std::array<RefByDim<0>, num_vertices> foreign;
166
167 const auto& entity = _storage[topology.template key_by_dim<entity_dim_>(elem)];
168
169 for(int i(0); i < num_vertices; i++)
170 {
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;
173 }
174
175 int result = CongruencySampler::compare(local.data(), foreign.data());
176 if(result == -1)
177 {
178 for(int i(0); i < num_vertices; ++i)
179 {
180 for(int j(0); j < num_vertices; ++j)
181 {
182 std::cout << "Comparing:\n";
183 std::cout << " Local: " << local[i] << "\n";
184 std::cout << " Foreign: " << foreign[j] << "\n";
185 }
186 }
187
188 XABORTM("Invalid orientation found.");
189 }
190 return result;
191 }
192
200 template<int dim_>
201 Index topology_size() const
202 {
203 return Shape::FaceTraits<QueryShape, dim_>::count;
204 }
205
217 template<int dim_>
218 OrientedRefByDim<dim_> topology(Index idx) const
219 {
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()!");
222
223 return _topology.template key_by_dim<dim_>(idx);
224 }
225
239 template<int parent_dim_, int child_dim_>
240 RefByDim<child_dim_> boundary(Index parent_idx, Index child_idx) const
241 {
242 static_assert(child_dim_ <= parent_dim_);
243 static_assert(child_dim_ >= 0);
244
245 auto& parent = _storage[topology<parent_dim_>(parent_idx).key];
246 return parent.children.template by_dim<child_dim_>()[child_idx];
247 }
248
260 template<int dim_>
261 RefByDim<dim_> sibling(Index sibling_idx) const
262 {
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()!");
265
266 return _children.template by_dim<dim_>()[sibling_idx];
267 }
268 };
269
270#ifdef DOXYGEN
279 class VertexQuery
280 {
288 Index num_entities(const MeshQuery& query);
289
300 typename MeshQuery_::VertexType_ vertex(const MeshQuery_& query, Index vertex_idx)
301 };
302
303 /*
304 * \brief Template query for vertices.
305 *
306 * This interface is expected by the AdaptiveMesh for constructing edges,
307 * faces, and cells.
308 *
309 * \author Markus Muegge
310 */
311 template<int dim_>
312 class EntityQuery
313 {
314 using Topology = typename MeshQuery_::template TopologyByDim<dim_>;
315
323 Index num_entities(const MeshQuery& query);
324
333 Topology topology(const MeshQuery& query, Index idx)
334
335
343 SubdivisionLevelTuple levels(const MeshQuery_& /*query*/, Index edge_idx)
344 {
345 return {
346 _level_spread[_template.template vertex_of<1>(edge_idx, 0)],
347 _level_spread[_template.template vertex_of<1>(edge_idx, 1)],
348 };
349 }
350 };
351
359 class TemplateSet
360 {
361 public:
363 static constexpr std::uint8_t zero_refinement_type = 0;
365 static constexpr std::uint8_t full_refinement_type = 0b11111111;
366
376 template<typename Shape_>
377 static constexpr bool is_shape_compatible();
378
387 template<int template_dim_, int child_dim_>
388 static constexpr int max_children();
389
399 template<int n>
400 static std::uint8_t refinement_type(const Geometry::SubdivisionLevelTuple<n>& levels);
401
415 template<typename Mesh_>
416 static void convert(const Mesh_& mesh, Geometry::SubdivisionLevels& sdls);
417
431 template<int template_dim_, int child_dim_>
432 static Index num_children(std::uint8_t type);
433
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);
451
475 static NextQuery advance_query(const MeshQuery_& query, PreviousQuery&& template_query)
476
477#endif
478 } // namespace FEAT::Geometry
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
@ parent
indicates that the level is a parent level
Geometry namespace.
std::uint64_t Index
Index data type.