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>
68 template<
unsigned int dim>
74 bool first_3d_element =
true;
81 first_3d_element =
false;
93 template<
unsigned int dim>
97 unsigned int component_ele_idx = comp_ele.
idx(),
98 bulk_ele_idx = bulk_ele.
idx();
109 if(is.
points().size() > 0) {
120 template<
unsigned int dim>
142 template<
unsigned int dim>
152 unsigned int component_ele_idx = elm.idx();
154 if (elm->dim() == dim &&
169 unsigned int bulk_ele_idx = *
it;
176 if (ele_3D->
dim() == 3 &&
182 "Tetrahedron element (%d) has wrong numbering or is degenerated (negative Jacobian).");
207 unsigned int current_component_element_idx = component_ele_idx;
216 bool element_covered =
true;
225 element_covered =
false;
256 END_TIMER(
"Bounding box element iteration");
269 template<
unsigned int dim>
272 DebugOut() <<
"######### ALGORITHM: compute_intersections_BIHtree #########\n";
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) {
320 END_TIMER(
"Bounding box element iteration");
327 template<
unsigned int dim>
338 unsigned int component_ele_idx = elm.idx();
340 if (elm.dim() == dim &&
349 unsigned int bulk_ele_idx = ele_3D.idx();
356 if (ele_3D.dim() == 3 &&
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).");
388 unsigned int current_component_element_idx = component_ele_idx;
398 bool element_covered =
true;
407 element_covered =
false;
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) {
471 for(
unsigned int j=0; j < RefElement<ele_dim>::n_sides_per_node; j++){
479 case 1:
if(ele_dim == 2) {
485 for(
unsigned int j=0; j < RefElement<ele_dim>::n_sides_per_line; j++){
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)
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) {
614 unsigned int comp_current = comp_ele.
idx();
615 unsigned int n_prolongations = 0;
617 for(
unsigned int& bulk_neighbor_idx : bulk_neighbors)
629 if(n_prolongations == 0)
651 ASSERT_DBG(0).add_value(bulk_ele_idx,
"bulk_ele_idx").error(
"Want to add the same intersection!");
657 template<
unsigned int dim>
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");
const Edge * edge() const
IntersectionAlgorithmBase(Mesh *mesh)
Classes with algorithms for computation of intersections of meshes.
std::vector< BoundingBox > elements_bb
Elements bounding boxes.
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
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...
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.
#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...
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
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.