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>
67 template<
unsigned int dim>
73 bool first_3d_element =
true;
80 first_3d_element =
false;
92 template<
unsigned int dim>
96 unsigned int component_ele_idx = comp_ele.
idx(),
97 bulk_ele_idx = bulk_ele.
idx();
108 if(is.
points().size() > 0) {
119 template<
unsigned int dim>
141 template<
unsigned int dim>
151 unsigned int component_ele_idx = elm.idx();
153 if (elm->dim() == dim &&
168 unsigned int bulk_ele_idx = *
it;
175 if (ele_3D->
dim() == 3 &&
181 "Tetrahedron element (%d) has wrong numbering or is degenerated (negative Jacobian).");
206 unsigned int current_component_element_idx = component_ele_idx;
215 bool element_covered =
true;
224 element_covered =
false;
255 END_TIMER(
"Bounding box element iteration");
268 template<
unsigned int dim>
271 DebugOut() <<
"######### ALGORITHM: compute_intersections_BIHtree #########\n";
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) {
319 END_TIMER(
"Bounding box element iteration");
326 template<
unsigned int dim>
337 unsigned int component_ele_idx = elm.idx();
339 if (elm.dim() == dim &&
348 unsigned int bulk_ele_idx = ele_3D.idx();
355 if (ele_3D.dim() == 3 &&
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).");
387 unsigned int current_component_element_idx = component_ele_idx;
397 bool element_covered =
true;
406 element_covered =
false;
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) {
470 for(
unsigned int j=0; j < RefElement<ele_dim>::n_sides_per_node; j++){
478 case 1:
if(ele_dim == 2) {
484 for(
unsigned int j=0; j < RefElement<ele_dim>::n_sides_per_line; j++){
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)
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) {
613 unsigned int comp_current = comp_ele.
idx();
614 unsigned int n_prolongations = 0;
616 for(
unsigned int& bulk_neighbor_idx : bulk_neighbors)
628 if(n_prolongations == 0)
650 ASSERT_DBG(0).add_value(bulk_ele_idx,
"bulk_ele_idx").error(
"Want to add the same intersection!");
656 template<
unsigned int dim>
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");
unsigned int n_sides() const
Returns number of sides aligned with the edge.
IntersectionAlgorithmBase(Mesh *mesh)
Classes with algorithms for computation of intersections of meshes.
std::vector< BoundingBox > elements_bb
Elements bounding boxes.
Edge edge() const
Returns pointer to the edge connected to the side.
InspectElementsAlgorithm(Mesh *_mesh)
std::vector< unsigned int > get_element_neighbors(const ElementAccessor< 3 > &ele, unsigned int ip_dim, unsigned int ip_obj_idx)
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.
Mesh * mesh
Auxiliary function that translates ElementAccessor<3> to Simplex<simplex_dim>.
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.
void prolongation_decide(const ElementAccessor< 3 > &comp_ele, const ElementAccessor< 3 > &bulk_ele, IntersectionAux< dim, 3 > &is)
SideIter side(const unsigned int loc_index)
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...
unsigned int compute_final_in_plane(std::vector< IPAux12 > &IP12s)
#define ADD_CALLS(n_calls)
Increase number of calls in actual timer.
unsigned int component_counter_
std::queue< Prolongation > component_queue_
Prolongation queue in the component mesh.
ElementAccessor< 3 > element() const
Returns iterator to the element of the side.
void compute_intersections_BIHtree(const BIHTree &bih)
Uses only BIHtree to find intersection candidates. (No prolongation).
std::vector< unsigned int > component_idx_
virtual ElementAccessor< 3 > element_accessor(unsigned int idx) const
Create and return ElementAccessor to element of given 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.
void set_duplicities(unsigned int n_duplicities)
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
void compute_intersections_3(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 ElementAccessor< 3 > &eleA, const ElementAccessor< 3 > &eleB, std::vector< IntersectionLocal< 2, 2 >> &storage)
Computes fundamental intersection of two 2D elements.
std::vector< std::vector< IntersectionAux< dim, 3 > > > intersection_list_
Resulting vector of intersections.
const unsigned int undefined_elm_idx_
void create_component_numbering()
Creates numbering of the 2D components and fills component_idx_ vector.
unsigned int dictionary_idx
unsigned int index() const
unsigned int edge_idx(unsigned int edg_idx) const
Return edge_idx of given index.
const BoundingBox & tree_box() const
unsigned int n_sides() 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.
Class for 1D-2D intersections.
virtual Range< ElementAccessor< 3 > > elements_range() const
Returns range of bulk elements.
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
Class for 2D-2D intersections.
unsigned int compute_final(std::vector< IPAux12 > &IP12s)
~InspectElementsAlgorithm()
unsigned int component_elm_idx
void compute_intersections_BB()
virtual unsigned int n_elements(bool boundary=false) const
Returns count of boundary or bulk elements.
const unsigned int unset_comp
bool compute_initial_CI(const ElementAccessor< 3 > &comp_ele, const ElementAccessor< 3 > &bulk_ele)
Computes the first intersection, from which we then prolongate.
void compute_intersections(const BIHTree &bih)
Uses BIHtree to find the initial candidate of a component and then prolongates the component interset...
BoundingBox mesh_3D_bb
Bounding box of all 3D elements.
#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.
double tetrahedron_jacobian() const
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...
Edge edge(uint edge_idx) const
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...
void compute_intersections_1(const BIHTree &bih)
Runs the algorithm (1): compute 1D-2D intersection in 2D plane. BIH is used to find intersection cand...
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)
unsigned int n_neighs_vb() const
Return number of neighbours.
#define DebugOut()
Macro defining 'debug' record of log.
InspectElementsAlgorithm12(Mesh *input_mesh)
unsigned int idx() const
Return local idx of element in boundary / bulk part of element vector.
Internal class representing intersection point.
std::queue< Prolongation > bulk_queue_
Prolongation queue in the bulk mesh.
SideIter side(const unsigned int i) const
Gets side iterator of the i -th side.
Implementation of range helper class.
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.
unsigned int ips_in_face() const
Returns idx of face when all IPs lie on it; -1 otherwise.
Internal class representing intersection object.