30 #ifndef OOMPH_TRIANGLE_MESH_HEADER 31 #define OOMPH_TRIANGLE_MESH_HEADER 34 #include <oomph-lib-config.h> 50 #include "../generic/problem.h" 51 #include "../generic/triangle_scaffold_mesh.h" 52 #include "../generic/triangle_mesh.h" 53 #include "../generic/refineable_mesh.h" 54 #include "../rigid_body/immersed_rigid_body_elements.h" 59 #ifdef OOMPH_HAS_TRIANGLE_LIB 63 void triangulate(
char *triswitches,
struct oomph::TriangulateIO *in,
64 struct oomph::TriangulateIO *out,
65 struct oomph::TriangulateIO *vorout);
181 Vector<double> ®ion_coordinates)
186 std::ostringstream error_message;
187 error_message <<
"Please use another region id different from zero.\n" 188 <<
"It is internally used as the default region number.\n";
189 throw OomphLibError(error_message.str(),
190 OOMPH_CURRENT_FUNCTION,
191 OOMPH_EXCEPTION_LOCATION);
195 std::map<unsigned, Vector<double> >::iterator it;
201 std::ostringstream error_message;
202 error_message <<
"The region id ("<<i<<
") that you are using for" 204 <<
"your region is already in use. Use another\n" 205 <<
"region id and verify that you are not re-using\n" 206 <<
" previously defined regions ids\n"<<std::endl;
207 OomphLibWarning(error_message.str(),
208 OOMPH_CURRENT_FUNCTION,
209 OOMPH_EXCEPTION_LOCATION);
354 template<
class ELEMENT>
362 #ifdef OOMPH_HAS_TRIANGLE_LIB 364 Triangulateio_exists=
false;
371 First_time_compute_holes_left_by_halo_elements =
true;
372 #endif // #ifdef OOMPH_HAS_MPI 377 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(2);
382 const std::string& element_file_name,
383 const std::string& poly_file_name,
384 TimeStepper* time_stepper_pt=
385 &Mesh::Default_TimeStepper,
386 const bool &allow_automatic_creation_of_vertices_on_boundaries=
true)
389 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(2);
393 allow_automatic_creation_of_vertices_on_boundaries;
398 First_time_compute_holes_left_by_halo_elements=
true;
399 #endif // #ifdef OOMPH_HAS_MPI 402 Time_stepper_pt=time_stepper_pt;
406 bool should_use_attributes=
false;
408 #ifdef OOMPH_HAS_TRIANGLE_LIB 410 TriangleHelper::create_triangulateio_from_polyfiles(node_file_name,
414 should_use_attributes);
417 Triangulateio_exists=
true;
424 this->Tmp_mesh_pt=
new 425 TriangleScaffoldMesh(node_file_name,
430 build_from_scaffold(time_stepper_pt,should_use_attributes);
433 delete this->Tmp_mesh_pt;
437 unsigned nb=nboundary();
438 for (
unsigned b=0;b<nb;b++)
440 this->
template setup_boundary_coordinates<ELEMENT>(b);
446 #ifdef OOMPH_HAS_TRIANGLE_LIB 453 TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper)
460 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(2);
467 Time_stepper_pt=time_stepper_pt;
472 First_time_compute_holes_left_by_halo_elements =
true;
473 #endif // #ifdef OOMPH_HAS_MPI 483 unsigned max_boundary_id = 0;
495 if (outer_boundary_pt.size()==0)
497 std::stringstream error_message;
499 <<
"There are no outer boundaries defined.\n" 500 <<
"Verify that you have specified the outer boundaries in the\n" 501 <<
"Triangle_mesh_parameter object\n\n";
502 throw OomphLibError(error_message.str(),
503 OOMPH_CURRENT_FUNCTION,
504 OOMPH_EXCEPTION_LOCATION);
509 unsigned n_outer_boundaries = outer_boundary_pt.size();
513 Vector<TriangleMeshPolygon*> outer_boundary_polygon_pt(n_outer_boundaries);
516 for(
unsigned i=0;i<n_outer_boundaries;++i)
522 outer_boundary_polygon_pt[i] =
523 closed_curve_to_polygon_helper(outer_boundary_pt[i], max_boundary_id);
535 unsigned n_internal_closed_curves = internal_closed_curve_pt.size();
540 Vector<TriangleMeshPolygon*> internal_polygon_pt(n_internal_closed_curves);
543 for(
unsigned i=0;i<n_internal_closed_curves;++i)
547 internal_polygon_pt[i] =
548 closed_curve_to_polygon_helper(
549 internal_closed_curve_pt[i], max_boundary_id);
557 Vector<TriangleMeshOpenCurve*> internal_open_curve_pt =
561 unsigned n_internal_open_curves = internal_open_curve_pt.size();
564 Vector<TriangleMeshOpenCurve*> internal_open_curve_poly_pt(
565 n_internal_open_curves);
568 for (
unsigned i = 0; i < n_internal_open_curves; i++)
573 internal_open_curve_poly_pt[i] =
574 create_open_curve_with_polyline_helper(
575 internal_open_curve_pt[i], max_boundary_id);
585 for (
unsigned i = 0; i < n_outer_boundaries; i++)
587 set_geom_objects_and_coordinate_limits_for_close_curve(
588 outer_boundary_pt[i]);
594 for (
unsigned i = 0; i < n_internal_closed_curves; i++)
596 set_geom_objects_and_coordinate_limits_for_close_curve(
597 internal_closed_curve_pt[i]);
603 for (
unsigned i = 0; i < n_internal_open_curves; i++)
605 set_geom_objects_and_coordinate_limits_for_open_curve(
606 internal_open_curve_pt[i]);
623 std::map<unsigned, Vector<double> > regions =
629 const bool refine_boundary =
632 const bool refine_internal_boundary =
635 if(!refine_internal_boundary && refine_boundary)
637 std::ostringstream error_stream;
640 "You have specified that Triangle may refine the outer boundary, but\n" 642 "not internal boundaries. Triangle does not support this combination.\n" 644 "If you do not want Triangle to refine internal boundaries, it can't\n" 646 "refine outer boundaries either!\n" 647 <<
"Please either disable all boundary refinement\n" 648 <<
"(call TriangleMeshParameters::disable_boundary_refinement()\n" 649 <<
"or enable internal boundary refinement (the default)\n";
651 throw OomphLibError(error_stream.str().c_str(),
652 OOMPH_CURRENT_FUNCTION,
653 OOMPH_EXCEPTION_LOCATION);
656 this->generic_constructor(outer_boundary_polygon_pt,
658 internal_open_curve_poly_pt,
660 extra_holes_coordinates,
666 refine_internal_boundary);
669 unsigned nb=nboundary();
681 for (
unsigned b=0;b<nb;b++)
683 this->
template setup_boundary_coordinates<ELEMENT>(b);
687 this->snap_nodes_onto_geometric_objects();
694 TimeStepper* time_stepper_pt=
695 &Mesh::Default_TimeStepper,
696 const bool &allow_automatic_creation_of_vertices_on_boundaries=
true)
699 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(2);
703 allow_automatic_creation_of_vertices_on_boundaries;
708 First_time_compute_holes_left_by_halo_elements=
true;
709 #endif // #ifdef OOMPH_HAS_MPI 713 "This constructor hasn't been tested since last cleanup.\n";
714 OomphLibWarning(message,
715 "TriangleMesh::TriangleMesh()",
716 OOMPH_EXCEPTION_LOCATION);
719 Time_stepper_pt=time_stepper_pt;
722 TriangulateIO triangle_in;
725 std::stringstream input_string_stream;
729 input_string_stream<<
"-pA -a -a" << element_area <<
"q30";
732 if (!this->is_creation_of_vertices_on_boundaries_allowed())
734 input_string_stream<<
" -YY";
738 char triswitches[100];
739 sprintf(triswitches,
"%s",input_string_stream.str().c_str());
744 bool use_attributes=
false;
747 build_triangulateio(poly_file_name,triangle_in,use_attributes);
753 triangulate(triswitches,&triangle_in,&Triangulateio,0);
756 this->Tmp_mesh_pt=
new TriangleScaffoldMesh(Triangulateio);
759 build_from_scaffold(time_stepper_pt,use_attributes);
762 delete this->Tmp_mesh_pt;
766 bool clear_hole_data=
false;
767 TriangleHelper::clear_triangulateio(triangle_in,clear_hole_data);
770 unsigned nb=nboundary();
771 for (
unsigned b=0;b<nb;b++)
773 this->
template setup_boundary_coordinates<ELEMENT>(b);
782 BrokenCopy::broken_copy(
"TriangleMesh");
788 BrokenCopy::broken_assign(
"TriangleMesh");
794 #ifdef OOMPH_HAS_TRIANGLE_LIB 795 if (Triangulateio_exists)
797 TriangleHelper::clear_triangulateio(Triangulateio);
800 std::set<TriangleMeshCurveSection*>::iterator it_polyline;
801 for (it_polyline = Free_curve_section_pt.begin();
802 it_polyline != Free_curve_section_pt.end();
805 delete (*it_polyline);
808 std::set<TriangleMeshPolygon*>::iterator it_polygon;
809 for (it_polygon = Free_polygon_pt.begin();
810 it_polygon != Free_polygon_pt.end();
813 delete (*it_polygon);
816 std::set<TriangleMeshOpenCurve*>::iterator it_open_polyline;
817 for (it_open_polyline = Free_open_curve_pt.begin();
818 it_open_polyline != Free_open_curve_pt.end();
821 delete (*it_open_polyline);
830 const bool &preserve_existing_data)
832 this->Time_stepper_pt = time_stepper_pt;
839 void compute_boundary_segments_connectivity_and_initial_zeta_values(
846 void re_assign_initial_zeta_values_for_internal_boundary(
848 Vector<std::list<FiniteElement*> > &old_segment_sorted_ele_pt,
849 std::map<FiniteElement*, bool> &old_is_inverted);
853 void re_scale_re_assigned_initial_zeta_values_for_internal_boundary(
861 void identify_boundary_segments_and_assign_initial_zeta_values(
862 const unsigned& b, Vector<FiniteElement*> &input_face_ele_pt,
863 const bool &is_internal_boundary,
864 std::map<FiniteElement*,FiniteElement*> &face_to_bulk_element_pt);
869 void identify_boundary_segments_and_assign_initial_zeta_values(
876 void synchronize_boundary_coordinates(
const unsigned& b);
881 void select_boundary_face_elements(
882 Vector<FiniteElement*> &face_el_pt,
const unsigned &b,
883 bool &is_internal_boundary,
884 std::map<FiniteElement*,FiniteElement*> &face_to_bulk_element_pt);
889 {
return Boundary_segment_node_pt[b];}
894 {
return Boundary_segment_node_pt[b][s];}
899 {
return Boundary_segment_node_pt[b][s][n];}
901 #endif // OOMPH_HAS_MPI 903 #ifdef OOMPH_HAS_TRIANGLE_LIB 911 unsigned nhole=Triangulateio.numberofholes;
912 unsigned count_coord=0;
913 for(
unsigned ihole=0;ihole<nhole;ihole++)
915 Triangulateio.holelist[count_coord]+=internal_point[ihole][0];
916 Triangulateio.holelist[count_coord+1]+=internal_point[ihole][1];
923 update_triangulateio();
930 unsigned nnode = Triangulateio.numberofpoints;
935 for(
unsigned inod=0;inod<nnode;inod++)
938 unsigned count=Oomph_vertex_nodes_id[inod];
942 Node* mesh_node_pt=this->node_pt(inod);
943 new_x=mesh_node_pt->x(0);
944 new_y=mesh_node_pt->x(1);
945 Triangulateio.pointlist[count*2] = new_x;
946 Triangulateio.pointlist[(count*2)+1] = new_y;
952 void dump_distributed_info_for_restart(std::ostream &dump_file);
956 std::string input_string;
959 getline(read_file,input_string,
'#');
962 read_file.ignore(200,
'\n');
965 return std::atoi(input_string.c_str());
969 void read_distributed_info_for_restart(std::istream &restart_file);
974 OomphCommunicator* comm_pt, std::istream &restart_file)
976 std::ostringstream error_stream;
977 error_stream <<
"Empty default reestablish disributed info method " 979 error_stream <<
"This should be overloaded in a specific " 980 <<
"RefineableTriangleMesh\n";
981 throw OomphLibError(error_stream.str(),
982 OOMPH_CURRENT_FUNCTION,
983 OOMPH_EXCEPTION_LOCATION);
986 #endif // #ifdef OOMPH_HAS_MPI 992 this->remove_boundary_nodes();
995 unsigned n_node = this->nnode();
996 for(
unsigned n=n_node;n>0;--n)
998 delete this->Node_pt[n-1];
999 this->Node_pt[n-1] = 0;
1002 unsigned n_element = this->nelement();
1003 for(
unsigned e=n_element;e>0;--e)
1005 delete this->Element_pt[e-1];
1006 this->Element_pt[e-1] = 0;
1009 this->flush_element_and_node_storage();
1013 this->Boundary_element_pt.clear();
1014 this->Face_index_at_boundary.clear();
1015 this->Region_element_pt.clear();
1016 this->Region_attribute.clear();
1017 this->Boundary_region_element_pt.clear();
1018 this->Face_index_region_at_boundary.clear();
1019 this->Boundary_curve_section_pt.clear();
1020 this->Polygonal_vertex_arclength_info.clear();
1022 #ifdef OOMPH_HAS_MPI 1026 this->Halo_node_pt.clear();
1027 this->Root_halo_element_pt.clear();
1029 this->Haloed_node_pt.clear();
1030 this->Root_haloed_element_pt.clear();
1032 this->External_halo_node_pt.clear();
1033 this->External_halo_element_pt.clear();
1035 this->External_haloed_node_pt.clear();
1036 this->External_haloed_element_pt.clear();
1040 unsigned nbound=nboundary();
1041 Boundary_coordinate_exists.resize(nbound,
false);
1044 this->Tmp_mesh_pt=
new TriangleScaffoldMesh(this->Triangulateio);
1047 Triangulateio_exists=
true;
1053 delete this->Tmp_mesh_pt;
1054 this->Tmp_mesh_pt=0;
1056 #ifdef OOMPH_HAS_MPI 1059 nbound = this->nboundary();
1063 nbound = this->initial_shared_boundary_id();
1072 nbound = this->nboundary();
1076 for (
unsigned b=0;b<nbound;b++)
1078 this->
template setup_boundary_coordinates<ELEMENT>(b);
1088 this->snap_nodes_onto_geometric_objects();
1095 return Triangulateio_exists;
1104 return Oomph_vertex_nodes_id;
1121 void build_from_scaffold(TimeStepper* time_stepper_pt,
1122 const bool &use_attributes);
1124 #ifdef OOMPH_HAS_TRIANGLE_LIB 1128 void build_triangulateio(
const std::string& poly_file_name,
1129 TriangulateIO& triangulate_io,
1130 bool& use_attributes);
1136 Vector<TriangleMeshPolygon*> &internal_polygon_pt,
1137 Vector<TriangleMeshOpenCurve*>
1141 std::map<
unsigned, Vector<double> >
1143 std::map<unsigned, double >
1145 TimeStepper* time_stepper_pt,
1146 const bool &use_attributes,
1147 const bool &refine_boundary,
1148 const bool &refine_internal_boundary)
1151 MeshChecker::assert_geometric_element<TElementGeometricBase,ELEMENT>(2);
1154 if (element_area < 10e-14)
1156 std::ostringstream warning_message;
1158 <<
"The current elements area was stated to (" << element_area
1159 <<
").\nThe current precision to generate the input to triangle " 1160 <<
"is fixed to 14 digits\n\n";
1161 OomphLibWarning(warning_message.str(),
1162 OOMPH_CURRENT_FUNCTION,
1163 OOMPH_EXCEPTION_LOCATION);
1168 Use_attributes = use_attributes;
1171 Time_stepper_pt=time_stepper_pt;
1177 Internal_polygon_pt=internal_polygon_pt;
1180 Internal_open_curve_pt = open_polylines_pt;
1189 TriangulateIO triangulate_io;
1192 TriangleHelper::initialise_triangulateio(triangulate_io);
1196 UnstructuredTwoDMeshGeometryBase::build_triangulateio(outer_boundary_pt,
1197 internal_polygon_pt,
1205 TriangleHelper::initialise_triangulateio(Triangulateio);
1208 Triangulateio_exists=
true;
1211 std::stringstream input_string_stream;
1212 input_string_stream.precision(14);
1213 input_string_stream.setf(std::ios_base::fixed,
1214 std::ios_base::floatfield);
1220 input_string_stream <<
"-pA -a -a" << element_area <<
" -q30" << std::fixed;
1224 {input_string_stream<<
" -YY";}
1227 if(refine_boundary==
false)
1229 input_string_stream <<
"-Y";
1231 if(refine_internal_boundary==
false) {input_string_stream <<
"Y";}
1235 char triswitches[100];
1236 sprintf(triswitches,
"%s",input_string_stream.str().c_str());
1239 triangulate(triswitches, &triangulate_io, &Triangulateio, 0);
1242 this->Tmp_mesh_pt=
new TriangleScaffoldMesh(Triangulateio);
1248 build_from_scaffold(time_stepper_pt,
true);
1250 Use_attributes=
true;
1256 build_from_scaffold(time_stepper_pt,use_attributes);
1260 delete this->Tmp_mesh_pt;
1261 this->Tmp_mesh_pt=0;
1264 bool clear_hole_data=
false;
1265 TriangleHelper::clear_triangulateio(triangulate_io,clear_hole_data);
1271 #endif // OOMPH_HAS_TRIANGLE_LIB 1280 #ifdef OOMPH_HAS_MPI 1286 {
return Initial_shared_boundary_id;}
1290 {
return Final_shared_boundary_id;}
1297 Vector<unsigned> &shared_boundaries_in_this_processor)
1301 std::set<unsigned> shared_boundaries_in_this_processor_set;
1309 for (
unsigned iproc = 0; iproc < n_proc; iproc++)
1312 if (iproc != my_rank)
1316 const unsigned nshared_boundaries_with_iproc =
1317 this->nshared_boundaries(my_rank, iproc);
1321 if (nshared_boundaries_with_iproc > 0)
1324 Vector<unsigned> bound_ids_shared_with_iproc;
1325 bound_ids_shared_with_iproc =
1326 this->shared_boundaries_ids(my_rank, iproc);
1329 for (
unsigned bs = 0; bs < nshared_boundaries_with_iproc; bs++)
1331 const unsigned bnd_id = bound_ids_shared_with_iproc[bs];
1335 std::set<unsigned>::iterator it =
1336 shared_boundaries_in_this_processor_set.find(bnd_id);
1337 if (it != shared_boundaries_in_this_processor_set.end())
1339 std::stringstream error;
1341 <<
"The current shared boundary (" << bnd_id <<
") was\n" 1342 <<
"already added by other pair of processors\n." 1343 <<
"This means that there are repeated shared boundaries ids\n";
1344 throw OomphLibError(error.str(),
1345 OOMPH_CURRENT_FUNCTION,
1346 OOMPH_EXCEPTION_LOCATION);
1348 shared_boundaries_in_this_processor_set.insert(bnd_id);
1350 shared_boundaries_in_this_processor.push_back(bnd_id);
1363 const unsigned &q)
const 1364 {
return Shared_boundaries_ids[p][q].size();}
1367 {
return Shared_boundaries_ids;}
1370 {
return Shared_boundaries_ids;}
1373 {
return Shared_boundaries_ids[p];}
1376 {
return Shared_boundaries_ids[p];}
1379 const unsigned &q)
const 1380 {
return Shared_boundaries_ids[p][q];}
1383 {
return Shared_boundaries_ids[p][q];}
1387 const unsigned &i)
const 1388 {
return Shared_boundaries_ids[p][q][i];}
1391 {
return Shared_boundary_polyline_pt[p].size();}
1394 const unsigned &c)
const 1395 {
return Shared_boundary_polyline_pt[p][c].size();}
1399 {
return Shared_boundary_polyline_pt[p][c];}
1403 const unsigned &i)
const 1404 {
return Shared_boundary_polyline_pt[p][c][i];}
1407 {
return Shared_boundary_element_pt.size();}
1412 std::map<unsigned, Vector<FiniteElement*> >::iterator it =
1413 Shared_boundary_element_pt.find(b);
1414 if (it != Shared_boundary_element_pt.end())
1416 return Shared_boundary_element_pt[b].size();
1420 std::ostringstream error_stream;
1422 <<
"The shared boundary ("<< b <<
") does not exist!!!\n\n";
1423 throw OomphLibError(error_stream.str(),
1424 OOMPH_CURRENT_FUNCTION,
1425 OOMPH_EXCEPTION_LOCATION);
1430 {Shared_boundary_element_pt.clear();}
1435 std::map<unsigned, Vector<FiniteElement*> >::iterator it =
1436 Shared_boundary_element_pt.find(b);
1437 if (it != Shared_boundary_element_pt.end())
1439 Shared_boundary_element_pt[b].clear();
1443 std::ostringstream error_stream;
1445 <<
"The shared boundary ("<< b <<
") does not exist!!!\n\n";
1446 throw OomphLibError(error_stream.str(),
1447 OOMPH_CURRENT_FUNCTION,
1448 OOMPH_EXCEPTION_LOCATION);
1453 FiniteElement* ele_pt)
1454 {Shared_boundary_element_pt[b].push_back(ele_pt);}
1460 std::map<unsigned, Vector<FiniteElement*> >::iterator it =
1461 Shared_boundary_element_pt.find(b);
1462 if (it != Shared_boundary_element_pt.end())
1464 return Shared_boundary_element_pt[b][e];
1468 std::ostringstream error_stream;
1470 <<
"The shared boundary ("<< b <<
") does not exist!!!\n\n";
1471 throw OomphLibError(error_stream.str(),
1472 OOMPH_CURRENT_FUNCTION,
1473 OOMPH_EXCEPTION_LOCATION);
1478 {Face_index_at_shared_boundary.clear();}
1482 {Face_index_at_shared_boundary[b].push_back(i);}
1488 std::map<unsigned, Vector<int> >::iterator it =
1489 Face_index_at_shared_boundary.find(b);
1490 if (it != Face_index_at_shared_boundary.end())
1492 return Face_index_at_shared_boundary[b][e];
1496 std::ostringstream error_stream;
1498 <<
"The shared boundary ("<< b <<
") does not exist!!!\n\n";
1499 throw OomphLibError(error_stream.str(),
1500 OOMPH_CURRENT_FUNCTION,
1501 OOMPH_EXCEPTION_LOCATION);
1508 std::map<unsigned, Vector<Node*> >::iterator it =
1509 Shared_boundary_node_pt.find(b);
1510 if (it != Shared_boundary_node_pt.end())
1512 return Shared_boundary_node_pt[b].size();
1516 std::ostringstream error_stream;
1518 <<
"The shared boundary ("<< b <<
") does not exist!!!\n\n";
1519 throw OomphLibError(error_stream.str(),
1520 OOMPH_CURRENT_FUNCTION,
1521 OOMPH_EXCEPTION_LOCATION);
1527 {Shared_boundary_node_pt.clear();}
1531 {Shared_boundary_node_pt[b].clear();}
1537 const unsigned nbound_node=Shared_boundary_node_pt[b].size();
1538 bool node_already_on_this_boundary=
false;
1540 for (
unsigned n=0; n<nbound_node; n++)
1543 if (node_pt==Shared_boundary_node_pt[b][n])
1545 node_already_on_this_boundary=
true;
1550 if (!node_already_on_this_boundary)
1552 Shared_boundary_node_pt[b].push_back(node_pt);
1560 std::map<unsigned, Vector<Node*> >::iterator it =
1561 Shared_boundary_node_pt.find(b);
1562 if (it != Shared_boundary_node_pt.end())
1564 return Shared_boundary_node_pt[b][n];
1568 std::ostringstream error_stream;
1570 <<
"The shared boundary ("<< b <<
") does not exist!!!\n\n";
1571 throw OomphLibError(error_stream.str(),
1572 OOMPH_CURRENT_FUNCTION,
1573 OOMPH_EXCEPTION_LOCATION);
1581 std::map<unsigned, Vector<Node*> >::iterator it =
1582 Shared_boundary_node_pt.find(b);
1583 if (it != Shared_boundary_node_pt.end())
1586 Vector<Node*>::iterator it_shd_nodes =
1587 std::find(Shared_boundary_node_pt[b].begin(),
1588 Shared_boundary_node_pt[b].end(),
1591 if(it_shd_nodes!=Shared_boundary_node_pt[b].end())
1598 std::ostringstream error_stream;
1600 <<
"The shared boundary ("<< b <<
") does not exist!!!\n\n";
1601 throw OomphLibError(error_stream.str(),
1602 OOMPH_CURRENT_FUNCTION,
1603 OOMPH_EXCEPTION_LOCATION);
1609 {
return Shared_boundary_from_processors;}
1613 std::map<unsigned, Vector<unsigned> >::iterator it =
1614 Shared_boundary_from_processors.find(b);
1616 if (it == Shared_boundary_from_processors.end())
1618 std::ostringstream error_message;
1620 <<
"The boundary ("<<b<<
") seems not to be shared by any processors,\n" 1621 <<
"it is possible that the boundary was created by the user an not\n" 1622 <<
"automatically by the common interfaces between processors-domains\n";
1623 throw OomphLibError(error_message.str(),
1624 OOMPH_CURRENT_FUNCTION,
1625 OOMPH_EXCEPTION_LOCATION);
1628 return (*it).second;
1635 return Shared_boundary_overlaps_internal_boundary.size();
1640 const unsigned &shd_bnd_id)
1642 std::map<unsigned, unsigned>::iterator it =
1643 Shared_boundary_overlaps_internal_boundary.find(shd_bnd_id);
1644 if (it != Shared_boundary_overlaps_internal_boundary.end())
1654 const unsigned &shd_bnd_id)
1656 std::map<unsigned, unsigned>::iterator it =
1657 Shared_boundary_overlaps_internal_boundary.find(shd_bnd_id);
1659 if (it == Shared_boundary_overlaps_internal_boundary.end())
1661 std::ostringstream error_message;
1663 <<
"The shared boundary ("<<shd_bnd_id<<
") does not lie on an internal " 1665 <<
"Make sure to call this method just for shared boundaries that lie " 1666 <<
"on an internal boundary.\n\n";
1667 throw OomphLibError(error_message.str(),
1668 OOMPH_CURRENT_FUNCTION,
1669 OOMPH_EXCEPTION_LOCATION);
1672 return (*it).second;
1678 const unsigned &internal_bnd_id,
1679 Vector<unsigned> &shd_bnd_ids)
1682 shd_bnd_ids.clear();
1685 std::map<unsigned, unsigned>::iterator it =
1686 Shared_boundary_overlaps_internal_boundary.begin();
1687 for (; it !=Shared_boundary_overlaps_internal_boundary.end(); it++)
1691 if ((*it).second == internal_bnd_id)
1694 shd_bnd_ids.push_back((*it).first);
1699 if (shd_bnd_ids.size() == 0)
1701 std::ostringstream error_message;
1703 <<
" The internal boundary (" << internal_bnd_id <<
") has no shared " 1704 <<
"boundaries overlapping it\n" 1705 <<
"Make sure to call this method just for internal boundaries that " 1706 <<
"are marked to as being\noverlaped by shared boundaries\n";
1707 throw OomphLibError(error_message.str(),
1708 OOMPH_CURRENT_FUNCTION,
1709 OOMPH_EXCEPTION_LOCATION);
1718 {
return Shared_boundary_overlaps_internal_boundary;}
1724 std::map<unsigned, bool>::iterator it;
1725 it = Boundary_was_splitted.find(b);
1726 if (it == Boundary_was_splitted.end())
1732 return (*it).second;
1740 std::map<unsigned, Vector<TriangleMeshPolyLine*> >::iterator it;
1741 it = Boundary_subpolylines.find(b);
1743 if (it == Boundary_subpolylines.end())
1745 std::ostringstream error_message;
1747 <<
"The boundary ("<<b<<
") was marked as been splitted but there\n" 1748 <<
"are not registered polylines to represent the boundary.\n" 1749 <<
"The new polylines were not set up when the boundary was found to\n" 1750 <<
"be splitted or the polylines have been explicitly deleted before\n" 1752 throw OomphLibError(error_message.str(),
1753 OOMPH_CURRENT_FUNCTION,
1754 OOMPH_EXCEPTION_LOCATION);
1757 return (*it).second.size();
1765 std::map<unsigned, Vector<TriangleMeshPolyLine*> >::iterator it;
1766 it = Boundary_subpolylines.find(b);
1767 if (it == Boundary_subpolylines.end())
1769 std::ostringstream error_message;
1771 <<
"The boundary ("<<b<<
") was marked as been splitted but there\n" 1772 <<
"are not registered polylines to represent the boundary.\n" 1773 <<
"The new polylines were not set up when the boundary was found to\n" 1774 <<
"be splitted or the polylines have been explicitly deleted before\n" 1776 throw OomphLibError(error_message.str(),
1777 OOMPH_CURRENT_FUNCTION,
1778 OOMPH_EXCEPTION_LOCATION);
1780 return (*it).second;
1787 const unsigned &isub)
1789 std::map<unsigned, std::vector<bool> >::iterator it;
1790 it = Boundary_marked_as_shared_boundary.find(b);
1791 if (it == Boundary_marked_as_shared_boundary.end())
1798 return (*it).second[isub];
1827 {Shared_boundary_polyline_pt.clear();}
1859 void create_distributed_domain_representation(Vector<TriangleMeshPolygon *>
1861 Vector<TriangleMeshOpenCurve*>
1866 void sort_polylines_helper(Vector<TriangleMeshPolyLine *>
1867 &unsorted_polylines_pt,
1868 Vector<Vector<TriangleMeshPolyLine *> >
1869 &sorted_polylines_pt);
1873 void create_tmp_polygons_helper(Vector<Vector<TriangleMeshPolyLine *> >
1875 Vector<TriangleMeshPolygon *> &polygons_pt);
1880 void create_tmp_open_curves_helper(Vector<Vector<TriangleMeshPolyLine *> >
1881 &sorted_open_curves_pt,
1882 Vector<TriangleMeshPolyLine*>
1883 &unsorted_shared_to_internal_poly_pt,
1884 Vector<TriangleMeshOpenCurve *>
1896 void compute_holes_left_by_halo_elements_helper(
1897 Vector<Vector<double> > &output_holes_coordinates);
1904 void update_holes_information_helper(
1905 Vector<TriangleMeshPolygon *> &polygons_pt,
1906 Vector<Vector<double> > &output_holes_coordinates);
1913 const int check_connections_of_polyline_nodes(
1914 std::set<FiniteElement*> &element_in_processor_pt,
1915 const int &root_edge_bnd_id,
1916 std::map<std::pair<Node*,Node*>,
bool> &overlapped_face,
1917 std::map<
unsigned, std::map<Node*, bool> >
1918 &node_on_bnd_not_overlapped_by_shd_bnd,
1919 std::list<Node*> ¤t_polyline_nodes,
1920 std::map<
unsigned, std::list<Node*> >
1921 &shared_bnd_id_to_sorted_list_node_pt,
1922 const unsigned &node_degree,
1924 const bool called_from_load_balance=
false);
1929 void create_shared_polylines_connections();
1932 void create_shared_boundaries(OomphCommunicator* comm_pt,
1933 const Vector<unsigned> &element_domain,
1934 const Vector<GeneralisedElement*>
1936 const Vector<FiniteElement*>
1938 std::map<Data*,std::set<unsigned> >
1939 &processors_associated_with_data,
1941 overrule_keep_as_halo_element_status);
1946 void get_halo_elements_on_all_procs(
const unsigned &nproc,
1947 const Vector<unsigned>
1949 const Vector<GeneralisedElement*>
1951 std::map<Data*,std::set<unsigned> >
1952 &processors_associated_with_data,
1954 overrule_keep_as_halo_element_status,
1955 std::map<GeneralisedElement*, unsigned>
1956 &element_to_global_index,
1958 Vector<GeneralisedElement*> > >&
1959 output_halo_elements_pt);
1964 void get_element_edges_on_boundary(std::map<std::pair<Node*,Node*>,
1965 unsigned> &element_edges_on_boundary);
1972 void create_polylines_from_halo_elements_helper(
1973 const Vector<unsigned> &element_domain,
1974 std::map<GeneralisedElement*, unsigned> &element_to_global_index,
1975 std::set<FiniteElement*> &element_in_processor_pt,
1976 Vector<Vector<Vector<GeneralisedElement*> > > &input_halo_elements,
1977 std::map<std::pair<Node*,Node*>,
unsigned> &elements_edges_on_boundary,
1978 Vector<Vector<Vector<TriangleMeshPolyLine *> > > &output_polylines_pt);
1982 void break_loops_on_shared_polyline_helper(
1983 const unsigned &initial_shd_bnd_id,
1984 std::list<Node*> &input_nodes,
1985 Vector<FiniteElement*> &input_boundary_element_pt,
1986 Vector<int> &input_face_index_element,
1987 const int &input_connect_to_the_left,
1988 const int &input_connect_to_the_right,
1989 Vector<std::list<Node*> > &output_sorted_nodes_pt,
1990 Vector<Vector<FiniteElement*> > &output_boundary_element_pt,
1991 Vector<Vector<int> > &output_face_index_element,
1992 Vector<int> &output_connect_to_the_left,
1993 Vector<int> &output_connect_to_the_right);
1998 void break_loops_on_shared_polyline_load_balance_helper(
1999 const unsigned &initial_shd_bnd_id,
2000 std::list<Node*> &input_nodes,
2001 Vector<FiniteElement*> &input_boundary_element_pt,
2002 Vector<FiniteElement*> &input_boundary_face_element_pt,
2003 Vector<int> &input_face_index_element,
2004 const int &input_connect_to_the_left,
2005 const int &input_connect_to_the_right,
2006 Vector<std::list<Node*> > &output_sorted_nodes_pt,
2007 Vector<Vector<FiniteElement*> > &output_boundary_element_pt,
2008 Vector<Vector<FiniteElement*> > &output_boundary_face_element_pt,
2009 Vector<Vector<int> > &output_face_index_element,
2010 Vector<int> &output_connect_to_the_left,
2011 Vector<int> &output_connect_to_the_right);
2016 void create_shared_polyline(
const unsigned &my_rank,
2017 const unsigned &shd_bnd_id,
2018 const unsigned &iproc,
2019 const unsigned &jproc,
2020 std::list<Node*> &sorted_nodes,
2021 const int &root_edge_bnd_id,
2022 Vector<FiniteElement*>
2024 Vector<int> &face_index_ele,
2025 Vector<Vector<TriangleMeshPolyLine *> >
2026 &unsorted_polylines_pt,
2027 const int &connect_to_the_left_flag,
2028 const int &connect_to_the_right_flag);
2034 target_domain_for_local_non_halo_element)
2036 std::ostringstream error_stream;
2037 error_stream <<
"Empty default load balancing function called.\n";
2038 error_stream <<
"This should be overloaded in a specific " 2039 <<
"RefineableTriangleMesh\n";
2040 throw OomphLibError(error_stream.str(),
2041 OOMPH_CURRENT_FUNCTION,
2042 OOMPH_EXCEPTION_LOCATION);
2047 virtual void reset_boundary_element_info(
2048 Vector<unsigned> &ntmp_boundary_elements,
2049 Vector<Vector<unsigned> > &ntmp_boundary_elements_in_region,
2050 Vector<FiniteElement*> &deleted_elements);
2052 #endif // #ifdef OOMPH_HAS_MPI 2059 void output_boundary_coordinates(
const unsigned &b,
2060 std::ostream &outfile);
2078 return x < p.
x || (x == p.
x && y < p.
y);
2088 return (A.
x - O.
x) * (B.
y - O.
y) - (A.
y - O.
y) * (B.
x - O.
x);
2095 int n = P.size(), k = 0;
2096 std::vector<Point> H(2*n);
2099 std::sort(P.begin(), P.end());
2102 for (
int i = 0; i < n; ++i) {
2103 while (k >= 2 && cross(H[k-2], H[k-1], P[i]) <= 0) k--;
2108 for (
int i = n-2, t = k+1; i >= 0; i--) {
2109 while (k >= t && cross(H[k-2], H[k-1], P[i]) <= 0) k--;
2131 template<
class ELEMENT>
2133 public virtual RefineableMeshBase
2142 typedef void (*MeshUpdateFctPt)(Mesh* mesh_pt);
2150 typedef void (*InternalHolePointUpdateFctPt)(
2151 const unsigned &ihole, TriangleMeshPolygon* poly_pt);
2153 #ifdef OOMPH_HAS_TRIANGLE_LIB 2158 TimeStepper* time_stepper_pt=
2159 &Mesh::Default_TimeStepper)
2164 initialise_adaptation_data();
2167 initialise_boundary_refinement_data();
2170 #endif // #ifdef OOMPH_HAS_TRIANGLE_LIB 2174 const std::string& element_file_name,
2175 const std::string& poly_file_name,
2176 TimeStepper* time_stepper_pt=
2177 &Mesh::Default_TimeStepper,
2178 const bool &allow_automatic_creation_of_vertices_on_boundaries=
true)
2183 allow_automatic_creation_of_vertices_on_boundaries)
2187 create_polylines_from_polyfiles(node_file_name, poly_file_name);
2190 initialise_adaptation_data();
2193 initialise_boundary_refinement_data();
2198 #ifdef OOMPH_HAS_TRIANGLE_LIB 2205 TriangulateIO& triangulate_io,
2206 TimeStepper* time_stepper_pt=
2207 &Mesh::Default_TimeStepper,
2208 const bool &use_attributes=
false,
2210 &allow_automatic_creation_of_vertices_on_boundaries=
true,
2211 OomphCommunicator* comm_pt = 0)
2214 initialise_adaptation_data();
2217 initialise_boundary_refinement_data();
2220 this->Time_stepper_pt=time_stepper_pt;
2223 TriangulateIO triangle_refine;
2226 TriangleHelper::initialise_triangulateio(this->Triangulateio);
2229 this->Triangulateio_exists=
true;
2232 this->refine_triangulateio(triangulate_io,
2237 std::stringstream input_string_stream;
2238 input_string_stream<<
"-pq30-ra";
2241 if (!allow_automatic_creation_of_vertices_on_boundaries)
2242 {input_string_stream<<
" -YY";}
2246 allow_automatic_creation_of_vertices_on_boundaries;
2252 char triswitches[100];
2253 sprintf(triswitches,
"%s",input_string_stream.str().c_str());
2256 triangulate(triswitches,&triangle_refine,&this->Triangulateio,0);
2259 this->Tmp_mesh_pt=
new TriangleScaffoldMesh(this->Triangulateio);
2262 this->build_from_scaffold(time_stepper_pt,use_attributes);
2265 delete this->Tmp_mesh_pt;
2266 this->Tmp_mesh_pt=0;
2269 bool clear_hole_data=
false;
2270 TriangleHelper::clear_triangulateio(triangle_refine,clear_hole_data);
2272 #ifdef OOMPH_HAS_MPI 2283 unsigned nb=nboundary();
2284 for (
unsigned b=0;b<nb;b++)
2286 this->
template setup_boundary_coordinates<ELEMENT>(b);
2292 #endif // #ifdef OOMPH_HAS_TRIANGLE_LIB 2300 {Print_timings_transfering_target_areas=
true;}
2305 {Print_timings_transfering_target_areas=
false;}
2309 {Disable_projection=
false;}
2313 {Disable_projection=
true;}
2317 {Print_timings_projection=
true;}
2321 {Print_timings_projection=
false;}
2339 return Max_sample_points_for_limited_locate_zeta_during_target_area_transfer;
2354 {
return Use_iterative_solver_for_projection;}
2359 {Use_iterative_solver_for_projection=
true;}
2364 {Use_iterative_solver_for_projection=
false;}
2368 {set_print_level_timings_adaptation(print_level);}
2372 {Print_timings_level_adaptation=0;}
2377 const unsigned max_print_level = 3;
2379 if (print_level > max_print_level)
2381 Print_timings_level_adaptation=max_print_level;
2385 Print_timings_level_adaptation=print_level;
2391 {set_print_level_timings_load_balance(print_level);}
2395 {Print_timings_level_load_balance=0;}
2400 const unsigned max_print_level = 3;
2402 if (print_level > max_print_level)
2404 Print_timings_level_load_balance=max_print_level;
2408 Print_timings_level_load_balance=print_level;
2415 outfile << std::endl;
2416 outfile <<
"Targets for mesh adaptation: " << std::endl;
2417 outfile <<
"---------------------------- " << std::endl;
2418 outfile <<
"Target for max. error: " << Max_permitted_error << std::endl;
2419 outfile <<
"Target for min. error: " << Min_permitted_error << std::endl;
2420 outfile <<
"Target min angle: " << Min_permitted_angle << std::endl;
2421 outfile <<
"Min. allowed element size: " << Min_element_size << std::endl;
2422 outfile <<
"Max. allowed element size: " << Max_element_size << std::endl;
2423 outfile <<
"Don't unrefine if less than " << Max_keep_unrefined
2424 <<
" elements need unrefinement." << std::endl;
2425 outfile << std::endl;
2432 unsigned nelem=nelement();
2433 Vector<double> elem_error(nelem,DBL_MAX);
2436 double backup=Min_element_size;
2439 double orig_max_area, orig_min_area;
2440 this->max_and_min_element_size(orig_max_area, orig_min_area);
2443 Min_element_size=orig_min_area/3.0;
2449 Min_element_size=backup;
2457 throw OomphLibError(
"unrefine_uniformly() not implemented yet",
2458 OOMPH_CURRENT_FUNCTION,
2459 OOMPH_EXCEPTION_LOCATION);
2465 void adapt(
const Vector<double>& elem_error);
2473 return Mesh_update_fct_pt;
2481 return Internal_hole_point_update_fct_pt;
2487 #ifdef OOMPH_HAS_MPI 2490 std::map<unsigned, Vector<Node*> >::iterator it =
2491 Sorted_shared_boundary_node_pt.find(b);
2492 if (it == Sorted_shared_boundary_node_pt.end())
2494 std::ostringstream error_message;
2496 <<
"The boundary ("<<b<<
") is not marked as shared\n";
2497 throw OomphLibError(error_message.str(),
2498 OOMPH_CURRENT_FUNCTION,
2499 OOMPH_EXCEPTION_LOCATION);
2501 return (*it).second.size();
2505 {Sorted_shared_boundary_node_pt.clear();}
2509 std::map<unsigned, Vector<Node*> >::iterator it =
2510 Sorted_shared_boundary_node_pt.find(b);
2511 if (it == Sorted_shared_boundary_node_pt.end())
2513 std::ostringstream error_message;
2515 <<
"The boundary ("<<b<<
") is not marked as shared\n";
2516 throw OomphLibError(error_message.str(),
2517 OOMPH_CURRENT_FUNCTION,
2518 OOMPH_EXCEPTION_LOCATION);
2520 return (*it).second[i];
2526 std::map<unsigned, Vector<Node*> >::iterator it =
2527 Sorted_shared_boundary_node_pt.find(b);
2528 if (it == Sorted_shared_boundary_node_pt.end())
2530 std::ostringstream error_message;
2532 <<
"The boundary ("<<b<<
") is not marked as shared\n";
2533 throw OomphLibError(error_message.str(),
2534 OOMPH_CURRENT_FUNCTION,
2535 OOMPH_EXCEPTION_LOCATION);
2537 return (*it).second;
2540 #endif // #ifdef OOMPH_HAS_MPI 2544 void create_polylines_from_polyfiles(
const std::string& node_file_name,
2545 const std::string& poly_file_name);
2547 #ifdef OOMPH_HAS_MPI 2550 void fill_boundary_elements_and_nodes_for_internal_boundaries();
2556 void fill_boundary_elements_and_nodes_for_internal_boundaries(
2557 std::ofstream& outfile);
2562 OomphCommunicator* comm_pt, std::istream &restart_file)
2569 this->fill_boundary_elements_and_nodes_for_internal_boundaries();
2573 this->reset_shared_boundary_elements_and_nodes(comm_pt);
2577 this->sort_nodes_on_shared_boundaries();
2580 this->reset_halo_haloed_scheme();
2583 const unsigned noriginal_boundaries =
2584 this->initial_shared_boundary_id();
2585 this->set_nboundary(noriginal_boundaries);
2589 for (
unsigned b = 0; b < noriginal_boundaries; b++)
2594 this->identify_boundary_segments_and_assign_initial_zeta_values(b,
this);
2596 if (this->boundary_geom_object_pt(b) != 0)
2599 this->
template setup_boundary_coordinates<ELEMENT>(b);
2604 this->snap_nodes_onto_geometric_objects();
2610 #endif // #ifdef OOMPH_HAS_MPI 2615 #ifdef OOMPH_HAS_MPI 2618 unsigned my_rank = 0;
2628 const unsigned ninternal = this->Internal_polygon_pt.size();
2629 for (
unsigned i_internal = 0; i_internal < ninternal; i_internal++)
2631 this->update_polygon_after_restart(
2632 this->Internal_polygon_pt[i_internal]);
2637 for (
unsigned i_outer = 0; i_outer < nouter; i_outer++)
2642 #ifdef OOMPH_HAS_MPI 2647 const unsigned ncurves = this->nshared_boundary_curves(my_rank);
2648 for (
unsigned nc = 0; nc < ncurves; nc ++)
2651 this->update_shared_curve_after_restart(
2652 this->Shared_boundary_polyline_pt[my_rank][nc]
2657 #endif // #ifdef OOMPH_HAS_MPI 2659 const unsigned n_open_polyline = this->Internal_open_curve_pt.size();
2660 for (
unsigned i = 0; i < n_open_polyline; i++)
2662 this->update_open_curve_after_restart(
2663 this->Internal_open_curve_pt[i]);
2668 #ifdef OOMPH_HAS_MPI 2672 void load_balance(
const Vector<unsigned>&
2673 input_target_domain_for_local_non_halo_element);
2678 void get_shared_boundary_elements_and_face_indexes(
2679 const Vector<FiniteElement*> &first_element_pt,
2680 const Vector<FiniteElement*> &second_element_pt,
2681 Vector<FiniteElement*> &first_shared_boundary_element_pt,
2682 Vector<unsigned> &first_shared_boundary_element_face_index,
2683 Vector<FiniteElement*> &second_shared_boundary_element_pt,
2684 Vector<unsigned> &second_shared_boundary_element_face_index);
2689 void create_new_shared_boundaries(std::set<FiniteElement*>
2690 &element_in_processor_pt,
2691 Vector<Vector<FiniteElement*> >
2692 &new_shared_boundary_element_pt,
2693 Vector<Vector<unsigned> >
2694 &new_shared_boundary_element_face_index);
2699 void compute_shared_node_degree_helper(Vector<Vector<FiniteElement*> >
2700 &unsorted_face_ele_pt,
2701 std::map<Node*, unsigned>
2702 &global_node_degree);
2708 void create_adjacency_matrix_new_shared_edges_helper(
2709 Vector<Vector<FiniteElement*> > &unsorted_face_ele_pt,
2710 Vector<Vector<Node*> > &tmp_sorted_shared_node_pt,
2711 std::map<Node*, Vector<Vector<unsigned> > > &node_alias,
2712 Vector<Vector<Vector<unsigned> > > &adjacency_matrix);
2716 void get_shared_boundary_segment_nodes_helper(
2717 const unsigned &shd_bnd_id, Vector<Vector<Node*> > &tmp_segment_nodes);
2719 #endif // #ifdef OOMPH_HAS_MPI 2725 void get_boundary_segment_nodes_helper(
2726 const unsigned &b, Vector<Vector<Node*> > &tmp_segment_nodes);
2731 {Do_boundary_unrefinement_constrained_by_target_areas =
true;}
2734 {Do_boundary_unrefinement_constrained_by_target_areas =
false;}
2737 {Do_boundary_refinement_constrained_by_target_areas =
true;}
2740 {Do_boundary_refinement_constrained_by_target_areas =
false;}
2745 {Do_shared_boundary_unrefinement_constrained_by_target_areas =
true;}
2748 {Do_shared_boundary_unrefinement_constrained_by_target_areas =
false;}
2751 {Do_shared_boundary_refinement_constrained_by_target_areas =
true;}
2754 {Do_shared_boundary_refinement_constrained_by_target_areas =
false;}
2770 std::set<Vector<double> > &vertices)
2773 std::map<unsigned, std::set<Vector<double> > >::
2774 iterator it = Boundary_connections_pt.find(b);
2776 if (it != Boundary_connections_pt.end())
2779 vertices = (*it).second;
2792 const void synchronize_shared_boundary_connections();
2797 void add_vertices_for_non_deletion();
2802 void add_non_delete_vertices_from_boundary_helper(
2803 Vector<Vector<Node*> > src_bound_segment_node_pt,
2804 Vector<Vector<Node*> > dst_bound_segment_node_pt,
2805 const unsigned &dst_bnd_id,
const unsigned &dst_bnd_chunk);
2810 void create_temporary_boundary_connections(
2811 Vector<TriangleMeshPolygon *> &tmp_outer_polygons_pt,
2812 Vector<TriangleMeshOpenCurve *> &tmp_open_curves_pt);
2819 void restore_boundary_connections(
2820 Vector<TriangleMeshPolyLine*> &resume_initial_connection_polyline_pt,
2821 Vector<TriangleMeshPolyLine*> &resume_final_connection_polyline_pt);
2829 void restore_polyline_connections_helper(
2830 TriangleMeshPolyLine* polyline_pt,
2831 Vector<TriangleMeshPolyLine*> &resume_initial_connection_polyline_pt,
2832 Vector<TriangleMeshPolyLine*> &resume_final_connection_polyline_pt);
2840 void resume_boundary_connections(
2841 Vector<TriangleMeshPolyLine*> &resume_initial_connection_polyline_pt,
2842 Vector<TriangleMeshPolyLine*> &resume_final_connection_polyline_pt);
2846 bool get_connected_vertex_number_on_dst_boundary(
2847 Vector<double> &vertex_coordinates,
2848 const unsigned &dst_b_id,
unsigned &vertex_number);
2856 bool unrefine_boundary(
const unsigned &b,
2858 Vector<Vector<double> > &vector_bnd_vertices,
2859 double &unrefinement_tolerance,
2860 const bool &check_only =
false);
2868 bool refine_boundary(Mesh* face_mesh_pt,
2869 Vector<Vector<double> > &vector_bnd_vertices,
2870 double &refinement_tolerance,
2871 const bool &check_only =
false);
2877 bool apply_max_length_constraint(Mesh* face_mesh_pt,
2878 Vector<Vector<double> >
2879 &vector_bnd_vertices,
2880 double &max_length_constraint);
2887 bool unrefine_boundary_constrained_by_target_area(
2888 const unsigned &b,
const unsigned &c,
2889 Vector<Vector<double> > &vector_bnd_vertices,
2890 double &unrefinement_tolerance, Vector<double> &area_constraint);
2897 bool refine_boundary_constrained_by_target_area(
2898 MeshAsGeomObject* mesh_geom_obj_pt,
2899 Vector<Vector<double> > &vector_bnd_vertices,
2900 double &refinement_tolerance, Vector<double> &area_constraint);
2907 bool unrefine_shared_boundary_constrained_by_target_area(
2908 const unsigned &b,
const unsigned &c,
2909 Vector<Vector<double> > &vector_bnd_vertices,
2910 Vector<double> &area_constraint);
2917 bool refine_shared_boundary_constrained_by_target_area(
2918 Vector<Vector<double> > &vector_bnd_vertices,
2919 Vector<double> &area_constraint);
2938 Do_boundary_unrefinement_constrained_by_target_areas =
true;
2939 Do_boundary_refinement_constrained_by_target_areas =
true;
2940 Do_shared_boundary_unrefinement_constrained_by_target_areas =
true;
2941 Do_shared_boundary_refinement_constrained_by_target_areas =
true;
2944 #ifdef OOMPH_HAS_MPI 2954 void sort_nodes_on_shared_boundaries();
2959 void reset_shared_boundary_elements_and_nodes(
const bool flush_elements
2961 const bool update_elements
2963 const bool flush_nodes
2965 const bool update_nodes
2972 void reset_halo_haloed_scheme();
2981 void compute_global_node_names_and_shared_nodes(
2982 Vector<Vector<Vector<std::map<unsigned, Node*> > > >
2983 &other_proc_shd_bnd_node_pt,
2984 Vector<Vector<Vector<unsigned> > > &global_node_names,
2985 std::map<Vector<unsigned>,
unsigned> &node_name_to_global_index,
2986 Vector<Node*> &global_shared_node_pt);
2992 void send_boundary_node_info_of_shared_nodes(
2993 Vector<Vector<Vector<unsigned> > > &global_node_names,
2994 std::map<Vector<unsigned>,
unsigned> &node_name_to_global_index,
2995 Vector<Node*> &global_shared_node_pt);
3000 void reset_halo_haloed_scheme_helper(
3001 Vector<Vector<Vector<std::map<unsigned, Node*> > > >
3002 &other_proc_shd_bnd_node_pt,
3003 Vector<Vector<Node *> > &iproc_currently_created_nodes_pt,
3004 Vector<Vector<Vector<unsigned> > > &global_node_names,
3005 std::map<Vector<unsigned>,
unsigned> &node_name_to_global_index,
3006 Vector<Node*> &global_shared_node_pt);
3021 Vector<FiniteElement*> &new_elements_on_domain,
3022 FiniteElement* &ele_pt)
3025 const unsigned nnew_elements_on_domain = new_elements_on_domain.size();
3028 bool already_on_new_domain =
false;
3029 unsigned new_domain_ele_index = 0;
3031 for (
unsigned e = 0; e < nnew_elements_on_domain; e++)
3033 if (ele_pt == new_elements_on_domain[e])
3036 already_on_new_domain =
true;
3038 new_domain_ele_index = e;
3044 if (!already_on_new_domain)
3047 new_elements_on_domain.push_back(ele_pt);
3049 return nnew_elements_on_domain;
3054 return new_domain_ele_index;
3063 void get_required_elemental_information_load_balance_helper(
3065 Vector<Vector<FiniteElement*> > &f_haloed_ele_pt,
3066 FiniteElement* ele_pt);
3071 Vector<Node*> &new_nodes_on_domain,
3075 const unsigned nnew_nodes_on_domain = new_nodes_on_domain.size();
3078 bool already_on_new_domain =
false;
3079 unsigned new_domain_node_index = 0;
3081 for (
unsigned n = 0; n < nnew_nodes_on_domain; n++)
3083 if (node_pt == new_nodes_on_domain[n])
3086 already_on_new_domain =
true;
3088 new_domain_node_index = n;
3094 if (!already_on_new_domain)
3097 new_nodes_on_domain.push_back(node_pt);
3099 return nnew_nodes_on_domain;
3104 return new_domain_node_index;
3110 void add_node_load_balance_helper(
unsigned& iproc,
3111 Vector<Vector<FiniteElement*> >
3113 Vector<Node*> &new_nodes_on_domain,
3124 void get_required_nodal_information_load_balance_helper(
3125 Vector<Vector<FiniteElement*> > &f_halo_ele_pt,
3132 void create_element_load_balance_helper(
3134 Vector<Vector<FiniteElement*> > &f_haloed_ele_pt,
3135 Vector<Vector<std::map<unsigned,FiniteElement*> > >
3136 &received_old_haloed_element_pt,
3137 Vector<FiniteElement*> &new_elements_on_domain,
3138 Vector<Node*> &new_nodes_on_domain,
3139 Vector<Vector<Vector<std::map<unsigned, Node*> > > >
3140 &other_proc_shd_bnd_node_pt,
3141 Vector<Vector<Vector<unsigned> > > &global_node_names,
3142 std::map<Vector<unsigned>,
unsigned> &node_name_to_global_index,
3143 Vector<Node*> &global_shared_node_pt);
3150 void add_element_load_balance_helper(
const unsigned &iproc,
3151 Vector<Vector<std::map<
3152 unsigned,FiniteElement*> > >
3153 &received_old_haloed_element_pt,
3154 FiniteElement* ele_pt);
3157 void add_received_node_load_balance_helper(
3159 Vector<Vector<FiniteElement*> > &f_haloed_ele_pt,
3160 Vector<Vector<std::map<unsigned,FiniteElement*> > >
3161 &received_old_haloed_element_pt,
3162 Vector<Node*> &new_nodes_on_domain,
3163 Vector<Vector<Vector<std::map<unsigned, Node*> > > >
3164 &other_proc_shd_bnd_node_pt,
3165 unsigned& iproc,
unsigned& node_index,
3166 FiniteElement*
const &new_el_pt,
3167 Vector<Vector<Vector<unsigned> > > &global_node_names,
3168 std::map<Vector<unsigned>,
unsigned> &node_name_to_global_index,
3169 Vector<Node*> &global_shared_node_pt);
3174 void construct_new_node_load_balance_helper(
3176 Vector<Vector<FiniteElement*> > &f_haloed_ele_pt,
3177 Vector<Vector<std::map<unsigned,FiniteElement*> > >
3178 &received_old_haloed_element_pt,
3179 Vector<Node*> &new_nodes_on_domain,
3180 Vector<Vector<Vector<std::map<unsigned, Node*> > > >
3181 &other_proc_shd_bnd_node_pt,
3182 unsigned& iproc,
unsigned& node_index,
3183 FiniteElement*
const &new_el_pt,
3184 Vector<Vector<Vector<unsigned> > > &global_node_names,
3185 std::map<Vector<unsigned>,
unsigned> &node_name_to_global_index,
3186 Vector<Node*> &global_shared_node_pt);
3211 #ifdef ANNOTATE_REFINEABLE_TRIANGLE_MESH_COMMUNICATION 3228 GeneralisedElement*& el_pt)
3231 unsigned n_haloed=this->nroot_haloed_element(p);
3234 bool already_haloed_element=
false;
3235 unsigned haloed_el_index=0;
3236 for (
unsigned eh=0;eh<n_haloed;eh++)
3238 if (el_pt==this->root_haloed_element_pt(p, eh))
3241 already_haloed_element=
true;
3249 if (!already_haloed_element)
3252 this->add_root_haloed_element_pt(p, el_pt);
3259 return haloed_el_index;
3268 unsigned n_haloed_nod=this->nhaloed_node(p);
3271 bool is_an_haloed_node=
false;
3272 unsigned haloed_node_index=0;
3273 for (
unsigned k=0;k<n_haloed_nod;k++)
3275 if (nod_pt==this->haloed_node_pt(p,k))
3277 is_an_haloed_node=
true;
3278 haloed_node_index=k;
3284 if (!is_an_haloed_node)
3287 this->add_haloed_node_pt(p, nod_pt);
3289 return n_haloed_nod;
3294 return haloed_node_index;
3301 void get_required_elemental_information_helper(
unsigned& iproc,
3302 FiniteElement* ele_pt);
3307 void get_required_nodal_information_helper(
unsigned& iproc, Node* nod_pt);
3310 void add_haloed_node_helper(
unsigned& iproc, Node* nod_pt);
3313 void send_and_receive_elements_nodes_info(
int& send_proc,
int &recv_proc);
3317 void create_halo_element(
unsigned &iproc,
3318 Vector<Node*> &new_nodes_on_domain,
3319 Vector<Vector<Vector<std::map<
unsigned,
3320 Node*> > > > &other_proc_shd_bnd_node_pt,
3321 Vector<Vector<Vector<unsigned> > >
3323 std::map<Vector<unsigned>,
unsigned>
3324 &node_name_to_global_index,
3325 Vector<Node*> &global_shared_node_pt);
3331 void add_halo_element_helper(
unsigned& iproc, FiniteElement* ele_pt);
3334 void add_halo_node_helper(Node* &new_nod_pt,
3335 Vector<Node*> &new_nodes_on_domain,
3336 Vector<Vector<Vector<std::map<
unsigned,
3338 &other_proc_shd_bnd_node_pt,
3340 unsigned& node_index,
3341 FiniteElement*
const &new_el_pt,
3342 Vector<Vector<Vector<unsigned> > >
3344 std::map<Vector<unsigned>,
unsigned>
3345 &node_name_to_global_index,
3346 Vector<Node*> &global_shared_node_pt);
3350 void construct_new_halo_node_helper(Node* &new_nod_pt,
3351 Vector<Node*> &new_nodes_on_domain,
3352 Vector<Vector<Vector<std::map<
unsigned,
3354 &other_proc_shd_bnd_node_pt,
3356 unsigned& node_index,
3357 FiniteElement*
const &new_el_pt,
3358 Vector<Vector<Vector<unsigned> > >
3360 std::map<Vector<unsigned>,
unsigned>
3361 &node_name_to_global_index,
3362 Vector<Node*> &global_shared_node_pt);
3368 void update_other_proc_shd_bnd_node_helper
3370 Vector<Vector<Vector<std::map<unsigned, Node*> > > >
3371 &other_proc_shd_bnd_node_pt,
3372 Vector<unsigned> &other_processor_1,
3373 Vector<unsigned> &other_processor_2,
3374 Vector<unsigned> &other_shared_boundaries,
3375 Vector<unsigned> &other_indexes,
3376 Vector<Vector<Vector<unsigned> > > &global_node_names,
3377 std::map<Vector<unsigned>,
unsigned> &node_name_to_global_index,
3378 Vector<Node*> &global_shared_node_pt);
3384 #endif // #ifdef OOMPH_HAS_MPI 3393 bool update_polygon_using_face_mesh(TriangleMeshPolygon* polygon_pt,
3394 const bool& check_only=
false);
3403 bool update_open_curve_using_face_mesh(
3404 TriangleMeshOpenCurve* open_polyline_pt,
3405 const bool& check_only=
false);
3412 virtual bool surface_remesh_for_inner_hole_boundaries(
3413 Vector<Vector<double> > &internal_point_coord,
3414 const bool& check_only=
false);
3424 void create_unsorted_face_mesh_representation(
3425 const unsigned &boundary_id,
3426 Mesh* face_mesh_pt);
3432 void create_sorted_face_mesh_representation(
3433 const unsigned &boundary_id,
3435 std::map<FiniteElement*, bool> &is_inverted,
3436 bool &inverted_face_mesh);
3441 void get_face_mesh_representation(TriangleMeshPolygon* polygon_pt,
3442 Vector<Mesh*>& face_mesh_pt);
3446 void get_face_mesh_representation(
3447 TriangleMeshOpenCurve* open_polyline_pt,
3448 Vector<Mesh*>& face_mesh_pt);
3451 void update_polygon_after_restart(TriangleMeshPolygon* &polygon_pt);
3454 void update_open_curve_after_restart(TriangleMeshOpenCurve* &open_curve_pt);
3458 bool update_polygon_using_elements_area(
3459 TriangleMeshPolygon* &polygon_pt,
const Vector<double> &target_area);
3463 bool update_open_curve_using_elements_area(
3464 TriangleMeshOpenCurve* &open_curve_pt,
const Vector<double> &target_area);
3466 #ifdef OOMPH_HAS_MPI 3469 bool update_shared_curve_using_elements_area(
3470 Vector<TriangleMeshPolyLine*> &vector_polyline_pt,
3471 const Vector<double> &target_areas);
3474 void update_shared_curve_after_restart(Vector<TriangleMeshPolyLine*>
3475 &vector_polyline_pt);
3477 #endif // #ifdef OOMPH_HAS_MPI 3485 this->Nbin_x_for_area_transfer=100;
3490 this->Nbin_y_for_area_transfer=100;
3494 Max_sample_points_for_limited_locate_zeta_during_target_area_transfer=5;
3497 this->Max_element_size=1.0;
3498 this->Min_element_size=0.001;
3499 this->Min_permitted_angle=15.0;
3502 this->Disable_projection=
false;
3505 this->Use_iterative_solver_for_projection=
true;
3508 this->Print_timings_level_adaptation=0;
3511 this->Print_timings_level_load_balance=0;
3515 this->Print_timings_transfering_target_areas=
false;
3518 this->Print_timings_projection=
false;
3524 Mesh_update_fct_pt=0;
3528 Internal_hole_point_update_fct_pt=0;
3532 #ifdef OOMPH_HAS_TRIANGLE_LIB 3536 void refine_triangulateio(TriangulateIO& triangulate_io,
3537 const Vector<double> &target_area,
3538 TriangulateIO &triangle_refine);
3540 #endif // #ifdef OOMPH_HAS_TRIANGLE_LIB 3545 Vector<double> &target_area)
3547 double min_angle=DBL_MAX;
3548 unsigned count_unrefined=0;
3549 unsigned count_refined=0;
3550 this->Nrefinement_overruled=0;
3553 std::map<FiniteElement*,double> max_area_from_region;
3554 for (std::map<unsigned, double>::iterator it=this->
Regions_areas.begin();
3557 unsigned r=(*it).first;
3558 unsigned nel=this->nregion_element(r);
3559 for(
unsigned e=0;e<nel;e++)
3561 max_area_from_region[this->region_element_pt(r,e)]=(*it).second;
3565 unsigned nel=this->nelement();
3566 for (
unsigned e=0;e<nel;e++)
3569 FiniteElement* el_pt=this->finite_element_pt(e);
3572 double area=el_pt->size();
3576 double ax=el_pt->node_pt(0)->x(0);
3577 double ay=el_pt->node_pt(0)->x(1);
3579 double bx=el_pt->node_pt(1)->x(0);
3580 double by=el_pt->node_pt(1)->x(1);
3582 double cx=el_pt->node_pt(2)->x(0);
3583 double cy=el_pt->node_pt(2)->x(1);
3587 acos(((ax-cx)*(bx-cx)+(ay-cy)*(by-cy))/
3588 (sqrt((ax-cx)*(ax-cx)+(ay-cy)*(ay-cy))*
3589 sqrt((bx-cx)*(bx-cx)+(by-cy)*(by-cy))))*
3590 180.0/MathematicalConstants::Pi;
3591 min_angle=std::min(min_angle,angle0);
3594 acos(((ax-bx)*(cx-bx)+(ay-by)*(cy-by))/
3595 (sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by))*
3596 sqrt((cx-bx)*(cx-bx)+(cy-by)*(cy-by))))*
3597 180.0/MathematicalConstants::Pi;
3598 min_angle=std::min(min_angle,angle1);
3600 double angle2=180.0-angle0-angle1;
3601 min_angle=std::min(min_angle,angle2);
3606 double size_ratio=3.0;
3607 if (elem_error[e]>max_permitted_error())
3610 target_area[e]=std::max(area/size_ratio,Min_element_size);
3613 target_area[e]=std::min(target_area[e],Max_element_size);
3615 if (target_area[e]!=Min_element_size)
3621 this->Nrefinement_overruled++;
3624 else if (elem_error[e]<min_permitted_error())
3627 target_area[e]=std::min(size_ratio*area,Max_element_size);
3630 target_area[e]=std::max(target_area[e],Min_element_size);
3632 if (target_area[e]!=Max_element_size)
3640 double area_leave_alone = std::max(area,Min_element_size);
3641 target_area[e] = std::min(area_leave_alone,Max_element_size);
3645 std::map<FiniteElement*,double>::iterator it=
3646 max_area_from_region.find(el_pt);
3647 if (it!=max_area_from_region.end())
3649 target_area[e]=std::min(target_area[e],(*it).second);
3656 this->Nrefined=count_refined;
3657 this->Nunrefined=count_unrefined;
3659 if (this->Nrefinement_overruled!=0)
3662 <<
"\nNOTE: Refinement of " 3663 << this->Nrefinement_overruled <<
" elements was " 3664 <<
"overruled \nbecause the target area would have " 3665 <<
"been below \nthe minimum permitted area of " 3667 <<
".\nYou can change the minimum permitted area with the\n" 3668 <<
"function RefineableTriangleMesh::min_element_size().\n\n";
3737 template<
class ELEMENT>
3739 public virtual SolidMesh
3744 #ifdef OOMPH_HAS_TRIANGLE_LIB 3750 TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper)
3755 set_lagrangian_nodal_coordinates();
3758 #endif // #ifdef OOMPH_HAS_TRIANGLE_LIB 3761 const std::string& node_file_name,
3762 const std::string& element_file_name,
3763 const std::string& poly_file_name,
3764 TimeStepper* time_stepper_pt=
3765 &Mesh::Default_TimeStepper,
3766 const bool &allow_automatic_creation_of_vertices_on_boundaries=
true)
3771 allow_automatic_creation_of_vertices_on_boundaries)
3774 set_lagrangian_nodal_coordinates();
3786 #ifdef OOMPH_HAS_TRIANGLE_LIB 3791 template<
class ELEMENT>
3794 public virtual SolidMesh
3802 TimeStepper* time_stepper_pt=
3803 &Mesh::Default_TimeStepper)
3810 set_lagrangian_nodal_coordinates();
3816 const Vector<double> &target_area,
3817 TriangulateIO& triangulate_io,
3818 TimeStepper* time_stepper_pt=
3819 &Mesh::Default_TimeStepper,
3820 const bool &use_attributes=
false,
3822 &allow_automatic_creation_of_vertices_on_boundaries=
true,
3823 OomphCommunicator* comm_pt = 0) :
3829 allow_automatic_creation_of_vertices_on_boundaries,
3833 set_lagrangian_nodal_coordinates();
3840 #endif // #ifdef OOMPH_HAS_TRIANGLE_LIB bool Print_timings_transfering_target_areas
Enable/disable printing timings for transfering target areas.
RefineableSolidTriangleMesh(TriangleMeshParameters &triangle_mesh_parameters, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Build mesh, based on the specifications on TriangleMeshParameter.
void disable_timings_projection()
Disables info. and timings for projection.
Vector< unsigned > & shared_boundaries_ids(const unsigned &p, const unsigned &q)
Node *& boundary_segment_node_pt(const unsigned &b, const unsigned &s, const unsigned &n)
Return pointer to node n on boundary b.
bool use_iterative_solver_for_projection()
double Max_element_size
Max permitted element size.
bool Do_boundary_refinement_constrained_by_target_areas
Flag that enables or disables boundary refinement (true by default)
void enable_automatic_creation_of_vertices_on_boundaries()
double & min_element_size()
Min element size allowed during adaptation.
virtual void load_balance(const Vector< unsigned > &target_domain_for_local_non_halo_element)
Virtual function to perform the load balance routines.
Vector< TriangleMeshOpenCurve * > Internal_open_curves_pt
Internal boundaries.
const unsigned nshared_boundary_node(const unsigned &b)
void enable_timings_projection()
Enables info. and timings for projection.
Unstructured refineable Triangle Mesh upgraded to solid mesh.
std::map< unsigned, Vector< double > > & regions_coordinates()
Helper function for getting access to the regions coordinates.
Vector< TriangleMeshClosedCurve * > Internal_closed_curve_pt
Internal closed boundaries.
std::map< unsigned, double > Regions_areas
Target areas for regions; defaults to 0.0 which (luckily) implies "no specific target area" for trian...
void enable_shared_boundary_refinement_constrained_by_target_areas()
void enable_projection()
Enables the solution projection step during adaptation.
virtual ~RefineableTriangleMesh()
Empty Destructor.
void initialise_adaptation_data()
Helper function to initialise data associated with adaptation.
const unsigned nshared_boundaries() const
void disable_shared_boundary_unrefinement_constrained_by_target_areas()
bool Disable_projection
Enable/disable solution projection during adaptation.
MeshUpdateFctPt & mesh_update_fct_pt()
Access to function pointer to function that updates the mesh following the snapping of boundary nodes...
std::map< unsigned, unsigned > Shared_boundary_overlaps_internal_boundary
Stores information about those shared boundaries that lie over or over a segment of an internal bound...
Vector< TriangleMeshClosedCurve * > & outer_boundary_pt()
Helper function for getting access to the outer boundary.
bool is_internal_boundary_refinement_allowed() const
Helper function for getting the status of boundary refinement.
void set_target_area_for_region(const unsigned &i, const double &area)
Helper function to specify target area for region.
RefineableTriangleMesh(const Vector< double > &target_area, TriangulateIO &triangulate_io, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false, const bool &allow_automatic_creation_of_vertices_on_boundaries=true, OomphCommunicator *comm_pt=0)
Build mesh from specified triangulation and associated target areas for elements in it NOTE: This is ...
void update_polyline_representation_from_restart()
Method used to update the polylines representation after restart.
Vector< TriangleMeshOpenCurve * > internal_open_curves_pt() const
Helper function for getting the internal open boundaries.
void reestablish_distribution_info_for_restart(OomphCommunicator *comm_pt, std::istream &restart_file)
const unsigned nshared_boundary_curves(const unsigned &p) const
virtual void reestablish_distribution_info_for_restart(OomphCommunicator *comm_pt, std::istream &restart_file)
std::map< unsigned, Vector< TriangleMeshPolyLine * > > Boundary_subpolylines
The polylines that will temporary represent the boundary that was splitted in the distribution proces...
TriangleMeshParameters(Vector< TriangleMeshClosedCurve *> &outer_boundary_pt)
void disable_internal_boundary_refinement()
Helper function for disabling the use of boundary refinement.
unsigned Counter_for_flat_packed_doubles
Counter used when processing vector of flat-packed doubles.
SolidTriangleMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &poly_file_name, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &allow_automatic_creation_of_vertices_on_boundaries=true)
unsigned try_to_add_node_pt_load_balance(Vector< Node *> &new_nodes_on_domain, Node *&node_pt)
Check if necessary to add the node to the new domain or if it has been already added.
Vector< TriangleMeshOpenCurve * > & internal_open_curves_pt()
Helper function for getting access to the internal open boundaries.
std::map< unsigned, Vector< int > > Face_index_at_shared_boundary
For the e-th finite element on shared boundary b, this is the index of the face that lies along that ...
void operator=(const TriangleMesh &)
Broken assignment operator.
unsigned try_to_add_root_haloed_element_pt(const unsigned &p, GeneralisedElement *&el_pt)
Check if necessary to add the element as haloed or if it has been previously added to the haloed sche...
void flush_face_index_at_shared_boundary()
void add_shared_boundary_node(const unsigned &b, Node *node_pt)
Add the node the shared boundary.
void initialise_boundary_refinement_data()
Set all the flags to true (the default values)
void add_region_coordinates(const unsigned &i, Vector< double > ®ion_coordinates)
Helper function for getting the extra regions.
bool Do_boundary_unrefinement_constrained_by_target_areas
Flag that enables or disables boundary unrefinement (true by default)
void enable_use_attributes()
Helper function for enabling the use of attributes.
Helper object for dealing with the parameters used for the TriangleMesh objects.
std::map< unsigned, double > Regions_areas
Target areas for regions; defaults to 0.0 which (luckily) implies "no specific target area" for trian...
void disable_boundary_refinement()
Helper function for disabling the use of boundary refinement.
void update_triangulateio()
Update the triangulateio object to the current nodal positions.
bool Triangulateio_exists
Boolean defining if Triangulateio object has been built or not.
void disable_print_timings_adaptation()
Disables printing of timings for adaptation.
std::map< unsigned, Vector< unsigned > > & shared_boundary_from_processors()
Return the association of the shared boundaries with the processors.
bool Allow_automatic_creation_of_vertices_on_boundaries
Vector< Node * > & boundary_segment_node_pt(const unsigned &b, const unsigned &s)
Return direct access to nodes associated with a segment of a given boundary.
std::map< unsigned, Vector< unsigned > > Shared_boundary_from_processors
Stores the processors involved in the generation of a shared boundary, in 2D two processors give rise...
Vector< unsigned > Flat_packed_unsigneds
Vector of flat-packed unsigneds to be communicated with other processors.
void refine_uniformly(DocInfo &doc_info)
Refine mesh uniformly and doc process.
coord2_t cross(const Point &O, const Point &A, const Point &B)
2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product. Returns a positive value, if OAB makes a counter-clockwise turn, negative for clockwise turn, and zero if the points are collinear.
Vector< Vector< double > > & extra_holes_coordinates()
Helper function for getting access to the extra holes.
Vector< TriangleMeshClosedCurve * > outer_boundary_pt() const
Helper function for getting the outer boundary.
InternalHolePointUpdateFctPt Internal_hole_point_update_fct_pt
Function pointer to function that can be set to update the position of the central point in internal ...
unsigned try_to_add_element_pt_load_balance(Vector< FiniteElement *> &new_elements_on_domain, FiniteElement *&ele_pt)
Check if necessary to add the element to the new domain or if it has been previously added...
bool is_boundary_refinement_allowed() const
Helper function for getting the status of boundary refinement.
bool Do_shared_boundary_refinement_constrained_by_target_areas
Flag that enables or disables boundary unrefinement (true by default)
const unsigned shared_boundaries_ids(const unsigned &p, const unsigned &q, const unsigned &i) const
std::map< unsigned, Vector< double > > Regions_coordinates
Store the coordinates for defining extra regions The key on the map is the region id...
unsigned max_sample_points_for_limited_locate_zeta_during_target_area_transfer()
Read/write access to number of sample points from which we try to locate zeta by Newton method when t...
TriangleMesh()
Empty constructor.
void disable_projection()
Disables the solution projection step during adaptation.
unsigned Nbin_y_for_area_transfer
Number of bins in the y-direction when transferring target areas by bin method. Only used if we don't...
std::map< unsigned, unsigned > & shared_boundary_overlaps_internal_boundary()
Gets the storage that indicates if a shared boundary is part of an internal boundary.
TriangleMeshParameters(TriangleMeshClosedCurve *outer_boundary_pt)
void flush_shared_boundary_polyline_pt()
bool is_mesh_distributed() const
Boolean to indicate if Mesh has been distributed.
Vector< TriangleMeshClosedCurve * > & internal_closed_curve_pt()
Helper function for getting access to the internal closed boundaries.
void remesh_from_internal_triangulateio()
Completely regenerate the mesh from the trianglateio structure.
void flush_shared_boundary_node(const unsigned &b)
Flush the boundary nodes associated to the shared boundary b.
Vector< unsigned > shared_boundaries_ids(const unsigned &p, const unsigned &q) const
Vector< Vector< Node * > > & boundary_segment_node_pt(const unsigned &b)
Return direct access to nodes associated with a boundary but sorted in segments.
void set_print_level_timings_adaptation(const unsigned &print_level)
Sets the printing level of timings for adaptation.
const unsigned initial_shared_boundary_id()
The initial boundary id for shared boundaries.
void disable_iterative_solver_for_projection()
bool First_time_compute_holes_left_by_halo_elements
Flag to know if it is the first time we are going to compute the holes left by the halo elements...
void set_communicator_pt(OomphCommunicator *comm_pt)
Function to set communicator (mesh is then assumed to be distributed)
void disable_shared_boundary_refinement_constrained_by_target_areas()
const unsigned nshared_boundaries(const unsigned &p, const unsigned &q) const
Access functions to boundaries shared with processors.
double & max_element_size()
Max element size allowed during adaptation.
bool Internal_boundary_refinement
Do not allow refinement of nodes on the internal boundary.
virtual ~TriangleMeshParameters()
Empty destructor.
TriangleMeshPolyLine * shared_boundary_polyline_pt(const unsigned &p, const unsigned &c, const unsigned &i) const
std::map< unsigned, Vector< Node * > > Shared_boundary_node_pt
Stores the boundary nodes adjacent to the shared boundaries, these nodes are a subset of the halo and...
virtual ~TriangleMesh()
Destructor.
Vector< double > Flat_packed_doubles
Vector of flat-packed doubles to be communicated with other processors.
std::vector< Point > convex_hull(std::vector< Point > P)
Returns a list of points on the convex hull in counter-clockwise order. Note: the last point in the r...
OomphCommunicator * Comm_pt
InternalHolePointUpdateFctPt & internal_hole_point_update_fct_pt()
Access to function pointer to can be used to generate the internal point for the ihole-th hole...
bool Use_iterative_solver_for_projection
unsigned nsorted_shared_boundary_node(unsigned &b)
const bool shared_boundary_overlaps_internal_boundary(const unsigned &shd_bnd_id)
Checks if the shared boundary overlaps an internal boundary.
unsigned Final_shared_boundary_id
The final boundary id for shared boundaries.
void enable_shared_boundary_unrefinement_constrained_by_target_areas()
Enable/disable unrefinement/refinement methods for shared boundaries.
void get_shared_boundaries_overlapping_internal_boundary(const unsigned &internal_bnd_id, Vector< unsigned > &shd_bnd_ids)
Gets the shared boundaries ids that overlap the given internal boundary.
bool Boundary_refinement
Do not allow refinement of nodes on the boundary.
Vector< unsigned > Oomph_vertex_nodes_id
Vector storing oomph-lib node number for all vertex nodes in the TriangulateIO representation of the ...
double Element_area
The element are when calling triangulate external routine.
std::map< unsigned, bool > Boundary_was_splitted
Flag to indicate if a polyline has been splitted during the distribution process, the boundary id of ...
RefineableTriangleMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &poly_file_name, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &allow_automatic_creation_of_vertices_on_boundaries=true)
Build mesh, based on the polyfiles.
void add_face_index_at_shared_boundary(const unsigned &b, const unsigned &i)
void add_shared_boundary_element(const unsigned &b, FiniteElement *ele_pt)
MeshUpdateFctPt Mesh_update_fct_pt
Function pointer to function that updates the mesh following the snapping of boundary nodes to the bo...
const unsigned read_unsigned_line_helper(std::istream &read_file)
bool Print_timings_projection
Enable/disable printing timings for projection.
double Min_element_size
Min permitted element size.
FiniteElement * shared_boundary_element_pt(const unsigned &b, const unsigned &e)
void disable_boundary_unrefinement_constrained_by_target_areas()
Vector< Vector< unsigned > > shared_boundaries_ids(const unsigned &p) const
void enable_timings_tranfering_target_areas()
Enables info. and timings for tranferring of target areas.
unsigned unrefine_uniformly()
Unrefine mesh uniformly: Return 0 for success, 1 for failure (if unrefinement has reached the coarses...
TriangleMesh(TriangleMeshParameters &triangle_mesh_parameters, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Build mesh, based on the specifications on TriangleMeshParameters.
std::map< unsigned, std::vector< bool > > Boundary_marked_as_shared_boundary
Flag to indicate if an internal boundary will be used as shared boundary because there is overlapping...
Vector< unsigned > & shared_boundary_from_processors(const unsigned &b)
void enable_print_timings_adaptation(const unsigned &print_level=1)
Enables printing of timings for adaptation.
Node * shared_boundary_node_pt(const unsigned &b, const unsigned &n)
double & element_area()
Helper function for getting access to the element area.
void disable_print_timings_load_balance()
Disables printing of timings for load balance.
void disable_use_attributes()
Helper function for disabling the use of attributes.
const unsigned nboundary_subpolylines(const unsigned &b)
Gets the number of subpolylines that create the boundarya (useful only when the boundary is marked as...
Vector< Vector< double > > extra_holes_coordinates() const
Helper function for getting the extra holes.
Vector< TriangleMeshClosedCurve * > Outer_boundary_pt
The outer boundary.
void disable_automatic_creation_of_vertices_on_boundaries()
virtual ~RefineableSolidTriangleMesh()
Empty Destructor.
std::map< unsigned, std::set< Vector< double > > > Boundary_connections_pt
A map that stores the vertices that receive connections, they are identified by the boundary number t...
TriangleScaffoldMesh * Tmp_mesh_pt
Temporary scaffold mesh.
void triangulate(char *triswitches, struct oomph::TriangulateIO *in, struct oomph::TriangulateIO *out, struct oomph::TriangulateIO *vorout)
TimeStepper * Time_stepper_pt
Timestepper used to build elements.
bool is_node_on_shared_boundary(const unsigned &b, Node *const &node_pt)
Is the node on the shared boundary.
const unsigned nshared_boundary_overlaps_internal_boundary()
Get the number of shared boundaries overlaping internal boundaries.
Vector< TriangleMeshClosedCurve * > internal_closed_curve_pt() const
Helper function for getting the internal closed boundaries.
void enable_boundary_refinement()
Helper function for enabling the use of boundary refinement.
RefineableTriangleMesh(TriangleMeshParameters &triangle_mesh_parameters, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Build mesh, based on the specifications on TriangleMeshParameters.
void doc_adaptivity_targets(std::ostream &outfile)
Doc the targets for mesh adaptation.
std::map< unsigned, Vector< Node * > > Sorted_shared_boundary_node_pt
Stores the nodes in the boundaries in the same order in all the processors Sorted_shared_boundary_nod...
void flush_sorted_shared_boundary_node()
double Min_permitted_angle
Min angle before remesh gets triggered.
TriangleMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &poly_file_name, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &allow_automatic_creation_of_vertices_on_boundaries=true)
Constructor with the input files.
unsigned Print_timings_level_adaptation
The printing level for adaptation.
Vector< std::string > Flat_packed_unsigneds_string
Temporary vector of strings to enable full annotation of RefineableTriangleMesh comms.
void enable_boundary_unrefinement_constrained_by_target_areas()
Enable/disable unrefinement/refinement methods for original boundaries.
virtual ~SolidTriangleMesh()
Empty Destructor.
SolidTriangleMesh(TriangleMeshParameters &triangle_mesh_parameters, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Build mesh, based on closed curve that specifies the outer boundary of the domain and any number of i...
std::map< unsigned, double > & target_area_for_region()
Helper function for getting access to the region's target areas.
void update_triangulateio(Vector< Vector< double > > &internal_point)
Update the TriangulateIO object to the current nodal position and the centre hole coordinates...
unsigned Max_sample_points_for_limited_locate_zeta_during_target_area_transfer
Default value for max. number of sample points used for locate_zeta when transferring target areas us...
double element_area() const
Helper function for getting the element area.
void disable_boundary_refinement_constrained_by_target_areas()
unsigned Initial_shared_boundary_id
The initial boundary id for shared boundaries.
const unsigned nshared_boundary_polyline(const unsigned &p, const unsigned &c) const
void disable_timings_tranfering_target_areas()
Disables info. and timings for tranferring of target areas.
Unstructured Triangle Mesh upgraded to solid mesh.
double compute_area_target(const Vector< double > &elem_error, Vector< double > &target_area)
Compute target area based on the element's error and the error target; return minimum angle (in degre...
void flush_shared_boundary_element(const unsigned &b)
Vector< Vector< double > > Extra_holes_coordinates
Store the coordinates for defining extra holes.
const unsigned nshared_boundary_element(const unsigned &b)
bool Use_attributes
Define the use of attributes (regions)
const bool boundary_was_splitted(const unsigned &b)
Helper function to verify if a given boundary was splitted in the distribution process.
const unsigned shared_boundary_overlapping_internal_boundary(const unsigned &shd_bnd_id)
Gets the boundary id of the internal boundary that the shared boundary lies on.
RefineableSolidTriangleMesh(const Vector< double > &target_area, TriangulateIO &triangulate_io, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &use_attributes=false, const bool &allow_automatic_creation_of_vertices_on_boundaries=true, OomphCommunicator *comm_pt=0)
Build mesh from specified triangulation and associated target areas for elements in it...
void enable_print_timings_load_balance(const unsigned &print_level=1)
Enables printing of timings for load balance.
void enable_internal_boundary_refinement()
Helper function for enabling the use of boundary refinement.
void set_print_level_timings_load_balance(const unsigned &print_level)
Sets the printing level of timings for load balance.
Vector< Vector< double > > Original_extra_holes_coordinates
Backup the original extra holes coordinates.
const bool boundary_marked_as_shared_boundary(const unsigned &b, const unsigned &isub)
Returns the value that indicates if a subpolyline of a given boundary continues been used as internal...
void enable_iterative_solver_for_projection()
Node * sorted_shared_boundary_node_pt(unsigned &b, unsigned &i)
bool is_automatic_creation_of_vertices_on_boundaries_allowed()
Vector< Vector< Vector< unsigned > > > Shared_boundaries_ids
Stores the boundaries ids created by the interaction of two processors Shared_boundaries_ids[iproc][j...
unsigned Counter_for_flat_packed_unsigneds
Counter used when processing vector of flat-packed unsigneds.
Vector< Node * > sorted_shared_boundary_node_pt(unsigned &b)
Vector< Vector< Vector< unsigned > > > & shared_boundaries_ids()
unsigned Print_timings_level_load_balance
The printing level for load balance.
Vector< TriangleMeshPolyLine * > & shared_boundary_polyline_pt(const unsigned &p, const unsigned &c)
TriangleMesh(const TriangleMesh &dummy)
Broken copy constructor.
Vector< Vector< unsigned > > & shared_boundaries_ids(const unsigned &p)
const unsigned final_shared_boundary_id()
The final boundary id for shared boundaries.
void flush_shared_boundary_element()
const bool boundary_connections(const unsigned &b, const unsigned &c, std::set< Vector< double > > &vertices)
Verifies if the given boundary receives a connection, and if that is the case then returns the list o...
int face_index_at_shared_boundary(const unsigned &b, const unsigned &e)
TriangleMesh(const std::string &poly_file_name, const double &element_area, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper, const bool &allow_automatic_creation_of_vertices_on_boundaries=true)
Build mesh from poly file, with specified target area for all elements.
bool Do_shared_boundary_unrefinement_constrained_by_target_areas
Flag that enables or disables boundary unrefinement (true by default)
unsigned Nbin_x_for_area_transfer
Number of bins in the x-direction when transferring target areas by bin method. Only used if we don't...
void set_mesh_level_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Overload set_mesh_level_time_stepper so that the stored time stepper now corresponds to the new times...
TriangleMeshClosedCurve * outer_boundary_pt(const unsigned &i) const
Helper function for getting the i-th outer boundary.
void flush_shared_boundary_node()
Flush ALL the shared boundary nodes.
bool is_use_attributes() const
Helper function for getting the status of use_attributes variable.
double & min_permitted_angle()
Min angle before remesh gets triggered.
void enable_boundary_refinement_constrained_by_target_areas()
Unstructured refineable Triangle Mesh.
OomphCommunicator * communicator_pt() const
Read-only access fct to communicator (Null if mesh is not distributed)
void generic_constructor(Vector< TriangleMeshPolygon *> &outer_boundary_pt, Vector< TriangleMeshPolygon *> &internal_polygon_pt, Vector< TriangleMeshOpenCurve *> &open_polylines_pt, const double &element_area, Vector< Vector< double > > &extra_holes_coordinates, std::map< unsigned, Vector< double > > ®ions_coordinates, std::map< unsigned, double > ®ions_areas, TimeStepper *time_stepper_pt, const bool &use_attributes, const bool &refine_boundary, const bool &refine_internal_boundary)
A general-purpose construction function that builds the mesh once the different specific constructors...
std::map< unsigned, Vector< FiniteElement * > > Shared_boundary_element_pt
Stores the boundary elements adjacent to the shared boundaries, these elements are a subset of the ha...
bool triangulateio_exists()
Boolean defining if Triangulateio object has been built or not.
Vector< unsigned > oomph_vertex_nodes_id()
Return the vector that contains the oomph-lib node number for all vertex nodes in the TriangulateIO r...
TriangleMeshClosedCurve *& outer_boundary_pt(const unsigned &i)
Helper function for getting access to the i-th outer boundary.
unsigned & nbin_x_for_area_transfer()
Read/write access to number of bins in the x-direction when transferring target areas by bin method...
Vector< TriangleMeshPolyLine * > & boundary_subpolylines(const unsigned &b)
Gets the vector of auxiliar polylines that will represent the given boundary (useful only when the bo...
unsigned try_to_add_haloed_node_pt(const unsigned &p, Node *&nod_pt)
Check if necessary to add the node as haloed or if it has been previously added to the haloed scheme...
void shared_boundaries_in_this_processor(Vector< unsigned > &shared_boundaries_in_this_processor)
Get the shared boundaries ids living in the current processor.
Vector< Vector< Vector< TriangleMeshPolyLine * > > > Shared_boundary_polyline_pt
Stores the polyline representation of the shared boundaries Shared_boundary_polyline_pt[iproc][ncurve...
Vector< Vector< Vector< unsigned > > > shared_boundaries_ids() const
unsigned & nbin_y_for_area_transfer()
Read/write access to number of bins in the y-direction when transferring target areas by bin method...