8 #include <unordered_set>
9 #include <boost/functional/hash.hpp>
28 template<
unsigned int dimA,
unsigned int dimB>
45 template<
unsigned int dim>
51 template<
unsigned int dim>
57 template<
unsigned int dim>
61 last_slave_for_3D_elements.assign(mesh->n_elements(), undefined_elm_idx_);
62 closed_elements.assign(mesh->n_elements(),
false);
68 template<
unsigned int dim>
72 if(elements_bb.size() == 0){
73 elements_bb.resize(mesh->n_elements());
74 bool first_3d_element =
true;
75 for (
auto elm : mesh->elements_range()) {
77 elements_bb[elm.idx()] = elm.bounding_box();
81 first_3d_element =
false;
82 mesh_3D_bb = elements_bb[elm.idx()];
84 mesh_3D_bb.expand(elements_bb[elm.idx()].min());
85 mesh_3D_bb.expand(elements_bb[elm.idx()].max());
93 template<
unsigned int dim>
97 unsigned int component_ele_idx = comp_ele.
idx(),
98 bulk_ele_idx = bulk_ele.
idx();
107 last_slave_for_3D_elements[bulk_ele_idx] = component_ele_idx;
109 if(is.
points().size() > 0) {
110 intersection_list_[component_ele_idx].push_back(is);
120 template<
unsigned int dim>
128 for(; i < intersection_list_[component_ele_idx].size();i++){
130 if(intersection_list_[component_ele_idx][i].bulk_ele_idx() == bulk_ele_idx){
142 template<
unsigned int dim>
151 for (
auto elm : mesh->elements_range()) {
152 unsigned int component_ele_idx = elm.idx();
154 if (elm->dim() == dim &&
155 !closed_elements[component_ele_idx] &&
169 unsigned int bulk_ele_idx = *
it;
176 if (ele_3D->
dim() == 3 &&
177 (last_slave_for_3D_elements[bulk_ele_idx] != component_ele_idx &&
178 !intersection_exists(component_ele_idx,bulk_ele_idx) )
182 "Tetrahedron element (%d) has wrong numbering or is degenerated (negative Jacobian).");
204 bool found = compute_initial_CI(elm, ele_3D);
207 unsigned int current_component_element_idx = component_ele_idx;
211 prolongation_decide(elm, ele_3D, intersection_list_[component_ele_idx].back());
216 bool element_covered =
true;
218 while(!bulk_queue_.empty()){
219 Prolongation pr = bulk_queue_.front();
222 if( pr.elm_3D_idx == undefined_elm_idx_)
225 element_covered =
false;
232 if(! closed_elements[current_component_element_idx])
233 closed_elements[current_component_element_idx] = element_covered;
236 if(!component_queue_.empty()){
237 Prolongation pr = component_queue_.front();
240 current_component_element_idx = pr.component_elm_idx;
244 component_queue_.pop();
247 while( !(component_queue_.empty() && bulk_queue_.empty()) );
251 if(closed_elements[component_ele_idx])
256 END_TIMER(
"Bounding box element iteration");
262 MessageOut().fmt(
"{}D-3D: number of intersections = {}\n", dim, n_intersections_);
269 template<
unsigned int dim>
272 DebugOut() <<
"######### ALGORITHM: compute_intersections_BIHtree #########\n";
278 for (
auto elm : mesh->elements_range()) {
279 unsigned int component_ele_idx = elm.idx();
281 if (elm.dim() == dim &&
295 unsigned int bulk_ele_idx = *
it;
298 if (ele_3D.
dim() == 3
302 "Tetrahedron element (%d) has wrong numbering or is degenerated (negative Jacobian).");
311 if(is.
points().size() > 0) {
313 intersection_list_[component_ele_idx].push_back(is);
316 closed_elements[component_ele_idx] =
true;
320 END_TIMER(
"Bounding box element iteration");
327 template<
unsigned int dim>
332 compute_bounding_boxes();
337 for (
auto elm : mesh->elements_range()) {
338 unsigned int component_ele_idx = elm.idx();
340 if (elm.dim() == dim &&
341 !closed_elements[component_ele_idx] &&
342 elements_bb[component_ele_idx].intersect(mesh_3D_bb))
348 for (
auto ele_3D : mesh->elements_range()) {
349 unsigned int bulk_ele_idx = ele_3D.idx();
356 if (ele_3D.dim() == 3 &&
357 (last_slave_for_3D_elements[bulk_ele_idx] != component_ele_idx &&
358 elements_bb[component_ele_idx].intersect(elements_bb[bulk_ele_idx]) &&
359 !intersection_exists(component_ele_idx,bulk_ele_idx) )
362 ASSERT_DBG(ele_3D.tetrahedron_jacobian() > 0).add_value(ele_3D.index(),
"element index").error(
363 "Tetrahedron element (%d) has wrong numbering or is degenerated (negative Jacobian).");
385 bool found = compute_initial_CI(elm, ele_3D);
388 unsigned int current_component_element_idx = component_ele_idx;
393 prolongation_decide(elm, ele_3D, intersection_list_[component_ele_idx].back());
398 bool element_covered =
true;
400 while(!bulk_queue_.empty()){
401 Prolongation pr = bulk_queue_.front();
404 if( pr.elm_3D_idx == undefined_elm_idx_)
407 element_covered =
false;
414 if(! closed_elements[current_component_element_idx])
415 closed_elements[current_component_element_idx] = element_covered;
418 if(!component_queue_.empty()){
419 Prolongation pr = component_queue_.front();
422 current_component_element_idx = pr.component_elm_idx;
426 component_queue_.pop();
429 while( !(component_queue_.empty() && bulk_queue_.empty()) );
433 if(closed_elements[component_ele_idx])
439 END_TIMER(
"Bounding box element iteration");
453 template<
unsigned int dim>
454 template<
unsigned int ele_dim>
457 unsigned int ip_obj_idx)
460 edges.reserve(ele_dim - ip_dim);
466 case 0:
if(ele_dim == 1) {
467 edges.push_back(&(mesh->edges[ele->
edge_idx(ip_obj_idx)]));
471 for(
unsigned int j=0; j < RefElement<ele_dim>::n_sides_per_node; j++){
473 edges.push_back(&(mesh->edges[ele->
edge_idx(local_edge)]));
479 case 1:
if(ele_dim == 2) {
480 edges.push_back(&(mesh->edges[ele->
edge_idx(ip_obj_idx)]));
485 for(
unsigned int j=0; j < RefElement<ele_dim>::n_sides_per_line; j++){
487 edges.push_back(&(mesh->edges[ele->
edge_idx(local_edge)]));
494 edges.push_back(&(mesh->edges[ele->
edge_idx(ip_obj_idx)]));
502 elements_idx.reserve(2*edges.size());
503 for(
Edge* edg : edges)
504 for(
int j=0; j < edg->n_sides;j++) {
505 if ( edg->side(j)->element().idx() != ele.
idx() )
506 elements_idx.push_back(edg->side(j)->element().idx());
513 template<
unsigned int dim>
515 unsigned int component_ele_idx,
516 std::queue< Prolongation >& queue)
521 last_slave_for_3D_elements[bulk_ele_idx] = component_ele_idx;
527 intersection_list_[component_ele_idx].push_back(il_other);
529 Prolongation pr = {component_ele_idx, bulk_ele_idx, (
unsigned int)intersection_list_[component_ele_idx].size() - 1};
539 template<
unsigned int dim>
546 unsigned int n_ip_vertices = 0;
581 if(IP.dim_A() < dim) {
582 if(IP.dim_A() == 0) n_ip_vertices++;
593 unsigned int bulk_current = bulk_ele.
idx();
596 for(
unsigned int& comp_neighbor_idx : comp_neighbors) {
597 if(!intersection_exists(comp_neighbor_idx,bulk_current))
598 create_prolongation(bulk_current, comp_neighbor_idx, component_queue_);
614 unsigned int comp_current = comp_ele.
idx();
615 unsigned int n_prolongations = 0;
617 for(
unsigned int& bulk_neighbor_idx : bulk_neighbors)
619 if(last_slave_for_3D_elements[bulk_neighbor_idx] == undefined_elm_idx_ ||
620 (last_slave_for_3D_elements[bulk_neighbor_idx] != comp_current &&
621 !intersection_exists(comp_current,bulk_neighbor_idx)))
622 n_prolongations += create_prolongation(bulk_neighbor_idx,
629 if(n_prolongations == 0)
631 Prolongation pr = {comp_ele.
idx(), undefined_elm_idx_, undefined_elm_idx_};
632 bulk_queue_.push(pr);
638 if(n_ip_vertices == is.
size()) closed_elements[comp_ele.
idx()] =
true;
651 ASSERT_DBG(0).add_value(bulk_ele_idx,
"bulk_ele_idx").error(
"Want to add the same intersection!");
657 template<
unsigned int dim>
689 prolongation_decide(elm, ele_3D,is);
716 ASSERT(storage.size() == 0);
719 unsigned int ele_idx, eleA_idx, eleB_idx,
720 componentA_idx, componentB_idx,
723 typedef std::pair<unsigned int, unsigned int> ipair;
724 std::unordered_set<ipair, boost::hash<ipair>> computed_pairs;
731 if(intersection_map[ele_idx].size() < 2)
continue;
736 for(
unsigned int i=0; i < local_map.size(); i++)
741 eleA_idx = local_map[i].first;
743 if(eleA->
dim() !=2 )
continue;
749 for(
unsigned int j=i+1; j < local_map.size(); j++)
751 eleB_idx = local_map[j].first;
754 if(componentA_idx == componentB_idx)
continue;
758 if(eleB->
dim() !=2 )
continue;
762 temp_eleA_idx = eleA_idx;
764 if (componentA_idx < componentB_idx){
770 ipair ip = std::make_pair(temp_eleA_idx, eleB_idx);
771 if(computed_pairs.count(ip) == 1){
777 computed_pairs.emplace(ip);
804 MessageOut() <<
"2D-2D: number of intersections = " << storage.size() <<
"\n";
820 unsigned int n_local_intersection = CI.
compute(is);
823 if(n_local_intersection > 1){
835 std::queue<unsigned int> queue;
838 if (ele->dim() == 2 &&
842 queue.push(ele.idx());
844 while(!queue.empty()){
845 unsigned int ele_idx = queue.front();
848 for(
unsigned int sid=0; sid < elm->
n_sides(); sid++) {
851 for(
int j=0; j < edg->
n_sides;j++) {
855 queue.push(neigh_idx);
888 ASSERT(storage.size() == 0);
893 unsigned int ele_idx = ele.idx();
895 if(intersection_map[ele_idx].size() < 2)
continue;
900 for(
unsigned int i=0; i < local_map.size(); i++)
905 unsigned int eleA_idx = local_map[i].first;
908 if(eleA.
dim() !=1 )
continue;
910 for(
unsigned int j=0; j < local_map.size(); j++)
912 unsigned int eleB_idx = local_map[j].first;
914 if(eleB.
dim() !=2 )
continue;
918 for(
unsigned int i=0; i<intersection_map[eleA_idx].size(); i++)
920 if(intersection_map[eleA_idx][i].first == eleB_idx) {
937 if(n_local_intersection > 0)
940 intersection_map[eleA_idx].push_back(std::make_pair(
944 intersection_map[eleB_idx].push_back(std::make_pair(
956 MessageOut() <<
"1D-2D [3]: number of intersections = " << storage.size() <<
"\n";
1000 unsigned int component_ele_idx = elm.idx();
1016 unsigned int bulk_ele_idx = *
it;
1019 if (ele_2D.
dim() == 2) {
1027 if(is.
points().size() > 0) {
1032 END_TIMER(
"Bounding box element iteration");
1046 unsigned int component_ele_idx = elm.idx();
1048 if (elm->dim() == 1)
1057 for(
unsigned int bulk_ele_idx : candidate_list) {
1060 if (ele_2D->
dim() == 2) {
1068 if(is.
points().size() > 0) {
1073 END_TIMER(
"Bounding box element iteration");