16 #include "discrete_problem/dg/multimesh_dg_neighbor_tree.h"
22 template<
typename Scalar>
27 build_multimesh_tree(&root, neighbor_searches, num_neighbor_searches);
35 for (
unsigned int i = 0; i < num_neighbor_searches; i++)
38 update_neighbor_search(ns, &root);
40 if (num_neighbors == 0)
41 num_neighbors = ns->n_neighbors;
43 if (ns->n_neighbors != num_neighbors)
44 throw Hermes::Exceptions::Exception(
"Num_neighbors of different NeighborSearches not matching in assemble_one_state().");
47 processed =
new bool[num_neighbors];
49 for (
unsigned int neighbor_i = 0; neighbor_i < num_neighbors; neighbor_i++)
54 processed[neighbor_i] =
true;
55 for (
unsigned int i = 0; i < num_neighbor_searches; i++)
57 if (!neighbor_searches[i]->neighbors.at(neighbor_i)->visited)
59 processed[neighbor_i] =
false;
66 template<
typename Scalar>
69 for (
unsigned int i = 0; i < number; i++)
72 if (ns->n_neighbors == 1 && (ns->central_transformations_size == 0 || ns->
central_transformations[0]->num_levels == 0))
74 for (
unsigned int j = 0; j < ns->n_neighbors; j++)
80 template<
typename Scalar>
81 void MultimeshDGNeighborTree<Scalar>::insert_into_multimesh_tree(MultimeshDGNeighborTreeNode* node,
unsigned int* transformations,
unsigned int transformation_count)
84 if (transformation_count == 0)
87 if (node->get_left_son() ==
nullptr && node->get_right_son() ==
nullptr)
89 node->set_left_son(
new MultimeshDGNeighborTreeNode(node, transformations[0]));
90 insert_into_multimesh_tree(node->get_left_son(), transformations + 1, transformation_count - 1);
97 if (node->get_left_son()->get_transformation() == transformations[0])
98 insert_into_multimesh_tree(node->get_left_son(), transformations + 1, transformation_count - 1);
100 else if (node->get_right_son())
102 if (node->get_right_son()->get_transformation() == transformations[0])
103 insert_into_multimesh_tree(node->get_right_son(), transformations + 1, transformation_count - 1);
105 throw Hermes::Exceptions::Exception(
"More than two possible sons in insert_into_multimesh_tree().");
110 node->set_right_son(
new MultimeshDGNeighborTreeNode(node, transformations[0]));
111 insert_into_multimesh_tree(node->get_right_son(), transformations + 1, transformation_count - 1);
116 template<
typename Scalar>
117 std::vector<std::vector<unsigned int>*> MultimeshDGNeighborTree<Scalar>::get_multimesh_neighbors_transformations(MultimeshDGNeighborTreeNode* multimesh_tree)
120 std::vector<std::vector<unsigned int>*> running_transformations;
122 running_transformations.push_back(
new std::vector<unsigned int>);
124 traverse_multimesh_tree(multimesh_tree, running_transformations);
125 return running_transformations;
128 template<
typename Scalar>
129 void MultimeshDGNeighborTree<Scalar>::traverse_multimesh_tree(MultimeshDGNeighborTreeNode* node,
130 std::vector<std::vector<unsigned int>*>& running_transformations)
133 if (node->get_transformation() == 0)
135 if (node->get_left_son())
136 traverse_multimesh_tree(node->get_left_son(), running_transformations);
137 if (node->get_right_son())
138 traverse_multimesh_tree(node->get_right_son(), running_transformations);
140 delete running_transformations.back();
141 running_transformations.pop_back();
145 if (node->get_left_son() ==
nullptr && node->get_right_son() ==
nullptr)
148 std::vector<unsigned int>* new_neighbor_transformations =
new std::vector < unsigned int > ;
150 for (
unsigned int i = 0; i < running_transformations.back()->size(); i++)
151 new_neighbor_transformations->push_back((*running_transformations.back())[i]);
153 running_transformations.back()->push_back(node->get_transformation());
155 running_transformations.push_back(new_neighbor_transformations);
160 running_transformations.back()->push_back(node->get_transformation());
161 if (node->get_left_son())
162 traverse_multimesh_tree(node->get_left_son(), running_transformations);
163 if (node->get_right_son())
164 traverse_multimesh_tree(node->get_right_son(), running_transformations);
165 running_transformations.back()->pop_back();
171 template<
typename Scalar>
172 void MultimeshDGNeighborTree<Scalar>::update_neighbor_search(NeighborSearch<Scalar>* ns, MultimeshDGNeighborTreeNode* multimesh_tree)
175 unsigned int num_neighbors = ns->get_num_neighbors();
177 for (
int i = 0; i < num_neighbors; i++)
180 MultimeshDGNeighborTreeNode* node;
181 if (i < ns->central_transformations_alloc_size && ns->central_transformations[i])
182 node = find_node(ns->central_transformations[i]->transf, ns->central_transformations[i]->num_levels, multimesh_tree);
184 node = multimesh_tree;
187 int added = update_ns_subtree(ns, node, i);
196 template<
typename Scalar>
197 MultimeshDGNeighborTreeNode* MultimeshDGNeighborTree<Scalar>::find_node(
unsigned int* transformations,
198 unsigned int transformation_count,
199 MultimeshDGNeighborTreeNode* node)
202 if (transformation_count == 0)
206 if (node->get_left_son())
208 if (node->get_left_son()->get_transformation() == transformations[0])
209 return find_node(transformations + 1, transformation_count - 1, node->get_left_son());
211 if (node->get_right_son())
213 if (node->get_right_son()->get_transformation() == transformations[0])
214 return find_node(transformations + 1, transformation_count - 1, node->get_right_son());
219 Hermes::Exceptions::Exception(
"Transformation of a central element not found in the multimesh tree.");
223 template<
typename Scalar>
224 int MultimeshDGNeighborTree<Scalar>::update_ns_subtree(NeighborSearch<Scalar>* ns,
225 MultimeshDGNeighborTreeNode* node,
unsigned int ith_neighbor)
227 int current_count = ns->get_num_neighbors();
231 if (node->get_left_son() ==
nullptr)
233 if (node->get_right_son())
234 throw Hermes::Exceptions::Exception(
"Only one son (right) not null in MultimeshDGNeighborTree<Scalar>::update_ns_subtree.");
240 Element* neighbor = ns->neighbors[ith_neighbor];
241 typename NeighborSearch<Scalar>::NeighborEdgeInfo edge_info = ns->neighbor_edges[ith_neighbor];
244 std::vector<std::vector<unsigned int>*> running_central_transformations;
246 running_central_transformations.push_back(
new std::vector<unsigned int>);
247 if (ith_neighbor < ns->central_transformations_alloc_size && ns->central_transformations[ith_neighbor])
248 ns->central_transformations[ith_neighbor]->copy_to(running_central_transformations.back());
251 std::vector<std::vector<unsigned int>*> running_neighbor_transformations;
253 running_neighbor_transformations.push_back(
new std::vector<unsigned int>);
254 if (ith_neighbor < ns->neighbor_transformations_alloc_size && ns->neighbor_transformations[ith_neighbor])
255 ns->neighbor_transformations[ith_neighbor]->copy_to(running_neighbor_transformations.back());
258 ns->delete_neighbor(ith_neighbor);
261 if (node->get_left_son())
262 traverse_multimesh_subtree(node->get_left_son(), running_central_transformations,
263 running_neighbor_transformations, edge_info, ns->active_edge,
264 ns->central_el->get_mode());
265 if (node->get_right_son())
266 traverse_multimesh_subtree(node->get_right_son(), running_central_transformations,
267 running_neighbor_transformations, edge_info, ns->active_edge,
268 ns->central_el->get_mode());
271 delete running_central_transformations.back();
272 running_central_transformations.pop_back();
273 delete running_neighbor_transformations.back();
274 running_neighbor_transformations.pop_back();
277 for (
unsigned int i = 0; i < running_central_transformations.size(); i++)
279 ns->neighbors.push_back(neighbor);
280 ns->neighbor_edges.push_back(edge_info);
282 if ((ns->n_neighbors >= ns->central_transformations_alloc_size) || !ns->central_transformations[ns->n_neighbors])
283 ns->add_central_transformations(
new typename NeighborSearch<Scalar>::Transformations, ns->n_neighbors);
285 if ((ns->n_neighbors >= ns->neighbor_transformations_alloc_size) || !ns->neighbor_transformations[ns->n_neighbors])
286 ns->add_neighbor_transformations(
new typename NeighborSearch<Scalar>::Transformations, ns->n_neighbors);
288 ns->central_transformations[ns->n_neighbors]->copy_from(*running_central_transformations[i]);
289 ns->neighbor_transformations[ns->n_neighbors]->copy_from(*running_neighbor_transformations[i]);
294 for (
unsigned int i = 0; i < running_central_transformations.size(); i++)
295 delete running_central_transformations[i];
296 for (
unsigned int i = 0; i < running_neighbor_transformations.size(); i++)
297 delete running_neighbor_transformations[i];
300 return ns->get_num_neighbors() - current_count;
303 template<
typename Scalar>
304 void MultimeshDGNeighborTree<Scalar>::traverse_multimesh_subtree(MultimeshDGNeighborTreeNode* node,
305 std::vector<std::vector<unsigned int>*>& running_central_transformations,
306 std::vector<std::vector<unsigned int>*>& running_neighbor_transformations,
307 const typename NeighborSearch<Scalar>::NeighborEdgeInfo& edge_info,
const int& active_edge,
const int& mode)
310 if (node->get_left_son() ==
nullptr && node->get_right_son() ==
nullptr)
313 std::vector<unsigned int>* new_neighbor_central_transformations =
new std::vector < unsigned int > ;
314 std::vector<unsigned int>* new_neighbor_neighbor_transformations =
new std::vector < unsigned int > ;
317 for (
unsigned int i = 0; i < running_central_transformations.back()->size(); i++)
318 new_neighbor_central_transformations->push_back((*running_central_transformations.back())[i]);
319 for (
unsigned int i = 0; i < running_neighbor_transformations.back()->size(); i++)
320 new_neighbor_neighbor_transformations->push_back((*running_neighbor_transformations.back())[i]);
323 running_central_transformations.back()->push_back(node->get_transformation());
326 running_central_transformations.push_back(new_neighbor_central_transformations);
330 if (mode == HERMES_MODE_TRIANGLE)
331 if ((active_edge == 0 && node->get_transformation() == 0) ||
332 (active_edge == 1 && node->get_transformation() == 1) ||
333 (active_edge == 2 && node->get_transformation() == 2))
334 running_neighbor_transformations.back()->push_back((!edge_info.orientation ? edge_info.local_num_of_edge : (edge_info.local_num_of_edge + 1) % 3));
336 running_neighbor_transformations.back()->push_back((edge_info.orientation ? edge_info.local_num_of_edge : (edge_info.local_num_of_edge + 1) % 3));
339 if ((active_edge == 0 && (node->get_transformation() == 0 || node->get_transformation() == 6)) ||
340 (active_edge == 1 && (node->get_transformation() == 1 || node->get_transformation() == 4)) ||
341 (active_edge == 2 && (node->get_transformation() == 2 || node->get_transformation() == 7)) ||
342 (active_edge == 3 && (node->get_transformation() == 3 || node->get_transformation() == 5)))
343 running_neighbor_transformations.back()->push_back((!edge_info.orientation ? edge_info.local_num_of_edge : (edge_info.local_num_of_edge + 1) %
H2D_MAX_NUMBER_EDGES));
345 running_neighbor_transformations.back()->push_back((edge_info.orientation ? edge_info.local_num_of_edge : (edge_info.local_num_of_edge + 1) %
H2D_MAX_NUMBER_EDGES));
348 running_neighbor_transformations.push_back(new_neighbor_neighbor_transformations);
355 running_central_transformations.back()->push_back(node->get_transformation());
359 if (mode == HERMES_MODE_TRIANGLE)
360 if ((active_edge == 0 && node->get_transformation() == 0) ||
361 (active_edge == 1 && node->get_transformation() == 1) ||
362 (active_edge == 2 && node->get_transformation() == 2))
363 running_neighbor_transformations.back()->push_back((!edge_info.orientation ? edge_info.local_num_of_edge : (edge_info.local_num_of_edge + 1) % 3));
365 running_neighbor_transformations.back()->push_back((edge_info.orientation ? edge_info.local_num_of_edge : (edge_info.local_num_of_edge + 1) % 3));
368 if ((active_edge == 0 && (node->get_transformation() == 0 || node->get_transformation() == 6)) ||
369 (active_edge == 1 && (node->get_transformation() == 1 || node->get_transformation() == 4)) ||
370 (active_edge == 2 && (node->get_transformation() == 2 || node->get_transformation() == 7)) ||
371 (active_edge == 3 && (node->get_transformation() == 3 || node->get_transformation() == 5)))
372 running_neighbor_transformations.back()->push_back((!edge_info.orientation ? edge_info.local_num_of_edge : (edge_info.local_num_of_edge + 1) %
H2D_MAX_NUMBER_EDGES));
374 running_neighbor_transformations.back()->push_back((edge_info.orientation ? edge_info.local_num_of_edge : (edge_info.local_num_of_edge + 1) %
H2D_MAX_NUMBER_EDGES));
377 if (node->get_left_son())
378 traverse_multimesh_subtree(node->get_left_son(), running_central_transformations, running_neighbor_transformations,
379 edge_info, active_edge, mode);
380 if (node->get_right_son())
381 traverse_multimesh_subtree(node->get_right_son(), running_central_transformations, running_neighbor_transformations,
382 edge_info, active_edge, mode);
385 running_central_transformations.back()->pop_back();
386 running_neighbor_transformations.back()->pop_back();
392 template class HERMES_API MultimeshDGNeighborTree < double > ;
393 template class HERMES_API MultimeshDGNeighborTree < std::complex<double> > ;
static void process_edge(NeighborSearch< Scalar > **neighbor_searches, unsigned char num_neighbor_searches, unsigned int &num_neighbors, bool *&processed)
The main method, for the passed neighbor searches, it will process all multi-mesh neighbor consolidat...
Transformations ** central_transformations
Array of transformations of the central element to each neighbor.
#define H2D_MAX_NUMBER_EDGES
A maximum number of edges of an element.
This class characterizes a neighborhood of a given edge in terms of adjacent elements and provides me...