8 #include <unordered_set>
9 #include <boost/functional/hash.hpp>
27 template<
unsigned int dimA,
unsigned int dimB>
44 template<
unsigned int dim>
50 template<
unsigned int dim>
56 template<
unsigned int dim>
60 last_slave_for_3D_elements.assign(mesh->n_elements(), undefined_elm_idx_);
61 closed_elements.assign(mesh->n_elements(),
false);
67 template<
unsigned int dim>
71 if(elements_bb.size() == 0){
72 elements_bb.resize(mesh->n_elements());
73 bool first_3d_element =
true;
74 for (
auto elm : mesh->elements_range()) {
76 elements_bb[elm.idx()] = elm.bounding_box();
80 first_3d_element =
false;
81 mesh_3D_bb = elements_bb[elm.idx()];
83 mesh_3D_bb.expand(elements_bb[elm.idx()].min());
84 mesh_3D_bb.expand(elements_bb[elm.idx()].max());
92 template<
unsigned int dim>
96 unsigned int component_ele_idx = comp_ele.
idx(),
97 bulk_ele_idx = bulk_ele.
idx();
106 last_slave_for_3D_elements[bulk_ele_idx] = component_ele_idx;
108 if(is.
points().size() > 0) {
109 intersection_list_[component_ele_idx].push_back(is);
119 template<
unsigned int dim>
127 for(; i < intersection_list_[component_ele_idx].size();i++){
129 if(intersection_list_[component_ele_idx][i].bulk_ele_idx() == bulk_ele_idx){
141 template<
unsigned int dim>
150 for (
auto elm : mesh->elements_range()) {
151 unsigned int component_ele_idx = elm.idx();
153 if (elm->dim() == dim &&
154 !closed_elements[component_ele_idx] &&
168 unsigned int bulk_ele_idx = *
it;
175 if (ele_3D->
dim() == 3 &&
176 (last_slave_for_3D_elements[bulk_ele_idx] != component_ele_idx &&
177 !intersection_exists(component_ele_idx,bulk_ele_idx) )
181 "Tetrahedron element (%d) has wrong numbering or is degenerated (negative Jacobian).");
203 bool found = compute_initial_CI(elm, ele_3D);
206 unsigned int current_component_element_idx = component_ele_idx;
210 prolongation_decide(elm, ele_3D, intersection_list_[component_ele_idx].back());
215 bool element_covered =
true;
217 while(!bulk_queue_.empty()){
218 Prolongation pr = bulk_queue_.front();
221 if( pr.elm_3D_idx == undefined_elm_idx_)
224 element_covered =
false;
231 if(! closed_elements[current_component_element_idx])
232 closed_elements[current_component_element_idx] = element_covered;
235 if(!component_queue_.empty()){
236 Prolongation pr = component_queue_.front();
239 current_component_element_idx = pr.component_elm_idx;
243 component_queue_.pop();
246 while( !(component_queue_.empty() && bulk_queue_.empty()) );
250 if(closed_elements[component_ele_idx])
255 END_TIMER(
"Bounding box element iteration");
261 MessageOut().fmt(
"{}D-3D: number of intersections = {}\n", dim, n_intersections_);
268 template<
unsigned int dim>
271 DebugOut() <<
"######### ALGORITHM: compute_intersections_BIHtree #########\n";
277 for (
auto elm : mesh->elements_range()) {
278 unsigned int component_ele_idx = elm.idx();
280 if (elm.dim() == dim &&
294 unsigned int bulk_ele_idx = *
it;
297 if (ele_3D.
dim() == 3
301 "Tetrahedron element (%d) has wrong numbering or is degenerated (negative Jacobian).");
310 if(is.
points().size() > 0) {
312 intersection_list_[component_ele_idx].push_back(is);
315 closed_elements[component_ele_idx] =
true;
319 END_TIMER(
"Bounding box element iteration");
326 template<
unsigned int dim>
331 compute_bounding_boxes();
336 for (
auto elm : mesh->elements_range()) {
337 unsigned int component_ele_idx = elm.idx();
339 if (elm.dim() == dim &&
340 !closed_elements[component_ele_idx] &&
341 elements_bb[component_ele_idx].intersect(mesh_3D_bb))
347 for (
auto ele_3D : mesh->elements_range()) {
348 unsigned int bulk_ele_idx = ele_3D.idx();
355 if (ele_3D.dim() == 3 &&
356 (last_slave_for_3D_elements[bulk_ele_idx] != component_ele_idx &&
357 elements_bb[component_ele_idx].intersect(elements_bb[bulk_ele_idx]) &&
358 !intersection_exists(component_ele_idx,bulk_ele_idx) )
361 ASSERT_DBG(ele_3D.tetrahedron_jacobian() > 0).add_value(ele_3D.index(),
"element index").error(
362 "Tetrahedron element (%d) has wrong numbering or is degenerated (negative Jacobian).");
384 bool found = compute_initial_CI(elm, ele_3D);
387 unsigned int current_component_element_idx = component_ele_idx;
392 prolongation_decide(elm, ele_3D, intersection_list_[component_ele_idx].back());
397 bool element_covered =
true;
399 while(!bulk_queue_.empty()){
400 Prolongation pr = bulk_queue_.front();
403 if( pr.elm_3D_idx == undefined_elm_idx_)
406 element_covered =
false;
413 if(! closed_elements[current_component_element_idx])
414 closed_elements[current_component_element_idx] = element_covered;
417 if(!component_queue_.empty()){
418 Prolongation pr = component_queue_.front();
421 current_component_element_idx = pr.component_elm_idx;
425 component_queue_.pop();
428 while( !(component_queue_.empty() && bulk_queue_.empty()) );
432 if(closed_elements[component_ele_idx])
438 END_TIMER(
"Bounding box element iteration");
452 template<
unsigned int dim>
453 template<
unsigned int ele_dim>
456 unsigned int ip_obj_idx)
459 edges.reserve(ele_dim - ip_dim);
465 case 0:
if(ele_dim == 1) {
466 edges.push_back(mesh->edge(ele->
edge_idx(ip_obj_idx)));
470 for(
unsigned int j=0; j < RefElement<ele_dim>::n_sides_per_node; j++){
472 edges.push_back(mesh->edge(ele->
edge_idx(local_edge)));
478 case 1:
if(ele_dim == 2) {
479 edges.push_back(mesh->edge(ele->
edge_idx(ip_obj_idx)));
484 for(
unsigned int j=0; j < RefElement<ele_dim>::n_sides_per_line; j++){
486 edges.push_back(mesh->edge(ele->
edge_idx(local_edge)));
493 edges.push_back(mesh->edge(ele->
edge_idx(ip_obj_idx)));
501 elements_idx.reserve(2*edges.size());
502 for(
Edge edg : edges)
503 for(
uint j=0; j < edg.n_sides();j++) {
504 if ( edg.side(j)->element().idx() != ele.
idx() )
505 elements_idx.push_back(edg.side(j)->element().idx());
512 template<
unsigned int dim>
514 unsigned int component_ele_idx,
515 std::queue< Prolongation >& queue)
520 last_slave_for_3D_elements[bulk_ele_idx] = component_ele_idx;
526 intersection_list_[component_ele_idx].push_back(il_other);
528 Prolongation pr = {component_ele_idx, bulk_ele_idx, (
unsigned int)intersection_list_[component_ele_idx].size() - 1};
538 template<
unsigned int dim>
545 unsigned int n_ip_vertices = 0;
580 if(IP.dim_A() < dim) {
581 if(IP.dim_A() == 0) n_ip_vertices++;
592 unsigned int bulk_current = bulk_ele.
idx();
595 for(
unsigned int& comp_neighbor_idx : comp_neighbors) {
596 if(!intersection_exists(comp_neighbor_idx,bulk_current))
597 create_prolongation(bulk_current, comp_neighbor_idx, component_queue_);
613 unsigned int comp_current = comp_ele.
idx();
614 unsigned int n_prolongations = 0;
616 for(
unsigned int& bulk_neighbor_idx : bulk_neighbors)
618 if(last_slave_for_3D_elements[bulk_neighbor_idx] == undefined_elm_idx_ ||
619 (last_slave_for_3D_elements[bulk_neighbor_idx] != comp_current &&
620 !intersection_exists(comp_current,bulk_neighbor_idx)))
621 n_prolongations += create_prolongation(bulk_neighbor_idx,
628 if(n_prolongations == 0)
630 Prolongation pr = {comp_ele.
idx(), undefined_elm_idx_, undefined_elm_idx_};
631 bulk_queue_.push(pr);
637 if(n_ip_vertices == is.
size()) closed_elements[comp_ele.
idx()] =
true;
650 ASSERT_DBG(0).add_value(bulk_ele_idx,
"bulk_ele_idx").error(
"Want to add the same intersection!");
656 template<
unsigned int dim>
688 prolongation_decide(elm, ele_3D,is);
715 ASSERT(storage.size() == 0);
718 unsigned int ele_idx, eleA_idx, eleB_idx,
719 componentA_idx, componentB_idx,
722 typedef std::pair<unsigned int, unsigned int> ipair;
723 std::unordered_set<ipair, boost::hash<ipair>> computed_pairs;
730 if(intersection_map[ele_idx].size() < 2)
continue;
735 for(
unsigned int i=0; i < local_map.size(); i++)
740 eleA_idx = local_map[i].first;
742 if(eleA->
dim() !=2 )
continue;
748 for(
unsigned int j=i+1; j < local_map.size(); j++)
750 eleB_idx = local_map[j].first;
753 if(componentA_idx == componentB_idx)
continue;
757 if(eleB->
dim() !=2 )
continue;
761 temp_eleA_idx = eleA_idx;
763 if (componentA_idx < componentB_idx){
769 ipair ip = std::make_pair(temp_eleA_idx, eleB_idx);
770 if(computed_pairs.count(ip) == 1){
776 computed_pairs.emplace(ip);
803 MessageOut() <<
"2D-2D: number of intersections = " << storage.size() <<
"\n";
819 unsigned int n_local_intersection = CI.
compute(is);
822 if(n_local_intersection > 1){
834 std::queue<unsigned int> queue;
837 if (ele->dim() == 2 &&
841 queue.push(ele.idx());
843 while(!queue.empty()){
844 unsigned int ele_idx = queue.front();
847 for(
unsigned int sid=0; sid < elm->
n_sides(); sid++) {
854 queue.push(neigh_idx);
887 ASSERT(storage.size() == 0);
892 unsigned int ele_idx = ele.idx();
894 if(intersection_map[ele_idx].size() < 2)
continue;
899 for(
unsigned int i=0; i < local_map.size(); i++)
904 unsigned int eleA_idx = local_map[i].first;
907 if(eleA.
dim() !=1 )
continue;
909 for(
unsigned int j=0; j < local_map.size(); j++)
911 unsigned int eleB_idx = local_map[j].first;
913 if(eleB.
dim() !=2 )
continue;
917 for(
unsigned int i=0; i<intersection_map[eleA_idx].size(); i++)
919 if(intersection_map[eleA_idx][i].first == eleB_idx) {
936 if(n_local_intersection > 0)
939 intersection_map[eleA_idx].push_back(std::make_pair(
943 intersection_map[eleB_idx].push_back(std::make_pair(
955 MessageOut() <<
"1D-2D [3]: number of intersections = " << storage.size() <<
"\n";
999 unsigned int component_ele_idx = elm.idx();
1015 unsigned int bulk_ele_idx = *
it;
1018 if (ele_2D.
dim() == 2) {
1026 if(is.
points().size() > 0) {
1031 END_TIMER(
"Bounding box element iteration");
1045 unsigned int component_ele_idx = elm.idx();
1047 if (elm->dim() == 1)
1056 for(
unsigned int bulk_ele_idx : candidate_list) {
1059 if (ele_2D->
dim() == 2) {
1067 if(is.
points().size() > 0) {
1072 END_TIMER(
"Bounding box element iteration");