40 std::string filename =
"meshes/3D/tests/output/patch_mesh_A_" + std::to_string(patch_counter) +
"_" + std::to_string(
m_rank);
42 filename =
"meshes/3D/tests/output/patch_mesh_B_" + std::to_string(patch_counter) +
"_" + std::to_string(
m_rank);
54 m_perf_log.push(
"Preamble",
"Brute force algorithm");
63 bool bDoIntersect =
false;
68 std::unordered_set<unsigned int>::iterator it_patch_A;
69 std::unordered_set<unsigned int>::iterator it_patch_B;
73 int nbOfPositiveTests = 0;
75 m_perf_log.pop(
"Preamble",
"Brute force algorithm");
77 for( it_patch_A = Patch_Set_A.begin();
78 it_patch_A != Patch_Set_A.end();
81 const libMesh::Elem * elem_A =
m_Mesh_A.elem(*it_patch_A);
83 for( it_patch_B = Patch_Set_B.begin();
84 it_patch_B != Patch_Set_B.end();
87 m_perf_log.push(
"Find intersection",
"Brute force algorithm");
89 const libMesh::Elem * elem_B =
m_Mesh_B.elem(*it_patch_B);
92 m_perf_log.pop(
"Find intersection",
"Brute force algorithm");
106 unsigned int query_idx = Query_elem->id();
111 std::cout <<
" DEBUG: brute force search results" << std::endl;
112 std::cout <<
" -> Positives / tests : " << nbOfPositiveTests <<
" / " << nbOfTests
113 <<
" (" << 100.*nbOfPositiveTests/nbOfTests <<
"%)" << std::endl << std::endl;
128 std::pair<unsigned int,unsigned int> & First_intersection)
131 libMesh::ReplicatedMesh& Mesh_patch_guide = Patch_guide->
patch_mesh();
132 libMesh::ReplicatedMesh& Mesh_patch_probed = Patch_probed->
patch_mesh();
135 std::unique_ptr<libMesh::PointLocatorBase> Patch_guide_Locator = Mesh_patch_guide.sub_point_locator();
139 Patch_guide_Locator->enable_out_of_mesh_mode();
142 libMesh::Elem * Patch_probed_first_elem = NULL;
143 unsigned int Patch_probed_first_elem_id = 0;
146 std::set<unsigned int> Intersecting_guide_elems;
147 bool bFoundIntersection =
false;
148 for(libMesh::ReplicatedMesh::element_iterator element_probed_it = Mesh_patch_probed.elements_begin();
149 element_probed_it != Mesh_patch_probed.elements_end();
152 Patch_probed_first_elem = * element_probed_it;
155 if(bFoundIntersection)
162 libMesh::Elem * Patch_guide_first_elem = NULL;
163 unsigned int Patch_guide_first_elem_id;
164 bool bFoundFirstInter =
false;
166 for(std::set<unsigned int>::iterator it_inter = Intersecting_guide_elems.begin();
167 it_inter != Intersecting_guide_elems.end();
170 Patch_guide_first_elem = Mesh_patch_guide.elem(*it_inter);
178 First_intersection.first = Patch_guide_first_elem_id;
179 First_intersection.second = Patch_probed_first_elem_id;
184 if(!bFoundFirstInter)
199 std::pair<unsigned int,unsigned int> & First_intersection)
201 bool bFoundFirstInter =
false;
202 std::unordered_set<unsigned int> & Patch_Set_Guide = Patch_guide->
elem_indexes();
203 std::unordered_set<unsigned int> & Patch_Set_Probed = Patch_probed->
elem_indexes();
205 libMesh::ReplicatedMesh& Mesh_patch_guide = Patch_guide->
patch_mesh();
206 libMesh::ReplicatedMesh& Mesh_patch_probed = Patch_probed->
patch_mesh();
208 std::unordered_set<unsigned int>::iterator it_patch_Guide;
209 std::unordered_set<unsigned int>::iterator it_patch_Probed;
211 for( it_patch_Guide = Patch_Set_Guide.begin();
212 it_patch_Guide != Patch_Set_Guide.end();
215 const libMesh::Elem * elem_Guide = Mesh_patch_guide.elem(*it_patch_Guide);
217 for( it_patch_Probed = Patch_Set_Probed.begin();
218 it_patch_Probed != Patch_Set_Probed.end();
221 const libMesh::Elem * elem_Probed = Mesh_patch_probed.elem(*it_patch_Probed);
227 First_intersection.first = *it_patch_Guide;
228 First_intersection.second = *it_patch_Probed;
234 homemade_assert_msg(bFoundFirstInter,
"Could't find a first intersecting pair. Are you sure that the patches do intersect?\n");
243 m_perf_log.push(
"Preamble",
"Advancing front algorithm");
259 bool bGuidedByB = Patch_guide->
size() > Patch_probed->
size();
264 std::cout <<
" DEBUG: Probe: A | Guide: B" << std::endl;
273 std::cout <<
" DEBUG: Probe: B | Guide: A" << std::endl;
278 unsigned int Guide_working_elem_id;
279 unsigned int Probed_working_elem_id;
282 std::pair<unsigned int,unsigned int> First_intersection;
286 unsigned int guide_neighbor_index = 0;
287 std::unordered_set<unsigned int>::iterator it_neigh, it_neigh_end;
290 bool bDoIntersect =
false;
293 bool bDoNeighborIntersect =
false;
297 bool bDoTestGuideNeighbours =
true;
309 int nbOfGuideElemsTested = 0;
311 int nbOfPositiveTests = 0;
313 bool bCreateNewNefForGuideNeigh =
true;
315 m_perf_log.pop(
"Preamble",
"Advancing front algorithm");
319 m_perf_log.push(
"Set up new guide element",
"Advancing front algorithm");
328 ++nbOfGuideElemsTested;
340 m_perf_log.pop(
"Set up new guide element",
"Advancing front algorithm");
344 m_perf_log.push(
"Find intersection",
"Advancing front algorithm");
354 m_perf_log.pop(
"Find intersection",
"Advancing front algorithm");
374 m_perf_log.push(
"Update test queue",
"Advancing front algorithm");
377 m_perf_log.pop(
"Update test queue",
"Advancing front algorithm");
379 m_perf_log.push(
"Update intersection queue",
"Advancing front algorithm");
382 if(bDoTestGuideNeighbours)
387 bCreateNewNefForGuideNeigh =
true;
389 for( ; it_neigh != it_neigh_end; ++it_neigh )
394 guide_neighbor_index = *it_neigh;
395 const libMesh::Elem * elem_neigh = Patch_guide->
elem(guide_neighbor_index);
398 if(bDoNeighborIntersect)
400 bCreateNewNefForGuideNeigh =
false;
403 if(bDoNeighborIntersect)
416 m_perf_log.pop(
"Update intersection queue",
"Advancing front algorithm");
422 unsigned int query_idx = Query_elem->id();
427 std::cout <<
" DEBUG: advancing front search results" << std::endl;
428 std::cout <<
" -> Guide elements tested / all : " << nbOfGuideElemsTested <<
" / " << Patch_guide->
size() << std::endl;
429 std::cout <<
" -> Positives / tests : " << nbOfPositiveTests <<
" / " << nbOfTests
430 <<
" (" << 100.*nbOfPositiveTests/nbOfTests <<
"%)" << std::endl << std::endl;
441 libMesh::Mesh::const_element_iterator it_coupl =
m_Mesh_Coupling.local_elements_begin();
442 libMesh::Mesh::const_element_iterator it_coupl_end =
m_Mesh_Coupling.local_elements_end();
444 int patch_counter = 0;
445 double real_volume = 0;
449 for( ; it_coupl != it_coupl_end; ++it_coupl)
451 const libMesh::Elem * Query_elem = * it_coupl;
453 m_perf_log.push(
"Build patches",
"Brute force");
455 m_perf_log.pop(
"Build patches",
"Brute force");
461 real_volume += Query_elem->volume();
464 m_perf_log.push(
"Find intersections",
"Brute force");
466 m_perf_log.pop(
"Find intersections",
"Brute force");
469 m_perf_log.push(
"Build intersections",
"Brute force");
471 m_perf_log.pop(
"Build intersections",
"Brute force");
477 m_perf_log.push(
"Prepare mesh",
"Brute force");
484 std::vector<double> timing_find_intersections(
m_nodes,0);
485 std::vector<double> timing_build_intersections(
m_nodes,0);
487 libMesh::PerfData performance_data =
m_perf_log.get_perf_data(
"Find intersections",
"Brute force");
488 timing_find_intersections[
m_rank] = performance_data.tot_time_incl_sub;
489 performance_data =
m_perf_log.get_perf_data(
"Build intersections",
"Brute force");
490 timing_build_intersections[
m_rank] = performance_data.tot_time_incl_sub;
492 m_comm.sum(timing_find_intersections);
493 m_comm.sum(timing_build_intersections);
507 m_perf_log.push(
"Calculate volume",
"Brute force");
509 m_perf_log.push(
"Calculate volume",
"Brute force");
511 std::cout <<
" DEBUG volume on proc. " <<
m_rank <<
"(BRUTE)" << std::endl;
513 std::cout <<
" -> Intersection volume / real : " << total_volume <<
" / " << real_volume << std::endl << std::endl;
520 libMesh::Mesh::const_element_iterator it_coupl =
m_Mesh_Coupling.local_elements_begin();
521 libMesh::Mesh::const_element_iterator it_coupl_end =
m_Mesh_Coupling.local_elements_end();
523 int patch_counter = 0;
525 for( ; it_coupl != it_coupl_end; ++it_coupl)
527 const libMesh::Elem * Query_elem = * it_coupl;
529 m_perf_log.push(
"Build patches",
"Brute force (preamble run)");
531 m_perf_log.pop(
"Build patches",
"Brute force (preamble run)");
535 m_perf_log.push(
"Find intersections",
"Brute force (preamble run)");
537 m_perf_log.pop(
"Find intersections",
"Brute force (preamble run)");
548 libMesh::Mesh::const_element_iterator it_coupl =
m_Mesh_Coupling.local_elements_begin();
549 libMesh::Mesh::const_element_iterator it_coupl_end =
m_Mesh_Coupling.local_elements_end();
551 int patch_counter = 0;
552 double real_volume = 0;
556 for( ; it_coupl != it_coupl_end; ++it_coupl)
558 const libMesh::Elem * Query_elem = * it_coupl;
560 m_perf_log.push(
"Build patches",
"Advancing front");
562 m_perf_log.pop(
"Build patches",
"Advancing front");
568 real_volume += Query_elem->volume();
570 m_perf_log.push(
"Find intersections",
"Advancing front");
572 m_perf_log.pop(
"Find intersections",
"Advancing front");
575 m_perf_log.push(
"Build intersections",
"Advancing front");
577 m_perf_log.pop(
"Build intersections",
"Advancing front");
583 m_perf_log.push(
"Prepare mesh",
"Advancing front");
585 m_perf_log.pop(
"Prepare mesh",
"Advancing front");
590 std::vector<double> timing_find_intersections(
m_nodes,0);
591 std::vector<double> timing_build_intersections(
m_nodes,0);
593 libMesh::PerfData performance_data =
m_perf_log.get_perf_data(
"Find intersections",
"Advancing front");
594 timing_find_intersections[
m_rank] = performance_data.tot_time_incl_sub;
595 performance_data =
m_perf_log.get_perf_data(
"Build intersections",
"Advancing front");
596 timing_build_intersections[
m_rank] = performance_data.tot_time_incl_sub;
598 m_comm.sum(timing_find_intersections);
599 m_comm.sum(timing_build_intersections);
613 m_perf_log.push(
"Calculate volume",
"Advancing front");
615 m_perf_log.push(
"Calculate volume",
"Advancing front");
617 std::cout <<
" DEBUG volume on proc. " <<
m_rank <<
"(FRONT)" << std::endl;
619 std::cout <<
" -> Intersection volume / real : " << total_volume <<
" / " << real_volume << std::endl << std::endl;
626 libMesh::Mesh::const_element_iterator it_coupl =
m_Mesh_Coupling.local_elements_begin();
627 libMesh::Mesh::const_element_iterator it_coupl_end =
m_Mesh_Coupling.local_elements_end();
629 int patch_counter = 0;
631 for( ; it_coupl != it_coupl_end; ++it_coupl)
633 const libMesh::Elem * Query_elem = * it_coupl;
635 m_perf_log.push(
"Build patches (preamble)",
"Advancing front (preamble run)");
637 m_perf_log.pop(
"Build patches",
"Advancing front (preamble run)");
641 m_perf_log.push(
"Find intersections",
"Advancing front (preamble run)");
643 m_perf_log.pop(
"Find intersections",
"Advancing front (preamble run)");
687 libMesh::Partitioner * dummy_partitioner =
m_Mesh_Coupling.partitioner().get();
693 std::vector<unsigned int> nb_of_inters_per_rank(
m_nodes,0);
694 unsigned int dummy_nb_of_inters = 0;
695 libMesh::Mesh::const_element_iterator it_local =
m_Mesh_Coupling.local_elements_begin();
696 libMesh::Mesh::const_element_iterator it_local_end =
m_Mesh_Coupling.local_elements_end();
697 for( ; it_local != it_local_end; ++ it_local)
699 const libMesh::Elem * dummy_elem = * it_local;
702 m_comm.sum(nb_of_inters_per_rank);
713 std::string intersection_statistics_filename;
723 libMesh::StatisticsVector<int> intersection_statistics(
m_nodes,0);
724 for(
unsigned int iii = 0; iii <
m_nodes; ++iii)
726 intersection_statistics[iii] = nb_of_inters_per_rank[iii];
729 std::ofstream inter_statistics_output(intersection_statistics_filename,std::ofstream::app);
731 inter_statistics_output << intersection_statistics.minimum() <<
" "
732 << intersection_statistics.maximum() <<
" "
733 << intersection_statistics.mean() <<
" "
734 << intersection_statistics.median() <<
" "
735 << intersection_statistics.stddev() << std::endl;
737 inter_statistics_output.close();
793 m_comm.sum(global_volume);
796 libMesh::Mesh::const_element_iterator it_coupl =
m_Mesh_Coupling.local_elements_begin();
797 libMesh::Mesh::const_element_iterator it_coupl_end =
m_Mesh_Coupling.local_elements_end();
798 double real_volume = 0;
800 for( ; it_coupl != it_coupl_end; ++it_coupl)
802 const libMesh::Elem * Query_elem = * it_coupl;
803 real_volume += Query_elem->volume();
809 std::cout <<
" TOTAL volume, proc. " <<
m_rank << std::endl;
810 std::cout <<
" -> Intersection volume / real : " << global_volume <<
" / " << real_volume << std::endl << std::endl;
821 std::unordered_set<unsigned int>::iterator it_patch_A;
823 bool bDoIntersect =
true;
824 bool bCreateNewNefForA =
true;
828 std::set<libMesh::Point> points_out;
829 double total_volume = 0;
833 int nbOfPositiveTests = 0;
834 for( it_patch_A = Patch_Set_A.begin();
835 it_patch_A != Patch_Set_A.end();
840 const libMesh::Elem * elem_A =
m_Mesh_A.elem(*it_patch_A);
841 bCreateNewNefForA =
true;
843 for(
auto it_patch_B = iterator_pair.first ;
844 it_patch_B != iterator_pair.second ;
847 const libMesh::Elem * elem_B =
m_Mesh_B.elem(it_patch_B->second);
850 m_perf_log.push(
"Build intersection polyhedron",
"Build intersections");
852 m_perf_log.pop(
"Build intersection polyhedron",
"Build intersections");
857 bCreateNewNefForA =
false;
858 m_perf_log.push(
"Calculate volume",
"Build intersections");
860 m_perf_log.pop(
"Calculate volume",
"Build intersections");
868 std::cout <<
" DEBUG: calculate the volume" << std::endl;
869 std::cout <<
" -> Intersection volume / real : " << total_volume <<
" / " << Query_elem->volume() << std::endl << std::endl;
870 std::cout <<
" -> Positives / tests : " << nbOfPositiveTests <<
" / " << nbOfTests
871 <<
" (" << 100.*nbOfPositiveTests/nbOfTests <<
"%)" << std::endl << std::endl;
882 std::unordered_set<unsigned int>::iterator it_patch_A;
884 bool bDoIntersect =
true;
885 bool bCreateNewNefForA =
true;
888 std::set<libMesh::Point> points_out;
892 int nbOfPositiveTests = 0;
895 for( it_patch_A = Patch_Set_A.begin();
896 it_patch_A != Patch_Set_A.end();
901 const libMesh::Elem * elem_A =
m_Mesh_A.elem(*it_patch_A);
902 bCreateNewNefForA =
true;
905 for(
auto it_patch_B = iterator_pair.first ;
906 it_patch_B != iterator_pair.second ;
909 const libMesh::Elem * elem_B =
m_Mesh_B.elem(it_patch_B->second);
913 m_perf_log.push(
"Build intersection polyhedron",
"Build intersections");
915 m_perf_log.pop(
"Build intersection polyhedron",
"Build intersections");
921 bCreateNewNefForA =
false;
922 m_perf_log.push(
"Update intersection",
"Build intersections");
924 m_perf_log.pop(
"Update intersection",
"Build intersections");
932 std::cout <<
" DEBUG: update intersection mesh" << std::endl;
933 std::cout <<
" -> Positives / tests : " << nbOfPositiveTests <<
" / " << nbOfTests
934 <<
" (" << 100.*nbOfPositiveTests/nbOfTests <<
"%)" << std::endl << std::endl;
bool m_bDidPreliminarySearch
Boolean flag determining if we did a preliminary intersection search, used for the coupling mesh repa...
std::string m_timing_data_file_base
Output filenames base for the timing data.
bool m_bIntersectionsBuilt
Boolean flag indicating if the intersections were built. (A bit useless right now ...
double get_total_volume()
Calculate the intersection mesh's total volume.
bool m_bSkipIntersectionConstruction
Boolean indicating if we should skip the intersection construction. Default: false.
void FindAndBuildIntersections_Front()
Find and build all the intersections, using the advancing front method.
void FindIntersections_Front()
Find all the intersections, using the advancing front method.
void FindIntersections_Brute()
Find all the intersections, using the brute force method.
void set_elem_as_inside_queue(unsigned int elem_id)
[ADV. FRONT] Mark element as already inside the deque of elements to be treated.
const libMesh::ReplicatedMesh & mesh()
Returns the address of the intersection mesh.
Class used to build a mesh patch from a parent mesh and an coupling mesh element. ...
std::string m_Output_filename_base
Output filenames base.
void export_patch_mesh(std::string &filename_base)
Export the patch mesh to a file.
bool m_bPrintIntersectionsPerPartData
Print intersections per partition. Default: false.
void FindPatchIntersections_Brute(const libMesh::Elem *Query_elem)
Find all the intersections between the patches associated to the Query_elem, using a brute force meth...
libMesh::Mesh & m_Mesh_Coupling
Mesh representing the coupling region.
const libMesh::Parallel::Communicator & m_comm
Global communicator.
const libMesh::Elem * current_elem_pointer()
unsigned int intersection_queue_extract_front_elem()
[ADV. FRONT] Pop and returns the first element to be treated.
void increase_intersection_mesh(const std::set< libMesh::Point > &input_points, unsigned int elem_idx_A, unsigned int elem_idx_B, unsigned int elem_idx_C)
Increase the intersection mesh with the current polyhedron mesh and update its data structures...
void export_intersection_data(const std::string &filename_base, const std::string &mesh_format=std::string(".e"))
Export both the intersection mesh its data structures.
const unsigned int m_nodes
Number of MPI processors.
void BuildCoupledPatches(const libMesh::Elem *Query_elem, int patch_counter=0)
Build both patches associated a given query element from the coupling region mesh.
unsigned int FrontSearch_prepare_for_probed_test()
[ADV. FRONT] Reset the advancing front search data structures, with the exception of list of elements...
void BruteForce_FindFirstPair(Patch_construction *Patch_guide, Patch_construction *Patch_probed, std::pair< unsigned int, unsigned int > &First_intersection)
Find the first intersecting pair from a patch, doing a full scan of the patches.
bool intersection_queue_empty()
[ADV. FRONT] Check if deque of elements to be treated is empty.
void PreparePreallocationAndLoad(SearchMethod search_type=BRUTE)
Do a preliminary search, to optimize the intersection search and construction.
void PreallocateAndPartitionCoupling()
Preallocate Intersection_Search::m_Intersection_Pairs_multimap and repartition the coupling mesh...
bool m_bSkipIntersectionPartitioning
Boolean indicating if we should skip the intersection repartitioning. Default: false.
Patch_construction m_Patch_Constructor_B
Patch_construction object for mesh B.
void print_stats_to_file(std::vector< double > &vec_data, const std::string filename)
bool test_queue_empty()
[ADV. FRONT] Check if deque of elements to be tested is empty.
void UpdateCouplingIntersection(const libMesh::Elem *Query_elem)
Build the intersections associated to the Query_elem and update the intersection mesh.
std::unordered_set< unsigned int > & elem_indexes()
Returns the set of elements inside the patch.
libMesh::ReplicatedMesh & patch_mesh()
Returns the patch mesh.
libMesh::PerfLog m_perf_log
libMesh::PerfLog object.
const libMesh::Elem * elem(unsigned int idx)
Patch_construction m_Patch_Constructor_A
Patch_construction object for mesh A.
std::unordered_multimap< unsigned int, unsigned int > m_Intersection_Pairs_multimap
Multimap containing the intersection pairs.
std::vector< unsigned int > m_Nb_Of_Intersections_Elem_C
Vector containing the number of intersections found inside each of the coupling mesh elements...
bool m_bHavePreallocData
Boolean flag determining if we have the data for a proper preallocation of m_Intersection_Pairs_multi...
void FindFirstPair(Patch_construction *Patch_guide, Patch_construction *Patch_probed, std::pair< unsigned int, unsigned int > &First_intersection)
Find the first intersecting pair from a patch.
Mesh_Intersection m_Mesh_Intersection
Object containing the intersection mesh.
unsigned int convert_patch_to_parent_elem_id(unsigned int input)
Convert an element index from the patch mesh to the parent mesh.
libMesh::ErrorVector m_coupling_weights
libMesh::ErrorVector used to repartition the coupling mesh.
void BuildPatch(const libMesh::Elem *Query_elem)
Build the patch mesh covering a given "Query_elem".
Intersection_Tools m_Intersection_test
Intersection operations for the main intersection tests.
bool m_bPrintDebug
Print debug data. Default: false.
bool set_neighbors_to_search_next_pairs()
[ADV. FRONT] Set the list of neighbors of the current element that must be tested yet...
void CalculateGlobalVolume()
Calculate the total intersection volume over all the processors.
libMesh::Mesh & mesh_A()
Reference to the mesh A.
void set_elem_as_treated(unsigned int elem_id)
[ADV. FRONT] Mark element as already treated.
void initialize()
Initialize the data structures.
void SetScalingFiles(const std::string &timing_data_file_base)
Set up timing output file.
libMesh::Mesh & mesh_Coupling()
Reference to the coupling mesh.
void add_neighbors_to_test_list()
[ADV. FRONT] Adds element to test list.
double get_intersection_volume(std::set< libMesh::Point > &input_points)
Calculate the volume of an polyhedron defined by the point set.
void FindPatchIntersections_Front(const libMesh::Elem *Query_elem)
Find all the intersections between the patches associated to the Query_elem, using an advancing front...
unsigned int test_queue_extract_front_elem()
[ADV. FRONT] Pop and returns the first element to be tested.
void preallocate_grid(int map_preallocation)
Preallocate the discrete points grid.
void FrontSearch_reset()
[ADV. FRONT] Reset the advancing front search data structures, with the exception of list of elements...
unsigned int size()
Returns the number of elements inside the patch.
void intersection_queue_push_back(unsigned int elem_id)
[ADV. FRONT] Push back element to the deque containing the elements to be treated.
void prepare_for_use()
Prepare the intersection mesh for use.
bool m_bSaveInterData
Boolean flag determining if we should save the intersection data or not. Default: true...
void CalculateIntersectionVolume(const libMesh::Elem *Query_elem)
Calculate the volume of the intersections associated to Query_elem without updating the intersection ...
Intersection_Tools m_Intersection_test_neighbors
Intersection operations for the neighbor intersection tests. (why do we need both?)
void FindAndBuildIntersections_Brute()
Find and build all the intersections, using the brute force method.
const unsigned int m_rank
This processor's rank (or ID in the communicator)
void BuildIntersections(SearchMethod search_type=BRUTE)
Find and build all the intersections.
libMesh::Mesh & mesh_B()
Reference to the mesh B.
bool m_bPrintTimingData
Print timing data. Default: false.
void FrontSearch_initialize()
[ADV. FRONT] Initialize the advancing front search data structures.
std::unordered_set< unsigned int > & neighbors_to_search_next_pair()
[ADV. FRONT] Returns the current element's neighbors that must be tested yet.