8 #include <unordered_set> 9 #include <boost/functional/hash.hpp> 25 template<
unsigned int dimA,
unsigned int dimB>
30 template<
unsigned int dimA,
unsigned int dimB>
31 template<
unsigned int simplex_dim>
34 ASSERT(simplex_dim == element->dim());
36 for(
unsigned int i=0; i < simplex_dim+1; i++)
37 field_of_points[i]= &(element->node[i]->point());
42 template<
unsigned int dim>
48 template<
unsigned int dim>
54 template<
unsigned int dim>
65 template<
unsigned int dim>
71 bool first_3d_element =
true;
78 first_3d_element =
false;
90 template<
unsigned int dim>
92 unsigned int bulk_ele_idx)
103 if(is.
points().size() > 0) {
114 template<
unsigned int dim>
136 template<
unsigned int dim>
146 unsigned int component_ele_idx = elm->index();
148 if (elm->dim() == dim &&
163 unsigned int bulk_ele_idx = *
it;
170 if (ele_3D->dim() == 3 &&
175 ASSERT_DBG(ele_3D->tetrahedron_jacobian() > 0).add_value(ele_3D->
index(),
"element index").error(
176 "Tetrahedron element (%d) has wrong numbering or is degenerated (negative Jacobian).");
204 unsigned int current_component_element_idx = component_ele_idx;
213 bool element_covered =
true;
222 element_covered =
false;
253 END_TIMER(
"Bounding box element iteration");
266 template<
unsigned int dim>
269 DebugOut() <<
"######### ALGORITHM: compute_intersections_BIHtree #########\n";
276 unsigned int component_ele_idx = elm->index();
278 if (elm->dim() == dim &&
293 unsigned int bulk_ele_idx = *
it;
296 if (ele_3D->dim() == 3
299 ASSERT_DBG(ele_3D->tetrahedron_jacobian() > 0).add_value(ele_3D->
index(),
"element index").error(
300 "Tetrahedron element (%d) has wrong numbering or is degenerated (negative Jacobian).");
311 if(is.
points().size() > 0) {
320 END_TIMER(
"Bounding box element iteration");
327 template<
unsigned int dim>
338 unsigned int component_ele_idx = elm->index();
340 if (elm->dim() == dim &&
350 unsigned int bulk_ele_idx = ele_3D.index();
357 if (ele_3D->dim() == 3 &&
363 ASSERT_DBG(ele_3D->tetrahedron_jacobian() > 0).add_value(ele_3D->index(),
"element index").error(
364 "Tetrahedron element (%d) has wrong numbering or is degenerated (negative Jacobian).");
392 unsigned int current_component_element_idx = component_ele_idx;
402 bool element_covered =
true;
411 element_covered =
false;
443 END_TIMER(
"Bounding box element iteration");
457 template<
unsigned int dim>
458 template<
unsigned int ele_dim>
461 unsigned int ip_obj_idx)
464 edges.reserve(ele_dim - ip_dim);
470 case 0:
if(ele_dim == 1) {
471 edges.push_back(&(
mesh->
edges[ele->edge_idx_[ip_obj_idx]]));
475 for(
unsigned int j=0; j < RefElement<ele_dim>::n_sides_per_node; j++){
477 edges.push_back(&(
mesh->
edges[ele->edge_idx_[local_edge]]));
483 case 1:
if(ele_dim == 2) {
484 edges.push_back(&(
mesh->
edges[ele->edge_idx_[ip_obj_idx]]));
489 for(
unsigned int j=0; j < RefElement<ele_dim>::n_sides_per_line; j++){
491 edges.push_back(&(
mesh->
edges[ele->edge_idx_[local_edge]]));
498 edges.push_back(&(
mesh->
edges[ele->edge_idx_[ip_obj_idx]]));
506 elements_idx.reserve(2*edges.size());
507 for(
Edge* edg : edges)
508 for(
int j=0; j < edg->n_sides;j++) {
509 if (edg->side(j)->element() != ele)
510 elements_idx.push_back(edg->side(j)->element()->index());
517 template<
unsigned int dim>
519 unsigned int component_ele_idx,
520 std::queue< Prolongation >& queue)
543 template<
unsigned int dim>
550 unsigned int n_ip_vertices = 0;
558 if(IP.dim_A() < dim) {
559 if(IP.dim_A() == 0) n_ip_vertices++;
570 unsigned int bulk_current = bulk_ele->
index();
573 for(
unsigned int& comp_neighbor_idx : comp_neighbors) {
591 unsigned int comp_current = comp_ele->
index();
592 unsigned int n_prolongations = 0;
594 for(
unsigned int& bulk_neighbor_idx : bulk_neighbors)
606 if(n_prolongations == 0)
628 ASSERT_DBG(0).add_value(bulk_ele_idx,
"bulk_ele_idx").error(
"Want to add the same intersection!");
634 template<
unsigned int dim>
693 ASSERT(storage.size() == 0);
696 unsigned int ele_idx, eleA_idx, eleB_idx,
697 componentA_idx, componentB_idx,
700 typedef std::pair<unsigned int, unsigned int> ipair;
701 std::unordered_set<ipair, boost::hash<ipair>> computed_pairs;
706 ele_idx = ele->index();
708 if(intersection_map[ele_idx].size() < 2)
continue;
713 for(
unsigned int i=0; i < local_map.size(); i++)
718 eleA_idx = local_map[i].first;
720 if(eleA->dim() !=2 )
continue;
726 for(
unsigned int j=i+1; j < local_map.size(); j++)
728 eleB_idx = local_map[j].first;
731 if(componentA_idx == componentB_idx)
continue;
735 if(eleB->dim() !=2 )
continue;
739 temp_eleA_idx = eleA_idx;
741 if (componentA_idx < componentB_idx){
747 ipair ip = std::make_pair(temp_eleA_idx, eleB_idx);
748 if(computed_pairs.count(ip) == 1){
754 computed_pairs.emplace(ip);
781 MessageOut() <<
"2D-2D: number of intersections = " << storage.size() <<
"\n";
800 unsigned int n_local_intersection = CI.compute(is);
803 if(n_local_intersection > 1){
815 std::queue<unsigned int> queue;
818 if (ele->dim() == 2 &&
822 queue.push(ele->index());
824 while(!queue.empty()){
825 unsigned int ele_idx = queue.front();
828 for(
unsigned int sid=0; sid < ele->n_sides(); sid++) {
829 Edge* edg = ele->side(sid)->edge();
831 for(
int j=0; j < edg->
n_sides;j++) {
835 queue.push(neigh_idx);
867 ASSERT(storage.size() == 0);
872 unsigned int ele_idx = ele->index();
874 if(intersection_map[ele_idx].size() < 2)
continue;
879 for(
unsigned int i=0; i < local_map.size(); i++)
884 unsigned int eleA_idx = local_map[i].first;
887 if(eleA->dim() !=1 )
continue;
889 for(
unsigned int j=0; j < local_map.size(); j++)
891 unsigned int eleB_idx = local_map[j].first;
893 if(eleB->dim() !=2 )
continue;
897 for(
unsigned int i=0; i<intersection_map[eleA_idx].size(); i++)
899 if(intersection_map[eleA_idx][i].first == eleB_idx) {
917 unsigned int n_local_intersection = CI.compute_final(is.
points());
919 if(n_local_intersection > 0)
922 intersection_map[eleA_idx].push_back(std::make_pair(
926 intersection_map[eleB_idx].push_back(std::make_pair(
938 MessageOut() <<
"2D-2D: number of intersections = " << storage.size() <<
"\n";
982 unsigned int component_ele_idx = elm->index();
999 unsigned int bulk_ele_idx = *
it;
1002 if (ele_2D->dim() == 2) {
1008 CI.compute_final(is.
points());
1011 if(is.
points().size() > 0) {
1016 END_TIMER(
"Bounding box element iteration");
IntersectionAlgorithmBase(Mesh *mesh)
void set_simplices(arma::vec3 **field_of_pointers_to_coordinates)
Creating sub-simplices in lexicografic order.
Classes with algorithms for computation of intersections of meshes.
std::vector< BoundingBox > elements_bb
Elements bounding boxes.
#define FOR_ELEMENTS(_mesh_, __i)
InspectElementsAlgorithm(Mesh *_mesh)
void prolongate(const Prolongation &pr)
Computes the intersection for a candidate in a queue and calls prolongation_decide again...
#define MessageOut()
Macro defining 'message' record of log.
void compute_intersections(std::vector< std::vector< ILpair >> &intersection_map, std::vector< IntersectionLocal< 1, 2 >> &storage)
Runs the algorithm (3): compute 1D-2D intersection inside 3D mesh. It directly fills the intersection...
void compute_single_intersection(const ElementFullIter &eleA, const ElementFullIter &eleB, std::vector< IntersectionLocal< 2, 2 >> &storage)
Computes fundamental intersection of two 2D elements.
Fundamental simplicial intersections.
bool intersection_exists(unsigned int component_ele_idx, unsigned int bulk_ele_idx)
A hard way to find whether the intersection of two elements has already been computed, or not.
std::vector< unsigned int > last_slave_for_3D_elements
void expand(const Point &point)
Auxiliary structure for prolongation process.
unsigned int size() const
Returns number of intersection points.
bool intersect(const BoundingBox &b2) const
unsigned int n_intersections_
Counter for intersection among elements.
InspectElementsAlgorithm22(Mesh *input_mesh)
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
#define ADD_CALLS(n_calls)
Increase number of calls in actual timer.
bool compute_initial_CI(unsigned int component_ele_idx, unsigned int bulk_ele_idx)
Computes the first intersection, from which we then prolongate.
unsigned int component_counter_
std::queue< Prolongation > component_queue_
Prolongation queue in the component mesh.
void compute_intersections_BIHtree(const BIHTree &bih)
Uses only BIHtree to find intersection candidates. (No prolongation).
std::vector< unsigned int > component_idx_
void assert_same_intersection(unsigned int comp_ele_idx, unsigned int bulk_ele_idx)
void compute_intersections(std::vector< std::vector< ILpair >> &intersection_map, std::vector< IntersectionLocal< 2, 2 >> &storage)
Runs the core algorithm for computing 2D-2D intersection in 3D.
unsigned int n_elements() const
std::vector< IntersectionAux< 1, 2 > > intersectionaux_storage12_
Stores temporarily 1D-2D intersections.
void find_bounding_box(const BoundingBox &boundingBox, std::vector< unsigned int > &result_list, bool full_list=false) const
std::vector< std::vector< IntersectionAux< dim, 3 > > > intersection_list_
Resulting vector of intersections.
const unsigned int undefined_elm_idx_
std::vector< unsigned int > get_element_neighbors(const ElementFullIter &ele, unsigned int ip_dim, unsigned int ip_obj_idx)
void create_component_numbering()
Creates numbering of the 2D components and fills component_idx_ vector.
unsigned int dictionary_idx
const BoundingBox & tree_box() const
static const IdxVector< (InDim >OutDim?InDim+1:dim-InDim) > interact(TInteraction< OutDim, InDim > interaction)
#define START_TIMER(tag)
Starts a timer with specified tag.
Class for O(log N) lookup for intersections with a set of bounding boxes.
std::vector< IntersectionPointAux< dimA, dimB > > & points()
Returns intersection points by a reference.
void swap(nlohmann::json &j1, nlohmann::json &j2) noexcept(is_nothrow_move_constructible< nlohmann::json >::value andis_nothrow_move_assignable< nlohmann::json >::value)
exchanges the values of two JSON objects
Simplex< dimA > simplexA
Objects representing single elements.
~InspectElementsAlgorithm()
unsigned int component_elm_idx
void compute_intersections_BB()
const unsigned int unset_comp
ElementFullIter element() const
void compute_intersections(const BIHTree &bih)
Uses BIHtree to find the initial candidate of a component and then prolongates the component interset...
std::vector< Edge > edges
Vector of MH edges, this should not be part of the geometrical mesh.
BoundingBox mesh_3D_bb
Bounding box of all 3D elements.
void prolongation_decide(const ElementFullIter &comp_ele, const ElementFullIter &bulk_ele, IntersectionAux< dim, 3 > is)
#define END_TIMER(tag)
Ends a timer with specified tag.
void compute_bounding_boxes()
Computes bounding boxes of all elements. Fills elements_bb and mesh_3D_bb.
Internal auxiliary class represents an intersection point of simplex<N> and simplex<M>.
Class RefElement defines numbering of vertices, sides, calculation of normal vectors etc...
void update_simplex(const ElementFullIter &element, Simplex< simplex_dim > &simplex)
Auxiliary function that translates ElementFullIter to Simplex<simplex_dim>.
void compute_intersections_2(const BIHTree &bih)
Runs the algorithm (2): compute 1D-2D intersection in 3D ambient space BIH is used to find intersecti...
Internal auxiliary class representing intersection object of simplex<dimA> and simplex<dimB>.
unsigned int create_prolongation(unsigned int bulk_ele_idx, unsigned int component_ele_idx, std::queue< Prolongation > &queue)
#define DebugOut()
Macro defining 'debug' record of log.
InspectElementsAlgorithm12(Mesh *input_mesh)
Internal class representing intersection point.
std::queue< Prolongation > bulk_queue_
Prolongation queue in the bulk mesh.
SideIter side(const unsigned int i) const
std::vector< bool > closed_elements
const BoundingBox & ele_bounding_box(unsigned int ele_idx) const
Gets bounding box of element of given index ele_index.
ElementVector element
Vector of elements of the mesh.
Internal class representing intersection object.