FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
target_set_computer.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// includes, FEAT
9#include <kernel/geometry/index_set.hpp>
10#include <kernel/geometry/target_set.hpp>
11
12// includes, system
13#include <vector>
14
15namespace FEAT
16{
17 namespace Geometry
18 {
20 namespace Intern
21 {
34 template<int end_dim_, int current_dim_>
35 struct TargetSetComputer
36 {
49 template<typename TargetSetHolderType, typename IndexSetHolderType>
50 static void bottom_to_top(TargetSetHolderType& _target_set_holder, const IndexSetHolderType& parent_ish)
51 {
52 // Template recursion: Call the lower dimensional version first
53 TargetSetComputer<end_dim_, current_dim_-1>::bottom_to_top(_target_set_holder, parent_ish);
54
55 typedef typename IndexSetHolderType::template IndexSet<current_dim_, current_dim_-1>::Type ParentIndexSetType;
56
57 // TargetSet to fill
58 TargetSet& my_target_set(_target_set_holder.template get_target_set<current_dim_>());
59
60 // Only do something if the target set is still empty
61 if(my_target_set.get_num_entities() == 0)
62 {
63 // Lower dimensional target set known to exist
64 TargetSet& ts_below(_target_set_holder.template get_target_set<current_dim_-1>());
65
66 // Indexset for entities of dimension current_dim_-1 at entities of dimension current_dim_
67 const ParentIndexSetType& is_parent_below(parent_ish.template get_index_set<current_dim_, current_dim_-1>());
68 // IndexSet for storing the indices of the MeshPart entities lying at entities of the parent
69 ParentIndexSetType lower_parent_to_mesh_part(Index(is_parent_below.get_num_indices()));
70
71 // For every entity of the parent, this will save whether it is referenced by the TargetSet
72 TargetSet lower_origin_set(is_parent_below.get_index_bound());
73 // and this is the marker for that
74 Index marker(is_parent_below.get_index_bound());
75 for(Index i(0); i < lower_origin_set.get_num_entities(); ++i)
76 lower_origin_set[i] = 0;
77 // Set the values to something bogus for every index present
78 for(Index i(0); i < ts_below.get_num_entities(); ++i)
79 lower_origin_set[ts_below[i]] = marker;
80
81 // Count the number of entities that get added
82 Index num_entities_current_dim(0);
83
84 // Temporary TargetSet initialized with the maximum possible size (= number of entities in the parent mesh,
85 // which is the case if the MeshPart contains all entities of the parent mesh)
86 TargetSet tmp_target_set(is_parent_below.get_num_entities());
87
88 // Check all entities of dimension current_dim_ from the parent
89 for(Index i(0); i < is_parent_below.get_num_entities(); ++i)
90 {
91 bool is_in_mesh_part(true);
92
93 // Check if all entities of dimension current_dim_-1 at entity i are referenced by the TargetSet
94 for(int j(0); j < ParentIndexSetType::num_indices; ++j)
95 {
96 // This is the index in the parent
97 Index parent_index(is_parent_below[i][j]);
98 if(lower_origin_set[parent_index] != marker)
99 is_in_mesh_part = false;
100 }
101
102 // If all subshapes belonged to the MeshPart, create the new parent mapping
103 if(is_in_mesh_part)
104 {
105 tmp_target_set[num_entities_current_dim] = i;
106 num_entities_current_dim++;
107 }
108 }
109
110 // tmp_target_set possibly has the wrong size, so manually create a correctly sized TargetSet
111 TargetSet new_target_set(num_entities_current_dim);
112 for(Index i(0); i < new_target_set.get_num_entities(); ++i)
113 new_target_set[i] = tmp_target_set[i];
114
115 // Update the information in the TargetSetHolder
116 my_target_set = std::move(new_target_set);
117 }
118 } // void bottom_to_top<typename, typename>()
119
132 template<typename TargetSetHolderType, typename IndexSetHolderType>
133 static void top_to_bottom(TargetSetHolderType& _target_set_holder, const IndexSetHolderType& parent_ish)
134 {
135 // Call higher dimensional version first
136 TargetSetComputer<end_dim_, current_dim_+1>::top_to_bottom(_target_set_holder, parent_ish);
137
138 typedef typename IndexSetHolderType::template IndexSet<current_dim_+1, current_dim_>::Type ParentIndexSetType;
139
140 // TargetSet to fill
141 TargetSet& my_target_set(_target_set_holder.template get_target_set<current_dim_>());
142
143 // Only do something if the target set is still empty
144 if(my_target_set.get_num_entities() == 0)
145 {
146 // Higher dimensional target set known to exist
147 TargetSet& ts_above(_target_set_holder.template get_target_set<current_dim_+1>());
148
149 // Indexset for entities of dimension current_dim_ at entities of dimension current_dim_+1
150 const ParentIndexSetType& is_parent_above(parent_ish.template get_index_set<current_dim_+1, current_dim_>());
151 // IndexSet for storing the indices of the MeshPart entities lying at entities of the parent
152 ParentIndexSetType upper_parent_to_mesh_part(Index(is_parent_above.get_num_indices()));
153
154 // For every entity of current_dim_ of the parent, this will save whether it belongs to an entity of
155 // dimensin current_dim_+1 that is referenced through the TargetSetHolder
156 TargetSet upper_origin_set(is_parent_above.get_index_bound());
157 // And this is the marker for that
158 Index marker(is_parent_above.get_index_bound());
159 for(Index i(0); i < upper_origin_set.get_num_entities(); ++i)
160 upper_origin_set[i] = 0;
161
162 for(Index i(0); i < ts_above.get_num_entities(); ++i)
163 {
164 // Index of the current entity in the parent
165 Index parent_index(ts_above[i]);
166 for(int j(0); j < is_parent_above.get_num_indices(); ++j)
167 {
168 // This is i.e. the global number of local edge j at face parent_index in the parent
169 Index parent_sub_entity_index(is_parent_above(parent_index, j));
170 upper_origin_set[parent_sub_entity_index] = marker;
171 }
172 }
173
174 // Temporary TargetSet initialized with the maximum possible size (= number of entities in the parent mesh,
175 // which is the case if the MeshPart contains all entities of the parent mesh)
176 TargetSet tmp_target_set(is_parent_above.get_index_bound());
177 // Count the number of entities that get added
178 Index num_entities_current_dim(0);
179 for(Index i(0); i < upper_origin_set.get_num_entities(); ++i)
180 {
181 if(upper_origin_set[i] == marker)
182 {
183 tmp_target_set[num_entities_current_dim] = i;
184 num_entities_current_dim++;
185 }
186 }
187
188 // tmp_target_set possibly has the wrong size, so manually create a correctly sized TargetSet
189 TargetSet new_target_set(num_entities_current_dim);
190 for(Index i(0); i < new_target_set.get_num_entities(); ++i)
191 new_target_set[i] = tmp_target_set[i];
192
193 // Update the information in the TargetSetHolder
194 my_target_set = std::move(new_target_set);
195 }
196 }
197 }; // struct TargetSetComputer<Index, Index>
198
202 template<int end_dim_>
203 struct TargetSetComputer<end_dim_, end_dim_>
204 {
206 template<typename TargetSetHolderType, typename IndexSetHolderType>
207 static void bottom_to_top(TargetSetHolderType& , const IndexSetHolderType&)
208 {
209 }
210
212 template<typename TargetSetHolderType, typename IndexSetHolderType>
213 static void top_to_bottom(TargetSetHolderType& , const IndexSetHolderType&)
214 {
215 }
216 }; // struct TargetSetComputer<int>
217 } // namespace Intern
219 } // namespace Geometry
220} // namespace FEAT
FEAT namespace.
Definition: adjactor.hpp:12
std::uint64_t Index
Index data type.