39 #ifndef OOMPH_UNSTRUCTURED_TWO_D_MESH_GEOMETRY_BASE_HEADER 40 #define OOMPH_UNSTRUCTURED_TWO_D_MESH_GEOMETRY_BASE_HEADER 45 using namespace oomph;
57 #ifdef OOMPH_HAS_TRIANGLE_LIB 112 namespace TriangleHelper
116 const bool& clear_hole_data=
true);
131 std::ostream &poly_file);
142 bool &use_attributes);
147 std::ostream &dump_file);
179 Initial_vertex_connected(false),
180 Final_vertex_connected(false),
181 Initial_vertex_connected_suspended(false),
182 Final_vertex_connected_suspended(false),
183 Initial_vertex_connected_to_curviline(false),
184 Final_vertex_connected_to_curviline(false),
185 Refinement_tolerance(0.08),
186 Unrefinement_tolerance(0.04),
197 virtual unsigned nsegment()
const = 0;
200 virtual unsigned boundary_id()
const = 0;
204 virtual unsigned boundary_chunk()
const = 0;
207 virtual unsigned nvertex()
const = 0;
210 virtual void output(std::ostream &outfile,
const unsigned& n_sample=50) = 0;
220 Refinement_tolerance=tolerance;
232 Refinement_tolerance=tolerance;
241 return Refinement_tolerance;
247 Refinement_tolerance=-1.0;
259 Unrefinement_tolerance=tolerance;
274 Unrefinement_tolerance=tolerance;
283 return Unrefinement_tolerance;
289 Unrefinement_tolerance=-1.0;
296 {Maximum_length = maximum_length;}
301 {Maximum_length=-1.0;}
305 {
return Maximum_length;}
308 virtual void initial_vertex_coordinate(
Vector<double> &vertex) = 0;
318 void connect_initial_vertex_to_polyline(
320 const unsigned &vertex_number,
321 const double &tolerance_for_connection = 1.0
e-14);
328 void connect_final_vertex_to_polyline(
330 const unsigned &vertex_number,
331 const double &tolerance_for_connection = 1.0
e-14);
339 void connect_initial_vertex_to_curviline(
341 const double &s_value,
342 const double &tolerance_for_connection = 1.0
e-14);
350 void connect_final_vertex_to_curviline(
352 const double &s_value,
353 const double &tolerance_for_connection = 1.0
e-14);
357 {
return Initial_vertex_connected;}
361 {Initial_vertex_connected =
true;}
365 {Initial_vertex_connected =
false;}
374 if (Initial_vertex_connected)
376 Initial_vertex_connected =
false;
377 Initial_vertex_connected_suspended =
true;
386 if (Initial_vertex_connected_suspended)
388 Initial_vertex_connected =
true;
389 Initial_vertex_connected_suspended =
false;
395 {
return Final_vertex_connected;}
399 {Final_vertex_connected =
true;}
403 {Final_vertex_connected =
false;}
412 if (Final_vertex_connected)
414 Final_vertex_connected =
false;
415 Final_vertex_connected_suspended =
true;
424 if (Final_vertex_connected_suspended)
426 Final_vertex_connected =
true;
427 Final_vertex_connected_suspended =
false;
433 {
return Initial_vertex_connected_bnd_id;}
437 {
return Initial_vertex_connected_bnd_id;}
441 {
return Initial_vertex_connected_n_vertex;}
445 {
return Initial_vertex_connected_n_vertex;}
449 {
return Initial_vertex_connected_n_chunk;}
453 {
return Initial_vertex_connected_n_chunk;}
457 {
return Final_vertex_connected_bnd_id;}
461 {
return Final_vertex_connected_bnd_id;}
465 {
return Final_vertex_connected_n_vertex;}
469 {
return Final_vertex_connected_n_vertex;}
473 {
return Final_vertex_connected_n_chunk;}
477 {
return Final_vertex_connected_n_chunk;}
481 {
return Initial_vertex_connected_to_curviline;}
485 {Initial_vertex_connected_to_curviline =
true;}
489 {Initial_vertex_connected_to_curviline =
false;}
493 {
return Final_vertex_connected_to_curviline;}
497 {Final_vertex_connected_to_curviline =
true;}
501 {Final_vertex_connected_to_curviline =
false;}
505 {
return Initial_s_connection_value;}
509 {
return Initial_s_connection_value;}
513 {
return Final_s_connection_value;}
517 {
return Final_s_connection_value;}
522 {
return Tolerance_for_s_connection;}
527 {
return Tolerance_for_s_connection;}
624 const double& zeta_start,
625 const double& zeta_end,
626 const unsigned& nsegment,
627 const unsigned& boundary_id,
629 space_vertices_evenly_in_arclength=
true,
630 const unsigned &boundary_chunk = 0)
632 Geom_object_pt(geom_object_pt),
633 Zeta_start(zeta_start),
636 Boundary_id(boundary_id),
637 Space_vertices_evenly_in_arclength(
638 space_vertices_evenly_in_arclength),
639 Boundary_chunk(boundary_chunk)
672 void output(std::ostream &outfile,
const unsigned& n_sample=50)
674 outfile <<
"ZONE T=\"Boundary " << Boundary_id <<
"\"\n";
677 for (
unsigned i=0;
i<n_sample;
i++)
679 zeta[0]=Zeta_start+(Zeta_end-Zeta_start)*
double(
i)/double(n_sample-1);
680 Geom_object_pt->position(zeta,r);
681 outfile << r[0] <<
" " << r[1] << std::endl;
690 return Space_vertices_evenly_in_arclength;
701 Geom_object_pt->position(z, vertex);
709 Geom_object_pt->position(z, vertex);
714 {
return !Connection_points_pt.empty();}
718 {
return &Connection_points_pt;}
723 const double &z_value,
724 const double &tol = 1.0
e-12)
731 if (std::fabs(z_value - Zeta_start) < tol ||
732 std::fabs(z_value - Zeta_end) < tol)
739 unsigned n_size = Connection_points_pt.size();
740 for (
unsigned i = 0;
i < n_size;
i++)
742 if (fabs(z_value - Connection_points_pt[
i]) < tol)
749 Connection_points_pt.push_back(z_value);
800 const unsigned &boundary_id,
801 const unsigned &boundary_chunk = 0) :
803 Vertex_coordinate(vertex_coordinate),
804 Boundary_id(boundary_id),
805 Boundary_chunk(boundary_chunk)
808 unsigned nvert=Vertex_coordinate.size();
809 for (
unsigned i=0;
i<nvert;
i++)
811 if (Vertex_coordinate[
i].size()!=2)
813 std::ostringstream error_stream;
815 <<
"TriangleMeshPolyLine should only be used in 2D!\n" 816 <<
"Your Vector of coordinates, contains data for " 817 << Vertex_coordinate[
i].size()
818 <<
"-dimensional coordinates." << std::endl;
820 OOMPH_CURRENT_FUNCTION,
821 OOMPH_EXCEPTION_LOCATION);
831 unsigned nvertex()
const {
return Vertex_coordinate.size();}
834 unsigned nsegment()
const {
return Vertex_coordinate.size()-1;}
845 {
return Vertex_coordinate[
i];}
849 {
return Vertex_coordinate[
i];}
853 {vertex = Vertex_coordinate[0];}
857 {vertex = Vertex_coordinate[nvertex()-1];}
860 void output(std::ostream &outfile,
const unsigned& n_sample=50)
862 outfile <<
"ZONE T=\"TriangleMeshPolyLine with boundary ID" 863 << Boundary_id<<
"\""<<std::endl;
864 unsigned nvert=Vertex_coordinate.size();
865 for(
unsigned i=0;
i<nvert;
i++)
867 outfile << Vertex_coordinate[
i][0] <<
" " 868 << Vertex_coordinate[
i][1] << std::endl;
879 const bool initial_connection = is_initial_vertex_connected();
882 const bool final_connection = is_final_vertex_connected();
886 if (initial_connection || final_connection)
893 const unsigned backup_initial_vertex_connected_bnd_id =
894 initial_vertex_connected_bnd_id();
896 const unsigned backup_initial_vertex_connected_chunk =
897 initial_vertex_connected_n_chunk();
899 const unsigned backup_initial_vertex_connected_n_vertex =
900 initial_vertex_connected_n_vertex();
902 const bool backup_initial_vertex_connected_to_curviline =
903 is_initial_vertex_connected_to_curviline();
905 const double backup_initial_s_connection = initial_s_connection_value();
907 const double backup_initial_s_tolerance = tolerance_for_s_connection();
912 const unsigned backup_final_vertex_connected_bnd_id =
913 final_vertex_connected_bnd_id();
915 const unsigned backup_final_vertex_connected_chunk =
916 final_vertex_connected_n_chunk();
918 const unsigned backup_final_vertex_connected_n_vertex =
919 final_vertex_connected_n_vertex();
921 const bool backup_final_vertex_connected_to_curviline =
922 is_final_vertex_connected_to_curviline();
924 const double backup_final_s_connection = final_s_connection_value();
926 const double backup_final_s_tolerance = tolerance_for_s_connection();
932 unset_initial_vertex_connected();
933 unset_initial_vertex_connected_to_curviline();
936 unset_final_vertex_connected();
937 unset_final_vertex_connected_to_curviline();
940 if (initial_connection)
943 set_final_vertex_connected();
945 final_vertex_connected_bnd_id() =
946 backup_initial_vertex_connected_bnd_id;
948 final_vertex_connected_n_chunk() =
949 backup_initial_vertex_connected_chunk;
951 final_vertex_connected_n_vertex() =
952 backup_initial_vertex_connected_n_vertex;
954 if (backup_initial_vertex_connected_to_curviline)
957 set_final_vertex_connected_to_curviline();
959 final_s_connection_value() = backup_initial_s_connection;
961 tolerance_for_s_connection() = backup_initial_s_tolerance;
966 if (final_connection)
969 set_initial_vertex_connected();
971 initial_vertex_connected_bnd_id() =
972 backup_final_vertex_connected_bnd_id;
974 initial_vertex_connected_n_chunk() =
975 backup_final_vertex_connected_chunk;
977 initial_vertex_connected_n_vertex() =
978 backup_final_vertex_connected_n_vertex;
980 if (backup_final_vertex_connected_to_curviline)
983 set_initial_vertex_connected_to_curviline();
985 initial_s_connection_value() = backup_final_s_connection;
987 tolerance_for_s_connection() = backup_final_s_tolerance;
995 std::reverse(Vertex_coordinate.begin(), Vertex_coordinate.end());
1025 namespace ToleranceForVertexMismatchInPolygons
1054 : Curve_section_pt(curve_section_pt),
1055 Polyline_refinement_tolerance(0.08),
1056 Polyline_unrefinement_tolerance(0.04)
1065 virtual unsigned nvertices()
const = 0;
1068 virtual unsigned nsegments()
const = 0;
1074 unsigned n_curve_section = ncurve_section();
1075 for(
unsigned i=0;
i<n_curve_section;
i++)
1077 unsigned boundary_id=Curve_section_pt[
i]->boundary_id();
1078 if (boundary_id>max) {max=boundary_id;}
1085 {
return Curve_section_pt.size();}
1095 Polyline_refinement_tolerance=tolerance;
1098 unsigned n_curve_sections = Curve_section_pt.size();
1099 for (
unsigned i = 0;
i < n_curve_sections;
i++)
1101 Curve_section_pt[
i]->set_refinement_tolerance(
1102 Polyline_refinement_tolerance);
1115 Polyline_refinement_tolerance=tolerance;
1118 unsigned n_curve_sections = Curve_section_pt.size();
1119 for (
unsigned i = 0;
i < n_curve_sections;
i++)
1121 Curve_section_pt[
i]->set_refinement_tolerance(
1122 Polyline_refinement_tolerance);
1132 return Polyline_refinement_tolerance;
1138 Polyline_refinement_tolerance=-1.0;
1141 unsigned n_curve_sections = Curve_section_pt.size();
1142 for (
unsigned i = 0;
i < n_curve_sections;
i++)
1143 {Curve_section_pt[
i]->disable_refinement_tolerance();}
1155 Polyline_unrefinement_tolerance=tolerance;
1158 unsigned n_curve_sections = Curve_section_pt.size();
1159 for (
unsigned i = 0;
i < n_curve_sections;
i++)
1161 Curve_section_pt[
i]->set_unrefinement_tolerance(
1162 Polyline_unrefinement_tolerance);
1178 Polyline_unrefinement_tolerance=tolerance;
1181 unsigned n_curve_sections = Curve_section_pt.size();
1182 for (
unsigned i = 0;
i < n_curve_sections;
i++)
1184 Curve_section_pt[
i]->set_unrefinement_tolerance(
1185 Polyline_unrefinement_tolerance);
1195 return Polyline_unrefinement_tolerance;
1201 Polyline_unrefinement_tolerance=-1.0;
1204 unsigned n_curve_sections = Curve_section_pt.size();
1205 for (
unsigned i = 0;
i < n_curve_sections;
i++)
1206 {Curve_section_pt[
i]->disable_unrefinement_tolerance();}
1210 virtual void output(std::ostream &outfile,
const unsigned& n_sample=50) = 0;
1214 {
return Curve_section_pt[
i];}
1218 {
return Curve_section_pt[
i];}
1251 const bool &is_internal_point_fixed=
false);
1259 unsigned n_curve_section=ncurve_section();
1260 unsigned n_vertices=0;
1261 for(
unsigned j=0;j<n_curve_section;j++)
1264 n_vertices+=Curve_section_pt[j]->nvertex()-1;
1267 if(n_curve_section==1) {n_vertices+=1;}
1274 unsigned n_curve_section=ncurve_section();
1276 for(
unsigned j=0;j<n_curve_section;j++)
1277 {nseg+=Curve_section_pt[j]->nsegment();}
1280 if(n_curve_section==1) {nseg+=1;}
1285 void output(std::ostream &outfile,
const unsigned& n_sample=50)
1287 unsigned nb=Curve_section_pt.size();
1288 for (
unsigned i=0;
i<nb;
i++)
1290 Curve_section_pt[
i]->output(outfile,n_sample);
1293 if (!Internal_point_pt.empty())
1295 outfile <<
"ZONE T=\"Internal point\"\n";
1296 outfile << Internal_point_pt[0] <<
" " 1297 << Internal_point_pt[1] <<
"\n";
1357 boundary_polyline_pt,
1359 const bool &is_internal_point_fixed=
false);
1366 {
return npolyline();}
1369 unsigned npolyline()
const {
return Curve_section_pt.size();}
1377 if (tmp_polyline == NULL)
1379 std::ostringstream error_stream;
1381 <<
"The (" << i <<
") TriangleMeshCurveSection is not a " 1382 <<
"TriangleMeshPolyLine\nThe TriangleMeshPolygon object" 1383 <<
"is constituent of only TriangleMeshPolyLine objects.\n" 1384 <<
"The problem could be generated when changing the constituent " 1385 <<
"objects of the TriangleMeshPolygon.\nCheck where you got " 1386 <<
"access to this objects and review that you are not introducing " 1387 <<
"any other objects than TriangleMeshPolyLines" << std::endl;
1389 OOMPH_CURRENT_FUNCTION,
1390 OOMPH_EXCEPTION_LOCATION);
1393 return tmp_polyline;
1402 if (tmp_polyline == NULL)
1404 std::ostringstream error_stream;
1406 <<
"The (" << i <<
") TriangleMeshCurveSection is not a " 1407 <<
"TriangleMeshPolyLine\nThe TriangleMeshPolygon object" 1408 <<
"is constituent of only TriangleMeshPolyLine objects.\n" 1409 <<
"The problem could be generated when changing the constituent " 1410 <<
"objects of the TriangleMeshPolygon.\nCheck where you got " 1411 <<
"access to this objects and review that you are not introducing " 1412 <<
"any other objects than TriangleMeshPolyLines" << std::endl;
1414 OOMPH_CURRENT_FUNCTION,
1415 OOMPH_EXCEPTION_LOCATION);
1418 return tmp_polyline;
1425 unsigned nline=npolyline();
1429 for(
unsigned iline=0;iline<nline;iline++)
1431 boundary_id[iline]=Curve_section_pt[iline]->boundary_id();
1439 {
return Enable_redistribution_of_segments_between_polylines;}
1444 {Enable_redistribution_of_segments_between_polylines=
true;}
1449 {Enable_redistribution_of_segments_between_polylines=
false;}
1453 {
return Can_update_configuration;}
1459 std::ostringstream error_stream;
1461 <<
"Broken Default Called\n" 1462 <<
"This function should be overloaded if Can_update_configuration = true," 1463 <<
"\nwhich indicates that the curve in it polylines parts can update its " 1464 <<
"own position (i.e. it\n" 1465 <<
"may be a rigid body. Otherwise the update will be via a FaceMesh \n" 1466 <<
"representation of the boundary which is appropriate for \n" 1467 <<
"general deforming surfaces\n";
1471 OOMPH_CURRENT_FUNCTION,
1472 OOMPH_EXCEPTION_LOCATION);
1527 unsigned n_vertices = 0;
1528 unsigned n_curve_section=ncurve_section();
1529 for (
unsigned i = 0;
i < n_curve_section;
i++)
1530 n_vertices+=Curve_section_pt[
i]->nvertex();
1532 if (n_curve_section==1) {n_vertices+=1;}
1539 unsigned n_curve_section=ncurve_section();
1541 for(
unsigned j=0;j<n_curve_section;j++)
1542 {nseg+=Curve_section_pt[j]->nsegment();}
1547 void output(std::ostream &outfile,
const unsigned& n_sample=50)
1549 unsigned nb=Curve_section_pt.size();
1550 for (
unsigned i=0;
i<nb;
i++)
1552 Curve_section_pt[
i]->output(outfile,n_sample);
1563 if (tmp_polyline == NULL)
1565 std::ostringstream error_stream;
1567 <<
"The (" << i <<
")-th TriangleMeshCurveSection is not a " 1568 <<
"TriangleMeshPolyLine.\nPlease make sure that when you" 1569 <<
"first created this object the (" << i <<
")-th\n" 1570 <<
"TriangleCurveSection is a TriangleMeshPolyLine." 1573 OOMPH_CURRENT_FUNCTION,
1574 OOMPH_EXCEPTION_LOCATION);
1577 return tmp_polyline;
1586 if (tmp_polyline == NULL)
1588 std::ostringstream error_stream;
1590 <<
"The (" << i <<
")-th TriangleMeshCurveSection is not a " 1591 <<
"TriangleMeshPolyLine.\nPlease make sure that when you" 1592 <<
"first created this object the (" << i <<
")-th\n" 1593 <<
"TriangleCurveSection is a TriangleMeshPolyLine." 1596 OOMPH_CURRENT_FUNCTION,
1597 OOMPH_EXCEPTION_LOCATION);
1600 return tmp_polyline;
1638 return Region_element_pt.size();
1645 std::map<unsigned,Vector<FiniteElement* > >::iterator it;
1648 it=Region_element_pt.find(i);
1651 if (it!=Region_element_pt.end())
1653 return (it->second).size();
1666 std::map<unsigned,Vector<FiniteElement* > >::iterator it;
1669 it=Region_element_pt.find(i);
1672 if (it!=Region_element_pt.end())
1675 return (it->second)[
e];
1680 std::stringstream error_message;
1683 error_message <<
"There are no regions associated with " 1684 <<
"region ID " << i <<
".";
1688 OOMPH_CURRENT_FUNCTION,
1689 OOMPH_EXCEPTION_LOCATION);
1696 return Region_attribute.size();
1702 return Region_attribute[
i];
1709 std::map<unsigned,GeomObject*>::iterator it;
1710 it=Boundary_geom_object_pt.find(b);
1711 if (it==Boundary_geom_object_pt.end())
1717 return (*it).second;
1724 return Boundary_geom_object_pt;
1731 return Boundary_coordinate_limits;
1738 std::map<unsigned,Vector<double> >::iterator it;
1739 it=Boundary_coordinate_limits.find(b);
1740 if (it==Boundary_coordinate_limits.end())
1742 throw OomphLibError(
"No coordinate limits associated with this boundary\n",
1743 OOMPH_CURRENT_FUNCTION,
1744 OOMPH_EXCEPTION_LOCATION);
1748 return (*it).second;
1754 const unsigned &r)
const 1758 std::map<unsigned,Vector<FiniteElement*> >::const_iterator it=
1759 Boundary_region_element_pt[b].find(r);
1760 if (it!=Boundary_region_element_pt[b].end())
1762 return (it->second).size();
1774 const unsigned &
e)
const 1777 std::map<unsigned,Vector<FiniteElement*> >::const_iterator it=
1778 Boundary_region_element_pt[b].find(r);
1779 if (it!=Boundary_region_element_pt[b].end())
1781 return (it->second)[
e];
1792 const unsigned &
e)
const 1795 std::map<unsigned,Vector<int> >::const_iterator it=
1796 Face_index_region_at_boundary[b].find(r);
1797 if (it!=Face_index_region_at_boundary[b].end())
1799 return (it->second)[
e];
1803 std::ostringstream error_message;
1804 error_message <<
"Face indices not set up for boundary " 1805 << b <<
" in region " << r <<
"\n";
1807 <<
"This probably means that the boundary is not adjacent to region\n";
1809 OOMPH_CURRENT_FUNCTION,
1810 OOMPH_EXCEPTION_LOCATION);
1818 std::map<unsigned,TriangleMeshCurveSection*>::iterator it=
1819 Boundary_curve_section_pt.find(b);
1821 if (it!=Boundary_curve_section_pt.end())
1832 return Nodes_on_boundary_pt;
1837 const bool get_connected_vertex_number_on_destination_polyline(
1840 unsigned& vertex_number);
1845 void check_contiguousness_on_polylines_helper(
1851 void check_contiguousness_on_polylines_helper(
1853 unsigned &index_halo_start,
unsigned &index_halo_end);
1857 bool is_point_inside_polygon_helper(
1864 Allow_automatic_creation_of_vertices_on_boundaries =
true;
1871 Allow_automatic_creation_of_vertices_on_boundaries=
false;
1878 return Allow_automatic_creation_of_vertices_on_boundaries;
1881 #ifdef OOMPH_HAS_MPI 1886 Boundary_segment_node_pt[b].clear();
1892 Boundary_segment_node_pt[b].resize(s);
1898 return Boundary_segment_node_pt[b].size();
1904 unsigned ntotal_nodes = 0;
1905 unsigned nsegments = Boundary_segment_node_pt[b].size();
1906 for (
unsigned is = 0; is < nsegments; is++)
1908 ntotal_nodes+=nboundary_segment_node(b,is);
1910 return ntotal_nodes;
1917 return Boundary_segment_node_pt[b][
s].size();
1924 Node*
const &node_pt)
1927 unsigned nbound_seg_node=nboundary_segment_node(b,s);
1928 bool node_already_on_this_boundary_segment=
false;
1931 for (
unsigned n=0; n<nbound_seg_node; n++)
1934 if (node_pt==Boundary_segment_node_pt[b][s][n])
1936 node_already_on_this_boundary_segment=
true;
1941 if (!node_already_on_this_boundary_segment)
1943 Boundary_segment_node_pt[b][
s].push_back(node_pt);
1954 return Boundary_initial_coordinate;
1960 return Boundary_final_coordinate;
1967 return Boundary_initial_zeta_coordinate;
1974 return Boundary_final_zeta_coordinate;
1981 return Boundary_segment_inverted;
1986 std::map<unsigned, Vector<Vector<double> > >&
1989 return Boundary_segment_initial_coordinate;
1994 std::map<unsigned, Vector<Vector<double> > >&
1997 return Boundary_segment_final_coordinate;
2004 return Boundary_segment_initial_arclength;
2011 return Boundary_segment_final_arclength;
2018 return Boundary_segment_initial_zeta;
2025 return Boundary_segment_final_zeta;
2032 std::map<unsigned, Vector<double> >::iterator it =
2033 Boundary_segment_initial_zeta.find(b);
2037 if(it==Boundary_segment_initial_zeta.end())
2039 std::stringstream error_message;
2041 <<
"The boundary ("<<b<<
") has no segments associated with it!!\n\n";
2043 OOMPH_CURRENT_FUNCTION,
2044 OOMPH_EXCEPTION_LOCATION);
2049 return (*it).second;
2056 std::map<unsigned, Vector<double> >::iterator it =
2057 Boundary_segment_final_zeta.find(b);
2061 if(it==Boundary_segment_final_zeta.end())
2063 std::stringstream error_message;
2065 <<
"The boundary ("<<b<<
") has no segments associated with it!!\n\n";
2067 OOMPH_CURRENT_FUNCTION,
2068 OOMPH_EXCEPTION_LOCATION);
2073 return (*it).second;
2079 std::map<unsigned, Vector<double> >::iterator it =
2080 Boundary_initial_coordinate.find(b);
2084 if(it==Boundary_initial_coordinate.end())
2086 std::stringstream error_message;
2088 <<
"The boundary (" << b <<
") has not established initial coordinates\n";
2090 OOMPH_CURRENT_FUNCTION,
2091 OOMPH_EXCEPTION_LOCATION);
2095 return (*it).second;
2101 std::map<unsigned, Vector<double> >::iterator it =
2102 Boundary_final_coordinate.find(b);
2106 if(it==Boundary_final_coordinate.end())
2108 std::stringstream error_message;
2110 <<
"The boundary (" << b <<
") has not established final coordinates\n";
2112 OOMPH_CURRENT_FUNCTION,
2113 OOMPH_EXCEPTION_LOCATION);
2118 return (*it).second;
2125 std::map<unsigned, Vector<unsigned> >::const_iterator it =
2126 Boundary_segment_inverted.find(b);
2130 if(it==Boundary_segment_inverted.end())
2132 std::stringstream error_message;
2134 <<
"The boundary (" << b <<
") has not established inv. segments info\n";
2136 OOMPH_CURRENT_FUNCTION,
2137 OOMPH_EXCEPTION_LOCATION);
2142 return (*it).second;
2149 std::map<unsigned, Vector<unsigned> >::iterator it =
2150 Boundary_segment_inverted.find(b);
2154 if(it==Boundary_segment_inverted.end())
2156 std::stringstream error_message;
2158 <<
"The boundary (" << b <<
") has not established inv. segments info\n";
2160 OOMPH_CURRENT_FUNCTION,
2161 OOMPH_EXCEPTION_LOCATION);
2166 return (*it).second;
2172 std::map<unsigned, Vector<double> >::iterator it =
2173 Boundary_initial_zeta_coordinate.find(b);
2177 if(it==Boundary_initial_zeta_coordinate.end())
2179 std::stringstream error_message;
2181 <<
"The boundary ("<<b<<
") has not established initial zeta " 2184 OOMPH_CURRENT_FUNCTION,
2185 OOMPH_EXCEPTION_LOCATION);
2190 return (*it).second;
2196 std::map<unsigned, Vector<double> >::iterator it =
2197 Boundary_final_zeta_coordinate.find(b);
2201 if(it==Boundary_final_zeta_coordinate.end())
2203 std::stringstream error_message;
2205 <<
"The boundary ("<<b<<
") has not established final zeta coordinate\n";
2207 OOMPH_CURRENT_FUNCTION,
2208 OOMPH_EXCEPTION_LOCATION);
2213 return (*it).second;
2220 std::map<unsigned, Vector<double> >::iterator it =
2221 Boundary_segment_initial_arclength.find(b);
2225 if(it==Boundary_segment_initial_arclength.end())
2227 std::stringstream error_message;
2229 <<
"The boundary ("<<b<<
") has no segments associated with it!!\n\n";
2231 OOMPH_CURRENT_FUNCTION,
2232 OOMPH_EXCEPTION_LOCATION);
2237 return (*it).second;
2244 std::map<unsigned, Vector<double> >::iterator it =
2245 Boundary_segment_final_arclength.find(b);
2249 if(it==Boundary_segment_final_arclength.end())
2251 std::stringstream error_message;
2253 <<
"The boundary ("<<b<<
") has no segments associated with it!!\n\n";
2255 OOMPH_CURRENT_FUNCTION,
2256 OOMPH_EXCEPTION_LOCATION);
2261 return (*it).second;
2268 std::map<unsigned, Vector<Vector<double> > >::iterator it =
2269 Boundary_segment_initial_coordinate.find(b);
2273 if(it==Boundary_segment_initial_coordinate.end())
2275 std::stringstream error_message;
2277 <<
"The boundary ("<<b<<
") has no segments associated with it!!\n\n";
2279 OOMPH_CURRENT_FUNCTION,
2280 OOMPH_EXCEPTION_LOCATION);
2285 return (*it).second;
2292 std::map<unsigned, Vector<Vector<double> > >::iterator it =
2293 Boundary_segment_final_coordinate.find(b);
2297 if(it==Boundary_segment_final_coordinate.end())
2299 std::stringstream error_message;
2301 <<
"The boundary ("<<b<<
") has no segments associated with it!!\n\n";
2303 OOMPH_CURRENT_FUNCTION,
2304 OOMPH_EXCEPTION_LOCATION);
2309 return (*it).second;
2312 #endif // OOMPH_HAS_MPI 2318 template<
class ELEMENT>
2322 std::ofstream some_file;
2323 setup_boundary_coordinates<ELEMENT>(b,some_file);
2331 template<
class ELEMENT>
2332 void setup_boundary_coordinates(
const unsigned& b,std::ofstream& outfile);
2338 #ifdef OOMPH_HAS_TRIANGLE_LIB 2348 ®ions_coordinates,
2349 std::map<unsigned, double>
2376 void add_connection_matrix_info_helper(
2384 void initialise_base_vertex(
2390 void add_base_vertex_info_helper(
2396 std::map<
unsigned, std::map<unsigned, unsigned> >
2397 &boundary_chunk_nvertices);
2401 #ifdef OOMPH_HAS_MPI 2456 void snap_nodes_onto_geometric_objects();
2504 std::map<unsigned,Vector<std::pair<double,double> > >
2530 void copy_connection_information_to_sub_polylines(
2545 #ifdef OOMPH_HAS_TRIANGLE_LIB 2559 Vector<std::pair<double,double> >& polygonal_vertex_arclength_info)
2568 double zeta_initial = boundary_pt->
zeta_start();
2571 unsigned n_seg = boundary_pt->
nsegment();
2572 vertex_coord.resize(n_seg+1);
2573 polygonal_vertex_arclength_info.resize(n_seg+1);
2574 polygonal_vertex_arclength_info[0].first=0.0;
2575 polygonal_vertex_arclength_info[0].second=zeta_initial;
2582 double zeta_increment =
2586 for(
unsigned s=0;
s<n_seg+1;
s++)
2589 zeta[0]= zeta_initial + zeta_increment*double(
s);
2591 vertex_coord[
s]=posn;
2596 polygonal_vertex_arclength_info[
s].first=
2597 polygonal_vertex_arclength_info[
s-1].first+
2598 sqrt(pow(vertex_coord[
s][0]-vertex_coord[
s-1][0],2)+
2599 pow(vertex_coord[
s][1]-vertex_coord[
s-1][1],2));
2600 polygonal_vertex_arclength_info[
s].second=zeta[0];
2610 unsigned nsample_per_segment=100;
2611 unsigned nsample=nsample_per_segment*n_seg;
2614 double zeta_increment=(boundary_pt->
zeta_end()-
2615 boundary_pt->
zeta_start())/(
double(nsample));
2619 zeta[0]=zeta_initial;
2627 double total_arclength=0.0;
2628 for (
unsigned i=1;
i<nsample;
i++)
2631 zeta[0]+=zeta_increment;
2637 total_arclength+=sqrt(pow(end_point[0]-start_point[0],2)+
2638 pow(end_point[1]-start_point[1],2));
2641 start_point=end_point;
2645 double target_s_increment=total_arclength/(double(n_seg));
2648 zeta[0]=zeta_initial;
2652 vertex_coord[0]=start_point;
2658 for(
unsigned s=1;
s<n_seg;
s++)
2662 double arclength_increment=0.0;
2663 for (
unsigned i=i_lo;
i<nsample;
i++)
2666 zeta[0]+=zeta_increment;
2672 arclength_increment+=sqrt(pow(end_point[0]-start_point[0],2)+
2673 pow(end_point[1]-start_point[1],2));
2676 start_point=end_point;
2679 if (arclength_increment>target_s_increment)
2690 vertex_coord[
s]=end_point;
2695 polygonal_vertex_arclength_info[
s].first=
2696 polygonal_vertex_arclength_info[
s-1].first+
2697 sqrt(pow(vertex_coord[
s][0]-vertex_coord[
s-1][0],2)+
2698 pow(vertex_coord[
s][1]-vertex_coord[
s-1][1],2));
2699 polygonal_vertex_arclength_info[
s].second=zeta[0];
2707 vertex_coord[
s]=end_point;
2708 polygonal_vertex_arclength_info[
s].first=
2709 polygonal_vertex_arclength_info[s-1].first+
2710 sqrt(pow(vertex_coord[s][0]-vertex_coord[s-1][0],2)+
2711 pow(vertex_coord[s][1]-vertex_coord[s-1][1],2));
2712 polygonal_vertex_arclength_info[
s].second=zeta[0];
2728 Vector<std::pair<double,double> >& polygonal_vertex_arclength_info)
2731 double zeta_initial = boundary_pt->
zeta_start();
2733 double zeta_final = boundary_pt->
zeta_end();
2738 unsigned n_connections = connection_points_pt->size();
2741 if (n_connections > 1)
2743 std::sort(connection_points_pt->begin(), connection_points_pt->end());
2748 bool out_of_range_connection_points =
false;
2749 std::ostringstream error_message;
2751 bool reversed =
false;
2752 if (zeta_final < zeta_initial)
2756 if (zeta_initial > (*connection_points_pt)[0])
2759 <<
"One of the specified connection points is out of the\n" 2760 <<
"curviline limits. We found that the point (" 2761 << (*connection_points_pt)[0] <<
") is\n" <<
"less than the" 2762 <<
"initial s value which is (" << zeta_initial <<
").\n" 2763 <<
"Initial value: ("<<zeta_initial<<
")\n" 2764 <<
"Final value: ("<<zeta_final<<
")\n" 2766 out_of_range_connection_points =
true;
2769 if (zeta_final < (*connection_points_pt)[n_connections-1])
2772 <<
"One of the specified connection points is out of the\n" 2773 <<
"curviline limits. We found that the point (" 2774 << (*connection_points_pt)[n_connections-1] <<
") is\n" 2775 <<
"greater than the final s value which is (" 2776 << zeta_final <<
").\n" 2777 <<
"Initial value: ("<<zeta_initial<<
")\n" 2778 <<
"Final value: ("<<zeta_final<<
")\n" 2780 out_of_range_connection_points =
true;
2785 if (zeta_initial < (*connection_points_pt)[0])
2788 <<
"One of the specified connection points is out of the\n" 2789 <<
"curviline limits. We found that the point (" 2790 << (*connection_points_pt)[0] <<
") is\n" <<
"greater than the" 2791 <<
"initial s value which is (" << zeta_initial <<
").\n" 2792 <<
"Initial value: ("<<zeta_initial<<
")\n" 2793 <<
"Final value: ("<<zeta_final<<
")\n" 2795 out_of_range_connection_points =
true;
2798 if (zeta_final > (*connection_points_pt)[n_connections-1])
2801 <<
"One of the specified connection points is out of the\n" 2802 <<
"curviline limits. We found that the point (" 2803 << (*connection_points_pt)[n_connections-1] <<
") is\n" 2804 <<
"less than the final s value which is (" 2805 << zeta_final <<
").\n" 2806 <<
"Initial value: ("<<zeta_initial<<
")\n" 2807 <<
"Final value: ("<<zeta_final<<
")\n" 2809 out_of_range_connection_points =
true;
2813 if (out_of_range_connection_points)
2816 OOMPH_CURRENT_FUNCTION,
2817 OOMPH_EXCEPTION_LOCATION);
2829 unsigned n_seg = boundary_pt->
nsegment();
2832 unsigned i_connection = 0;
2839 if (n_connections >= n_seg - 1)
2841 std::ostringstream warning_message;
2842 std::string output_string=
"UnstructuredTwoDMeshGeometryBase::";
2843 output_string+=
"create_vertex_coordinates_for_polyline_connections()";
2846 <<
"The number of segments specified for the curviline with\n" 2847 <<
"boundary id (" << boundary_pt->
boundary_id() <<
") is less " 2848 <<
"(or equal) than the ones that will be\ngenerated by using " 2849 <<
"the specified number of connection points.\n" 2850 <<
"You specified (" << n_seg <<
") segments but (" 2851 << n_connections + 1 <<
") segments\nwill be generated." 2855 OOMPH_EXCEPTION_LOCATION);
2858 boundary_pt->
nsegment() = n_connections + 1;
2860 vertex_coord.resize(n_seg+1);
2863 zeta[0]= zeta_initial;
2865 vertex_coord[0]=posn;
2867 polygonal_vertex_arclength_info.resize(n_seg+1);
2868 polygonal_vertex_arclength_info[0].first=0.0;
2869 polygonal_vertex_arclength_info[0].second=zeta_initial;
2872 for(i_connection = 0; i_connection < n_connections; i_connection++)
2876 zeta[0]= (*connection_points_pt)[i_connection];
2878 vertex_coord[i_connection + 1] = posn;
2881 polygonal_vertex_arclength_info[i_connection + 1].first=
2882 polygonal_vertex_arclength_info[i_connection].first+
2883 sqrt(pow(vertex_coord[i_connection + 1][0]-
2884 vertex_coord[i_connection][0],2)+
2885 pow(vertex_coord[i_connection + 1][1]-
2886 vertex_coord[i_connection][1],2));
2887 polygonal_vertex_arclength_info[i_connection + 1].second=zeta[0];
2892 zeta[0] = zeta_final;
2894 vertex_coord[n_seg]=posn;
2896 polygonal_vertex_arclength_info[n_seg].first=
2897 polygonal_vertex_arclength_info[n_seg-1].first+
2898 sqrt(pow(vertex_coord[n_seg][0]-vertex_coord[n_seg-1][0],2)+
2899 pow(vertex_coord[n_seg][1]-vertex_coord[n_seg-1][1],2));
2900 polygonal_vertex_arclength_info[n_seg].second = zeta_final;
2906 unsigned n_t_vertices = n_seg+1;
2909 unsigned l_vertices = n_t_vertices;
2912 unsigned n_assigned_vertices = 0;
2918 std::list<double> zeta_values_pt;
2919 zeta_values_pt.push_back(zeta_initial);
2920 for (
unsigned s = 0;
s < n_connections;
s++)
2922 zeta_values_pt.push_back((*connection_points_pt)[
s]);
2924 zeta_values_pt.push_back(zeta_final);
2927 l_vertices-= n_connections;
2928 n_assigned_vertices+= 2;
2929 n_assigned_vertices+= n_connections;
2934 double local_zeta_initial;
2935 double local_zeta_final;
2936 double local_zeta_increment;
2937 double local_zeta_insert;
2940 unsigned local_n_vertices;
2942 std::list<double>::iterator l_it = zeta_values_pt.begin();
2943 std::list<double>::iterator r_it = zeta_values_pt.begin();
2946 for (
unsigned h = 0; r_it!=zeta_values_pt.end(); l_it++,r_it++,h++)
2948 delta_z[h] = *r_it-*l_it;
2951 l_it = r_it = zeta_values_pt.begin();
2954 for (
unsigned h = 0; r_it!=zeta_values_pt.end(); h++)
2957 static_cast<unsigned>(((double)n_t_vertices * delta_z[h]) /
2958 std::fabs(zeta_final - zeta_initial));
2960 local_zeta_initial = *l_it;
2961 local_zeta_final = *r_it;
2962 local_zeta_increment =
2963 (local_zeta_final - local_zeta_initial) /
2964 (
double)(local_n_vertices + 1);
2966 for (
unsigned s=0;
s<local_n_vertices;
s++)
2969 local_zeta_initial + local_zeta_increment*double(
s+1);
2970 zeta_values_pt.insert(r_it, local_zeta_insert);
2971 n_assigned_vertices++;
2983 unsigned s = zeta_values_pt.size();
2985 if (s!=n_assigned_vertices)
2988 <<
"The total number of assigned vertices is different from\n" 2989 <<
"the number of elements in the z_values list. The number" 2990 <<
"of\nelements in the z_values list is (" << s <<
") but " 2992 <<
"of assigned vertices is (" << n_assigned_vertices <<
")." 2993 << std::endl << std::endl;
2995 OOMPH_CURRENT_FUNCTION,
2996 OOMPH_EXCEPTION_LOCATION);
3000 vertex_coord.resize(n_assigned_vertices);
3001 polygonal_vertex_arclength_info.resize(n_assigned_vertices);
3002 polygonal_vertex_arclength_info[0].first=0.0;
3003 polygonal_vertex_arclength_info[0].second=zeta_initial;
3006 l_it = zeta_values_pt.begin();
3007 for (
unsigned s = 0; l_it!=zeta_values_pt.end(); s++,l_it++)
3012 vertex_coord[
s] = posn;
3017 polygonal_vertex_arclength_info[
s].first=
3018 polygonal_vertex_arclength_info[s-1].first+
3019 sqrt(pow(vertex_coord[s][0]-vertex_coord[s-1][0],2)+
3020 pow(vertex_coord[s][1]-vertex_coord[s-1][1],2));
3030 unsigned nsample_per_segment=100;
3031 unsigned nsample=nsample_per_segment*n_seg;
3034 double zeta_increment=
3035 (zeta_final-zeta_initial)/(
double(nsample));
3039 zeta[0]=zeta_initial;
3046 double total_arclength=0.0;
3047 for (
unsigned i=1;
i<nsample;
i++)
3050 zeta[0]+=zeta_increment;
3056 total_arclength+=sqrt(pow(end_point[0]-start_point[0],2)+
3057 pow(end_point[1]-start_point[1],2));
3060 start_point=end_point;
3063 double local_zeta_initial;
3064 double local_zeta_final;
3065 double local_zeta_increment;
3068 unsigned local_n_vertices;
3070 std::list<double>::iterator l_it = zeta_values_pt.begin();
3071 std::list<double>::iterator r_it = zeta_values_pt.begin();
3074 for (
unsigned h = 0; r_it!=zeta_values_pt.end(); h++)
3078 local_zeta_initial = *l_it;
3079 local_zeta_final = *r_it;
3080 local_zeta_increment =
3081 (local_zeta_final - local_zeta_initial) /
3086 zeta[0]=local_zeta_initial;
3091 for (
unsigned i=1;
i<nsample;
i++)
3094 zeta[0]+=local_zeta_increment;
3100 delta_z[h]+=sqrt(pow(end_point[0]-start_point[0],2)+
3101 pow(end_point[1]-start_point[1],2));
3104 start_point=end_point;
3108 static_cast<unsigned>(((double)n_t_vertices * delta_z[h]) /
3112 double local_target_s_increment=
3113 delta_z[h]/double(local_n_vertices+1);
3116 zeta[0]=local_zeta_initial;
3123 for(
unsigned s=0;
s<local_n_vertices;
s++)
3127 double local_arclength_increment=0.0;
3128 for (
unsigned i=i_lo;
i<nsample;
i++)
3132 zeta[0]+=local_zeta_increment;
3138 local_arclength_increment+=
3139 sqrt(pow(end_point[0]-start_point[0],2)+
3140 pow(end_point[1]-start_point[1],2));
3143 start_point=end_point;
3146 if (local_arclength_increment>local_target_s_increment)
3156 zeta_values_pt.insert(r_it, zeta[0]);
3157 n_assigned_vertices++;
3169 unsigned h = zeta_values_pt.size();
3171 if (h!=n_assigned_vertices)
3174 <<
"The total number of assigned vertices is different from\n" 3175 <<
"the number of elements in the z_values list. The number of\n" 3176 <<
"elements in the z_values list is (" << h <<
") but the number\n" 3177 <<
"of assigned vertices is (" << n_assigned_vertices <<
")." 3178 << std::endl << std::endl;
3180 OOMPH_CURRENT_FUNCTION,
3181 OOMPH_EXCEPTION_LOCATION);
3185 vertex_coord.resize(n_assigned_vertices);
3186 polygonal_vertex_arclength_info.resize(n_assigned_vertices);
3187 polygonal_vertex_arclength_info[0].first=0.0;
3188 polygonal_vertex_arclength_info[0].second=zeta_initial;
3191 l_it = zeta_values_pt.begin();
3192 for (
unsigned s = 0; l_it!=zeta_values_pt.end();
s++,l_it++)
3197 vertex_coord[
s] = posn;
3202 polygonal_vertex_arclength_info[
s].first=
3203 polygonal_vertex_arclength_info[
s-1].first+
3204 sqrt(pow(vertex_coord[
s][0]-vertex_coord[
s-1][0],2)+
3205 pow(vertex_coord[
s][1]-vertex_coord[
s-1][1],2));
3206 polygonal_vertex_arclength_info[
s].second=zeta[0];
3229 std::ostringstream error_message;
3231 <<
"TriangleMeshClosedCurve that defines outer boundary\n" 3232 <<
"must be made up of at least two " 3233 <<
"TriangleMeshCurveSections\n" 3234 <<
"to allow the automatic set up boundary coordinates.\n" 3235 <<
"Yours only has (" << nb <<
")" << std::endl;
3237 OOMPH_CURRENT_FUNCTION,
3238 OOMPH_EXCEPTION_LOCATION);
3255 for (
unsigned b=0;b<nb;b++)
3267 if (curviline_pt != 0)
3273 my_boundary_polyline_pt[b]=curviline_to_polyline(curviline_pt,bnd_id);
3285 Boundary_curve_section_pt[bnd_id] = my_boundary_polyline_pt[b];
3288 Free_curve_section_pt.insert(my_boundary_polyline_pt[b]);
3291 if (bnd_id>max_bnd_id_local)
3293 max_bnd_id_local=bnd_id;
3297 else if (polyline_pt != 0)
3303 my_boundary_polyline_pt[b] = polyline_pt;
3315 Boundary_curve_section_pt[bnd_id] = my_boundary_polyline_pt[b];
3318 if (bnd_id>max_bnd_id_local)
3320 max_bnd_id_local=bnd_id;
3325 std::ostringstream error_stream;
3327 <<
"The 'curve_segment' is not a curviline neither a\n " 3328 <<
"polyline: What is it?\n" 3332 OOMPH_CURRENT_FUNCTION,
3333 OOMPH_EXCEPTION_LOCATION);
3344 Free_polygon_pt.insert(output_polygon_pt);
3349 output_polygon_pt->set_polyline_unrefinement_tolerance(
3354 for (
unsigned b=0;b<nb;b++)
3357 my_boundary_polyline_pt[b]->
3358 set_unrefinement_tolerance(unrefinement_tolerance[b]);
3360 my_boundary_polyline_pt[b]->
3361 set_refinement_tolerance(refinement_tolerance[b]);
3364 my_boundary_polyline_pt[b]->set_maximum_length(max_length[b]);
3366 return output_polygon_pt;
3391 for (
unsigned i = 0;
i < nb;
i++)
3402 if (curviline_pt != 0)
3408 my_boundary_polyline_pt[
i]=curviline_to_polyline(curviline_pt,bnd_id);
3420 copy_connection_information(curviline_pt,my_boundary_polyline_pt[
i]);
3423 Boundary_curve_section_pt[bnd_id] = my_boundary_polyline_pt[
i];
3426 Free_curve_section_pt.insert(my_boundary_polyline_pt[i]);
3429 if (bnd_id>max_bnd_id_local)
3431 max_bnd_id_local=bnd_id;
3434 else if (polyline_pt != 0)
3440 my_boundary_polyline_pt[
i] = polyline_pt;
3452 copy_connection_information(polyline_pt, my_boundary_polyline_pt[
i]);
3455 Boundary_curve_section_pt[bnd_id] = my_boundary_polyline_pt[
i];
3458 if (bnd_id>max_bnd_id_local)
3460 max_bnd_id_local=bnd_id;
3465 std::ostringstream error_stream;
3467 <<
"The 'curve_segment' (open) is not a curviline neither a\n " 3468 <<
"polyline: What is it?\n" 3471 OOMPH_CURRENT_FUNCTION,
3472 OOMPH_EXCEPTION_LOCATION);
3481 Free_open_curve_pt.insert(output_open_polyline_pt);
3484 output_open_polyline_pt->set_polyline_refinement_tolerance(
3486 output_open_polyline_pt->set_polyline_unrefinement_tolerance(
3491 for (
unsigned b=0;b<nb;b++)
3494 my_boundary_polyline_pt[b]->
3495 set_unrefinement_tolerance(unrefinement_tolerance[b]);
3497 my_boundary_polyline_pt[b]->
3498 set_refinement_tolerance(refinement_tolerance[b]);
3501 my_boundary_polyline_pt[b]->set_maximum_length(max_length[b]);
3503 return output_open_polyline_pt;
3518 std::ostringstream error_message;
3520 <<
"TriangleMeshCurve that defines closed boundary\n" 3521 <<
"must be made up of at least two " 3522 <<
"TriangleMeshCurveSection\n" 3523 <<
"to allow the automatic set up boundary coordinates.\n" 3524 <<
"Yours only has " << nb << std::endl;
3526 OOMPH_CURRENT_FUNCTION,
3527 OOMPH_EXCEPTION_LOCATION);
3537 dynamic_cast<GeomObject*
>(input_closed_curve_pt);
3540 if (bound_geom_obj_pt!=0)
3543 for(
unsigned p=0;p<n_poly;p++)
3549 Boundary_geom_object_pt[b_index] = bound_geom_obj_pt;
3554 Boundary_coordinate_limits[b_index].resize(2);
3555 Boundary_coordinate_limits[b_index][0] = p;
3556 Boundary_coordinate_limits[b_index][1] = p + 1.0;
3563 Immersed_rigid_body_triangle_mesh_polygon_used =
true;
3569 for (
unsigned b=0;b<nb;b++)
3575 if (curviline_pt != 0)
3580 zeta_bound[1] = curviline_pt->
zeta_end();
3586 Boundary_geom_object_pt[bnd_id] =
3588 Boundary_coordinate_limits[bnd_id] = zeta_bound;
3603 for (
unsigned b=0;b<nb;b++)
3609 if (curviline_pt != 0)
3614 zeta_bound[1] = curviline_pt->
zeta_end();
3620 Boundary_geom_object_pt[bnd_id] =
3622 Boundary_coordinate_limits[bnd_id] = zeta_bound;
3627 #endif // OOMPH_HAS_TRIANGLE_LIB 3631 #ifdef OOMPH_HAS_TRIANGLE_LIB 3644 this->create_vertex_coordinates_for_polyline_connections(
3645 curviline_pt,bound,polygonal_vertex_arclength);
3649 this->create_vertex_coordinates_for_polyline_no_connections(
3650 curviline_pt,bound,polygonal_vertex_arclength);
3654 Polygonal_vertex_arclength_info[bnd_id]=polygonal_vertex_arclength;
3665 double s_tolerance=1.0e-14;
3666 return get_associated_vertex_to_svalue(target_s_value,bnd_id,s_tolerance);
3673 double &s_tolerance)
3678 &Polygonal_vertex_arclength_info[bnd_id];
3681 unsigned vector_size = vertex_info->size();
3684 unsigned n_vertex = 0;
3690 double s = (*vertex_info)[n_vertex].second;
3693 if (std::fabs(s - target_s_value) < s_tolerance)
3701 while(n_vertex < vector_size);
3705 if (n_vertex >= vector_size)
3707 std::ostringstream error_message;
3709 <<
"Could not find the associated vertex number in\n" 3710 <<
"boundary " << bnd_id <<
" with the given s\n" 3711 <<
"connection value (" << target_s_value <<
") using\n" 3712 <<
"this tolerance: " << s_tolerance << std::endl;
3714 OOMPH_CURRENT_FUNCTION,
3715 OOMPH_EXCEPTION_LOCATION);
3722 #endif // OOMPH_HAS_TRIANGLE_LIB 3733 template<
class ELEMENT>
3749 unsigned n_repeated_ele = 0;
3751 unsigned n_regions = this->nregion();
3753 #ifdef OOMPH_HAS_MPI 3757 std::map<FiniteElement*,FiniteElement*> face_to_bulk_element_pt;
3767 for (
unsigned rr = 0 ; rr < n_regions; rr++)
3769 unsigned region_id =
static_cast<unsigned>(this->Region_attribute[rr]);
3772 double diff=fabs(Region_attribute[rr]-
3773 static_cast<double>(static_cast<unsigned>(
3774 this->Region_attribute[rr])));
3777 std::ostringstream error_message;
3779 <<
"Region attributes should be unsigneds because we \n" 3780 <<
"only use them to set region ids\n";
3782 OOMPH_CURRENT_FUNCTION,
3783 OOMPH_EXCEPTION_LOCATION);
3788 unsigned nel_in_region =
3789 this->nboundary_element_in_region(b,region_id);
3790 unsigned nel_repeated_in_region = 0;
3793 if (!Suppress_warning_about_regions_and_boundaries)
3795 if (nel_in_region==0)
3797 std::ostringstream warning_message;
3799 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
3801 <<
"There are no elements associated with boundary (" << b <<
")\n" 3802 <<
"in region (" << region_id <<
"). This could happen because:\n" 3803 <<
"1) You did not specify boundaries with this boundary id.\n" 3804 <<
"---- Review carefully the indexing of your boundaries.\n" 3805 <<
"2) The boundary (" << b <<
") is not associated with region (" 3806 << region_id <<
").\n" 3807 <<
"---- The boundary does not touch the region.\n" 3808 <<
"You can suppress this warning by setting the static public bool\n\n" 3809 <<
" UnstructuredTwoDMeshGeometryBase::Suppress_warning_about_regions_and_boundaries\n\n" 3813 OOMPH_EXCEPTION_LOCATION);
3820 if (nel_in_region > 0)
3824 bool repeated =
false;
3827 for (
unsigned e = 0;
e < nel_in_region;
e++)
3831 this->boundary_element_in_region_pt(b, region_id,
e);
3833 #ifdef OOMPH_HAS_MPI 3835 if (this->is_mesh_distributed() && bulk_elem_pt->
is_halo())
3846 this->face_index_at_boundary_in_region(b, region_id,
e);
3852 bulk_elem_pt, face_index);
3854 const unsigned n_nodes = tmp_ele_pt->
nnode();
3856 std::pair<Node*, Node*> tmp_pair =
3857 std::make_pair(tmp_ele_pt->
node_pt(0),
3858 tmp_ele_pt->
node_pt(n_nodes - 1));
3860 std::pair<Node*, Node*> tmp_pair_inverse =
3861 std::make_pair(tmp_ele_pt->
node_pt(n_nodes - 1),
3865 const unsigned n_done_nodes = done_nodes_pt.size();
3866 for (
unsigned l = 0; l < n_done_nodes; l++)
3868 if (tmp_pair == done_nodes_pt[l] || tmp_pair_inverse
3869 == done_nodes_pt[l])
3871 nel_repeated_in_region++;
3881 done_nodes_pt.push_back(tmp_pair);
3882 #ifdef OOMPH_HAS_MPI 3887 if (this->is_mesh_distributed())
3889 face_to_bulk_element_pt[tmp_ele_pt] = bulk_elem_pt;
3893 face_el_pt.push_back(tmp_ele_pt);
3906 if (outfile.is_open())
3908 face_el_pt[face_el_pt.size() - 1]->output(outfile);
3912 nel += nel_in_region;
3914 n_repeated_ele += nel_repeated_in_region;
3925 nel = this->nboundary_element(b);
3928 if (!Suppress_warning_about_regions_and_boundaries)
3932 std::ostringstream warning_message;
3934 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
3936 <<
"There are no elements associated with boundary (" << b <<
").\n" 3937 <<
"This could happen because you did not specify boundaries with\n" 3938 <<
"this boundary id. Review carefully the indexing of your\n" 3942 OOMPH_EXCEPTION_LOCATION);
3952 bool repeated =
false;
3955 for (
unsigned e = 0;
e < nel;
e++)
3960 #ifdef OOMPH_HAS_MPI 3963 if (this->is_mesh_distributed() && bulk_elem_pt->
is_halo())
3974 int face_index = this->face_index_at_boundary(b,
e);
3979 bulk_elem_pt, face_index);
3981 const unsigned n_nodes = tmp_ele_pt->
nnode();
3983 std::pair<Node*, Node*> tmp_pair =
3984 std::make_pair(tmp_ele_pt->
node_pt(0),
3985 tmp_ele_pt->
node_pt(n_nodes - 1));
3987 std::pair<Node*, Node*> tmp_pair_inverse =
3988 std::make_pair(tmp_ele_pt->
node_pt(n_nodes - 1),
3992 const unsigned n_done_nodes = done_nodes_pt.size();
3993 for (
unsigned l = 0; l < n_done_nodes; l++)
3995 if (tmp_pair == done_nodes_pt[l] || tmp_pair_inverse
3996 == done_nodes_pt[l])
4008 done_nodes_pt.push_back(tmp_pair);
4009 #ifdef OOMPH_HAS_MPI 4014 if (this->is_mesh_distributed())
4016 face_to_bulk_element_pt[tmp_ele_pt] = bulk_elem_pt;
4019 face_el_pt.push_back(tmp_ele_pt);
4032 if (outfile.is_open())
4034 face_el_pt[face_el_pt.size() - 1]->output(outfile);
4044 nel -= n_repeated_ele;
4047 if (nel!=face_el_pt.size())
4049 std::ostringstream error_message;
4051 <<
"The independent counting of face elements (" << nel <<
") for " 4052 <<
"boundary (" << b <<
") is different\n" 4053 <<
"from the real number of face elements in the container (" 4054 << face_el_pt.size() <<
")\n";
4056 OOMPH_CURRENT_FUNCTION,
4057 OOMPH_EXCEPTION_LOCATION);
4070 std::vector<bool> is_halo_face_element(nel,
false);
4073 unsigned nnon_halo_face_elements = 0;
4075 #ifdef OOMPH_HAS_MPI 4078 if (this->is_mesh_distributed())
4080 for (
unsigned ie = 0; ie < nel; ie++)
4085 face_to_bulk_element_pt[face_ele_pt];
4087 if (!tmp_bulk_ele_pt->
is_halo())
4090 is_halo_face_element[ie] =
false;
4092 nnon_halo_face_elements++;
4097 is_halo_face_element[ie] =
true;
4103 #endif // OOMPH_HAS_MPI 4107 nnon_halo_face_elements = nel;
4109 #ifdef OOMPH_HAS_MPI 4115 const unsigned nhalo_face_element = nel - nnon_halo_face_elements;
4117 if (nhalo_face_element > 0)
4119 std::ostringstream error_message;
4121 <<
"There should not be halo face elements since they were not\n" 4122 <<
"considered when computing the face elements.\n" 4123 <<
"The number of found halo face elements is: (" 4124 << nhalo_face_element <<
").\n\n";
4126 OOMPH_CURRENT_FUNCTION,
4127 OOMPH_EXCEPTION_LOCATION);
4143 unsigned nsorted_face_elements = 0;
4147 std::map<FiniteElement*, bool> done_el;
4152 std::map<FiniteElement*, bool> is_inverted;
4157 while(nsorted_face_elements < nnon_halo_face_elements)
4161 std::list<FiniteElement*> sorted_el_pt;
4167 bool found_initial_face_element =
false;
4172 #ifdef OOMPH_HAS_MPI 4173 if (this->is_mesh_distributed())
4175 for (iface = 0; iface < nel; iface++)
4178 if (!is_halo_face_element[iface])
4180 ele_face_pt = face_el_pt[iface];
4182 if (!done_el[ele_face_pt])
4187 found_initial_face_element =
true;
4190 nsorted_face_elements++;
4194 sorted_el_pt.push_back(ele_face_pt);
4196 done_el[ele_face_pt] =
true;
4204 #endif // #ifdef OOMPH_HAS_MPI 4208 ele_face_pt = face_el_pt[0];
4211 found_initial_face_element =
true;
4214 nsorted_face_elements++;
4218 sorted_el_pt.push_back(ele_face_pt);
4220 done_el[ele_face_pt] =
true;
4222 #ifdef OOMPH_HAS_MPI 4227 if (!found_initial_face_element)
4229 std::ostringstream error_message;
4231 <<
"Could not find an initial face element for the current segment\n";
4233 OOMPH_CURRENT_FUNCTION,
4234 OOMPH_EXCEPTION_LOCATION);
4239 const unsigned nnod = ele_face_pt->
nnode();
4244 Node* right_node_pt = ele_face_pt->
node_pt(nnod - 1);
4248 bool face_element_added =
false;
4258 for (
unsigned iiface=iface;iiface<nel;iiface++)
4261 face_element_added =
false;
4264 ele_face_pt = face_el_pt[iiface];
4268 if (!(done_el[ele_face_pt] || is_halo_face_element[iiface]))
4271 Node* local_left_node_pt = ele_face_pt->
node_pt(0);
4272 Node* local_right_node_pt = ele_face_pt->
node_pt(nnod - 1);
4275 if (left_node_pt == local_right_node_pt)
4277 left_node_pt = local_left_node_pt;
4278 sorted_el_pt.push_front(ele_face_pt);
4279 is_inverted[ele_face_pt] =
false;
4280 face_element_added =
true;
4283 else if (left_node_pt == local_left_node_pt)
4285 left_node_pt = local_right_node_pt;
4286 sorted_el_pt.push_front(ele_face_pt);
4287 is_inverted[ele_face_pt] =
true;
4288 face_element_added =
true;
4291 else if (right_node_pt == local_left_node_pt)
4293 right_node_pt = local_right_node_pt;
4294 sorted_el_pt.push_back(ele_face_pt);
4295 is_inverted[ele_face_pt] =
false;
4296 face_element_added =
true;
4299 else if (right_node_pt == local_right_node_pt)
4301 right_node_pt = local_left_node_pt;
4302 sorted_el_pt.push_back(ele_face_pt);
4303 is_inverted[ele_face_pt] =
true;
4304 face_element_added =
true;
4307 if (face_element_added)
4309 done_el[ele_face_pt] =
true;
4310 nsorted_face_elements++;
4316 }
while(face_element_added &&
4317 (nsorted_face_elements < nnon_halo_face_elements));
4320 segment_sorted_ele_pt.push_back(sorted_el_pt);
4324 #ifdef OOMPH_HAS_MPI 4325 if (!this->is_mesh_distributed())
4329 if (nsorted_face_elements!=nel||segment_sorted_ele_pt.size()!=1)
4331 std::ostringstream error_message;
4332 error_message <<
"Was only able to setup boundary coordinate on " 4333 <<
"boundary " << b <<
"\nfor "<< nsorted_face_elements
4334 <<
" of "<< nel <<
" face elements. This usually means\n" 4335 <<
"that the boundary is not simply connected.\n\n" 4336 <<
"Re-run the setup_boundary_coordintes() function\n" 4337 <<
"with an output file specified " 4338 <<
"as the second argument.\n" 4339 <<
"This file will contain FaceElements that\n" 4340 <<
"oomph-lib believes to be located on the boundary.\n" 4343 OOMPH_CURRENT_FUNCTION,
4344 OOMPH_EXCEPTION_LOCATION);
4346 #ifdef OOMPH_HAS_MPI 4371 const unsigned nsegments = segment_sorted_ele_pt.size();
4374 if (nnon_halo_face_elements > 0 && nsegments == 0)
4376 std::ostringstream error_message;
4378 <<
"The number of segments is zero, but the number of nonhalo\n" 4379 <<
"elements is: (" << nnon_halo_face_elements <<
")\n";
4381 OOMPH_CURRENT_FUNCTION,
4382 OOMPH_EXCEPTION_LOCATION);
4390 #ifdef OOMPH_HAS_MPI 4393 this->flush_boundary_segment_node(b);
4396 this->set_nboundary_segment_node(b,nsegments);
4398 #endif // #ifdef OOMPH_HAS_MPI 4402 for (
unsigned is = 0; is < nsegments; is++)
4406 if (segment_sorted_ele_pt[is].size() == 0)
4408 std::ostringstream error_message;
4410 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
4412 <<
"The (" << is <<
")-th segment has no elements\n";
4415 OOMPH_EXCEPTION_LOCATION);
4421 FiniteElement* first_ele_pt = segment_sorted_ele_pt[is].front();
4424 unsigned nnod = first_ele_pt->
nnode();
4427 Node *first_node_pt = first_ele_pt->node_pt(0);
4428 if (is_inverted[first_ele_pt])
4430 first_node_pt = first_ele_pt->node_pt(nnod-1);
4434 double x_left = first_node_pt->
x(0);
4435 double y_left = first_node_pt->
x(1);
4445 std::set<Node*> local_nodes_pt;
4446 local_nodes_pt.insert(first_node_pt);
4448 #ifdef OOMPH_HAS_MPI 4451 this->add_boundary_segment_node(b,is,first_node_pt);
4453 #endif // #ifdef OOMPH_HAS_MPI 4456 for (std::list<FiniteElement*>::iterator it =
4457 segment_sorted_ele_pt[is].begin();
4458 it != segment_sorted_ele_pt[is].end(); it++)
4466 if (is_inverted[el_pt])
4473 for (
unsigned j = 1; j < nnod; j++)
4475 Node* nod_pt = el_pt->node_pt(k_nod);
4479 double x_right = nod_pt->
x(0);
4480 double y_right = nod_pt->
x(1);
4484 (x_right - x_left) * (x_right - x_left) + (y_right - y_left)
4485 * (y_right - y_left));
4496 local_nodes_pt.insert(nod_pt);
4498 #ifdef OOMPH_HAS_MPI 4501 this->add_boundary_segment_node(b, is, nod_pt);
4503 #endif // #ifdef OOMPH_HAS_MPI 4509 segment_arclength[is] = zeta[0];
4512 segment_all_nodes_pt.push_back(local_nodes_pt);
4546 #ifdef OOMPH_HAS_MPI 4553 if (this->is_mesh_distributed() && Assigned_segments_initial_zeta_values[b])
4560 for (
unsigned is = 0; is < nsegments; is++)
4567 if (this->boundary_geom_object_pt(b)!=0)
4573 FiniteElement* first_ele_pt=segment_sorted_ele_pt[is].front();
4576 const unsigned nnod = first_ele_pt->
nnode();
4580 if (is_inverted[first_ele_pt])
4582 first_node_pt = first_ele_pt->node_pt(nnod-1);
4586 FiniteElement* last_ele_pt=segment_sorted_ele_pt[is].back();
4589 Node *last_node_pt = last_ele_pt->
node_pt(nnod-1);
4590 if (is_inverted[last_ele_pt])
4592 last_node_pt = last_ele_pt->node_pt(0);
4605 if (current_segment_initial_zeta[0] <
4606 current_segment_final_zeta[0])
4610 else if (current_segment_initial_zeta[0] >
4611 current_segment_final_zeta[0])
4613 std::stringstream error_message;
4615 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
4617 <<
"The zeta values are in decreasing order, this is weird\n" 4618 <<
"since they have just been set-up in increasing order few\n" 4620 <<
"Boundary: (" << b <<
")\n" 4621 <<
"Segment: (" << is <<
")\n" 4622 <<
"Initial zeta value: (" 4623 << current_segment_initial_zeta[0] <<
")\n" 4624 <<
"Initial coordinate: (" << first_node_pt->
x(0) <<
", " 4625 << first_node_pt->
x(1) <<
")\n" 4626 <<
"Final zeta value: (" 4627 << current_segment_final_zeta[0] <<
")\n" 4628 <<
"Initial coordinate: (" << last_node_pt->
x(0) <<
", " 4629 << last_node_pt->
x(1) <<
")\n";
4632 OOMPH_EXCEPTION_LOCATION);
4636 std::stringstream error_message;
4638 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
4640 <<
"It was not possible to determine whether the zeta values on" 4641 <<
"the current segment\nof the boundary are in" 4642 <<
"increasing or decreasing order\n\n" 4643 <<
"Boundary: (" << b <<
")\n" 4644 <<
"Segment: (" << is <<
")\n" 4645 <<
"Arclength: (" << segment_arclength[is] <<
"\n" 4646 <<
"Initial zeta value: (" 4647 << current_segment_initial_zeta[0] <<
")\n" 4648 <<
"Initial coordinate: (" << first_node_pt->
x(0) <<
", " 4649 << first_node_pt->
x(1) <<
")\n" 4650 <<
"Final zeta value: (" 4651 << current_segment_final_zeta[0] <<
")\n" 4652 <<
"Initial coordinate: (" << last_node_pt->
x(0) <<
", " 4653 << last_node_pt->
x(1) <<
")\n";
4656 OOMPH_EXCEPTION_LOCATION);
4658 #endif // #ifdef PARANOID 4662 const double original_segment_initial_zeta =
4663 boundary_segment_initial_zeta(b)[is];
4664 const double original_segment_final_zeta =
4665 boundary_segment_final_zeta(b)[is];
4669 if (original_segment_final_zeta > original_segment_initial_zeta)
4674 if (boundary_segment_inverted(b)[is])
4679 std::set<Node*> all_nodes_pt = segment_all_nodes_pt[is];
4680 for (std::set<Node*>::iterator it = all_nodes_pt.begin();
4681 it != all_nodes_pt.end(); it++)
4685 Node* nod_pt = (*it);
4689 zeta[0] = segment_arclength[is] - zeta[0];
4700 else if (original_segment_final_zeta < original_segment_initial_zeta)
4705 if (boundary_segment_inverted(b)[is])
4714 std::set<Node*> all_nodes_pt = segment_all_nodes_pt[is];
4715 for (std::set<Node*>::iterator it = all_nodes_pt.begin();
4716 it != all_nodes_pt.end(); it++)
4720 Node* nod_pt = (*it);
4724 zeta[0] = segment_arclength[is] - zeta[0];
4733 std::stringstream error_message;
4735 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
4737 <<
"It was not possible to identify if the zeta values on the\n" 4738 <<
"current segment in the boundary should go in increasing\n" 4739 <<
"or decreasing order.\n\n" 4740 <<
"Boundary: (" << b <<
")\n" 4741 <<
"Segment: (" << is <<
")\n" 4742 <<
"Initial zeta value: (" 4743 << original_segment_initial_zeta <<
")\n" 4744 <<
"Final zeta value: (" 4745 << original_segment_final_zeta <<
")\n";
4748 OOMPH_EXCEPTION_LOCATION);
4763 #endif // #ifdef OOMPH_HAS_MPI 4767 if (segment_all_nodes_pt.size() != nsegments)
4769 std::ostringstream error_message;
4771 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
4773 <<
"The number of segments ("<<nsegments<<
") and the number of " 4774 <<
"sets of nodes ("<<segment_all_nodes_pt.size()<<
") representing\n" 4775 <<
"the\nsegments is different!!!\n\n";
4778 OOMPH_EXCEPTION_LOCATION);
4806 double boundary_arclength = 0.0;
4813 #ifdef OOMPH_HAS_MPI 4814 if (this->is_mesh_distributed() && Assigned_segments_initial_zeta_values[b])
4821 first_coordinate = boundary_initial_coordinate(b);
4822 last_coordinate = boundary_final_coordinate(b);
4825 first_node_zeta_coordinate = boundary_initial_zeta_coordinate(b);
4826 last_node_zeta_coordinate = boundary_final_zeta_coordinate(b);
4830 boundary_arclength = std::max(first_node_zeta_coordinate[0],
4831 last_node_zeta_coordinate[0]);
4834 if (boundary_arclength == 0)
4836 std::ostringstream error_message;
4838 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
4839 error_message <<
"The boundary arclength is zero for boundary (" 4843 OOMPH_EXCEPTION_LOCATION);
4849 if (this->boundary_geom_object_pt(b)!=0)
4851 initial_segment_zeta = boundary_segment_initial_zeta(b);
4852 final_segment_zeta = boundary_segment_final_zeta(b);
4856 initial_segment_arclength = boundary_segment_initial_arclength(b);
4857 final_segment_arclength = boundary_segment_final_arclength(b);
4868 #endif // #ifdef OOMPH_HAS_MPI 4873 if (this->boundary_geom_object_pt(b)!=0)
4875 initial_segment_zeta[0] = this->boundary_coordinate_limits(b)[0];
4876 final_segment_zeta[0] = this->boundary_coordinate_limits(b)[1];
4883 initial_segment_arclength[0] = 0.0;
4885 #ifdef OOMPH_HAS_MPI 4889 #endif // #ifdef OOMPH_HAS_MPI 4903 for (
unsigned is = 0; is < nsegments; is++)
4906 if (segment_sorted_ele_pt[is].size() == 0)
4908 std::ostringstream error_message;
4910 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
4912 <<
"The (" << is <<
")-th segment has no elements\n";
4915 OOMPH_EXCEPTION_LOCATION);
4922 #ifdef OOMPH_HAS_MPI 4927 if (!Assigned_segments_initial_zeta_values[b])
4929 #endif // #ifdef OOMPH_HAS_MPI 4932 FiniteElement* first_ele_pt = segment_sorted_ele_pt[is].front();
4935 const unsigned nnod = first_ele_pt->
nnode();
4939 if (is_inverted[first_ele_pt])
4941 first_node_pt = first_ele_pt->node_pt(nnod-1);
4945 FiniteElement* last_ele_pt = segment_sorted_ele_pt[is].back();
4948 Node *last_node_pt = last_ele_pt->
node_pt(nnod-1);
4949 if (is_inverted[last_ele_pt])
4951 last_node_pt = last_ele_pt->node_pt(0);
4955 for (
unsigned i = 0;
i < 2;
i++)
4957 first_coordinate[
i] = first_node_pt->
x(
i);
4958 last_coordinate[
i] = last_node_pt->
x(
i);
4965 #ifdef OOMPH_HAS_MPI 4967 #endif // #ifdef OOMPH_HAS_MPI 4970 std::set<Node*> all_nodes_pt = segment_all_nodes_pt[is];
4974 GeomObject*
const geom_object_pt = this->boundary_geom_object_pt(b);
4975 if (geom_object_pt != 0)
4977 Vector<double> bound_coord_limits=this->boundary_coordinate_limits(b);
4985 zeta[0] = bound_coord_limits[0];
4990 geom_object_pt->
position(zeta, first_geom_object_location);
4994 zeta[0] = bound_coord_limits[1];
4999 geom_object_pt->
position(zeta, last_geom_object_location);
5004 double tmp_error = 0.0;
5005 for (
unsigned i = 0;
i < 2;
i++)
5007 const double dist = first_geom_object_location[
i]
5008 - first_coordinate[
i];
5009 tmp_error += dist * dist;
5011 error += sqrt(tmp_error);
5013 for (
unsigned i = 0;
i < 2;
i++)
5016 last_geom_object_location[
i] - last_coordinate[
i];
5017 tmp_error += dist * dist;
5019 error += sqrt(tmp_error);
5024 double rev_error = 0.0;
5026 for (
unsigned i = 0;
i < 2;
i++)
5029 first_geom_object_location[
i] - last_coordinate[
i];
5030 tmp_error += dist * dist;
5032 rev_error += sqrt(tmp_error);
5034 for (
unsigned i = 0;
i < 2;
i++)
5037 last_geom_object_location[
i] - first_coordinate[
i];
5038 tmp_error += dist * dist;
5040 rev_error += sqrt(tmp_error);
5043 const unsigned n_vertex =
5044 Polygonal_vertex_arclength_info[b].size();
5048 = Polygonal_vertex_arclength_info[b];
5053 if (error < rev_error)
5060 else if (error > rev_error)
5066 double temp = bound_coord_limits[0];
5067 bound_coord_limits[0] = bound_coord_limits[1];
5068 bound_coord_limits[1] = temp;
5070 #ifdef OOMPH_HAS_MPI 5073 if (!this->is_mesh_distributed())
5076 temp = initial_segment_zeta[is];
5077 initial_segment_zeta[is] = final_segment_zeta[is];
5078 final_segment_zeta[is] = temp;
5079 #ifdef OOMPH_HAS_MPI 5083 for (
unsigned v = 0; v < n_vertex; v++)
5085 polygonal_vertex_arclength[v].first
5086 = Polygonal_vertex_arclength_info[b][v].first;
5088 polygonal_vertex_arclength[v].second
5089 = Polygonal_vertex_arclength_info[b][n_vertex - v - 1].second;
5094 std::ostringstream error_stream;
5096 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
5097 error_stream <<
"Something very strange has happened.\n" 5098 <<
"The error between the endpoints of the geometric object\n" 5099 <<
"and the first and last nodes on the boundary is the same\n" 5100 <<
"irrespective of the direction of the coordinate.\n" 5101 <<
"This probably means that things are way off.\n" 5102 <<
"The errors are " << error <<
" and " << rev_error <<
"\n";
5103 std::cout << error_stream.str();
5106 OOMPH_EXCEPTION_LOCATION);
5115 const double zeta_old_range = segment_arclength[is];
5120 double zeta_new_range = final_segment_zeta[is] - initial_segment_zeta[is];
5122 double initial_local_segment_zeta = initial_segment_zeta[is];
5124 #ifdef OOMPH_HAS_MPI 5129 if (this->is_mesh_distributed() && Assigned_segments_initial_zeta_values[b])
5132 zeta_new_range=std::fabs(final_segment_zeta[is]-initial_segment_zeta[is]);
5135 initial_local_segment_zeta=std::min(initial_segment_zeta[is],
5136 final_segment_zeta[is]);
5143 unsigned use_old =
false;
5148 for (std::set<Node*>::iterator it = all_nodes_pt.begin();
5149 it != all_nodes_pt.end(); it++)
5152 Node* nod_pt = (*it);
5160 zeta[0]=initial_local_segment_zeta+
5161 (zeta_new_range/zeta_old_range)*(zeta[0]);
5169 for (
unsigned v = 1; v < n_vertex; v++)
5171 if ((zeta[0] >= polygonal_vertex_arclength[v - 1].first)
5172 && (zeta[0] <= polygonal_vertex_arclength[v].first))
5176 (polygonal_vertex_arclength[v].second
5177 - polygonal_vertex_arclength[v - 1].second);
5179 double delta_polyarc =
5180 (polygonal_vertex_arclength[v].first
5181 - polygonal_vertex_arclength[v - 1].first);
5184 double zeta_new = polygonal_vertex_arclength[v - 1].second
5185 + delta_zeta * (zeta[0] - polygonal_vertex_arclength[v - 1].first) /
5202 double diff=std::fabs(zeta[0]-
5203 polygonal_vertex_arclength[n_vertex-1].first);
5206 std::ostringstream error_stream;
5208 <<
"Wasn't able to locate the polygonal arclength exactly\n" 5209 <<
"during re-setup of boundary coordinates and have\n" 5210 <<
"assumed that we're dealing with the final point along\n" 5211 <<
"the curvilinear segment and encountered some roundoff\n" 5212 <<
"However,the difference in the polygonal zeta coordinates\n" 5213 <<
"between zeta[0] " << zeta[0]
5214 <<
" and the originallly stored value " 5215 << polygonal_vertex_arclength[n_vertex-1].first <<
"\n" 5216 <<
"is " << diff <<
" which exceeds the threshold specified\n" 5217 <<
"in the publically modifiable variable\n" 5218 <<
"ToleranceForVertexMismatchInPolygons::Tolerable_error\n" 5219 <<
"whose current value is: " 5221 <<
"\nPlease check your mesh carefully and increase the\n" 5222 <<
"threshold if you're sure this is appropriate\n";
5224 OOMPH_CURRENT_FUNCTION,
5225 OOMPH_EXCEPTION_LOCATION);
5228 zeta[0] = polygonal_vertex_arclength[n_vertex - 1].second;
5239 double z_initial = initial_segment_arclength[is];
5246 bottom_left_coordinate = first_coordinate;
5250 bottom_left_zeta_coordinate = first_node_zeta_coordinate;
5254 if (last_coordinate[1] < bottom_left_coordinate[1])
5257 bottom_left_coordinate = last_coordinate;
5260 bottom_left_zeta_coordinate = last_node_zeta_coordinate;
5263 else if (last_coordinate[1] == bottom_left_coordinate[1])
5266 if (last_coordinate[0] < bottom_left_coordinate[0])
5270 bottom_left_coordinate = last_coordinate;
5273 bottom_left_zeta_coordinate = last_node_zeta_coordinate;
5282 zeta = bottom_left_zeta_coordinate;
5283 const double zeta_ref = zeta[0];
5286 double zeta_max = 0.0;
5287 for (std::set<Node*>::iterator it = all_nodes_pt.begin(); it
5288 != all_nodes_pt.end(); it++)
5290 Node* nod_pt = (*it);
5293 #ifdef OOMPH_HAS_MPI 5299 if (this->is_mesh_distributed() &&
5300 Assigned_segments_initial_zeta_values[b])
5304 if (boundary_segment_inverted(b)[is])
5306 zeta[0] = segment_arclength[is] - zeta[0];
5310 #endif // #ifdef OOMPH_HAS_MPI 5313 zeta[0]+= z_initial;
5319 zeta[0] = std::fabs(zeta[0]);
5323 if (zeta[0] > zeta_max)
5330 #ifdef OOMPH_HAS_MPI 5337 if (this->is_mesh_distributed() &&
5338 Assigned_segments_initial_zeta_values[b])
5341 FiniteElement* first_seg_ele_pt = segment_sorted_ele_pt[is].front();
5346 if (first_seg_ele_pt->
is_halo())
5348 std::ostringstream error_message;
5350 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
5352 <<
"The first face element in the (" << is <<
")-th segment" 5356 OOMPH_EXCEPTION_LOCATION);
5361 const unsigned nnod = first_seg_ele_pt->
nnode();
5364 Node *first_seg_node_pt = first_seg_ele_pt->
node_pt(0);
5365 if (is_inverted[first_seg_ele_pt])
5367 first_seg_node_pt = first_seg_ele_pt->node_pt(nnod-1);
5371 FiniteElement* last_seg_ele_pt = segment_sorted_ele_pt[is].back();
5376 if (last_seg_ele_pt->
is_halo())
5378 std::ostringstream error_message;
5380 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
5382 <<
"The last face element in the (" << is <<
")-th segment" 5386 OOMPH_EXCEPTION_LOCATION);
5391 Node *last_seg_node_pt = last_seg_ele_pt->
node_pt(nnod-1);
5392 if (is_inverted[last_seg_ele_pt])
5394 last_seg_node_pt = last_seg_ele_pt->node_pt(0);
5402 last_seg_node_pt->get_coordinates_on_boundary(b,last_seg_arclen);
5405 boundary_segment_initial_arclength(b)[is] = first_seg_arclen[0];
5406 boundary_segment_final_arclength(b)[is] = last_seg_arclen[0];
5411 for (
unsigned k = 0 ; k < 2; k++)
5413 updated_segment_initial_coord[k] = first_seg_node_pt->
x(k);
5414 updated_segment_final_coord[k] = last_seg_node_pt->x(k);
5418 boundary_segment_initial_coordinate(b)[is] =
5419 updated_segment_initial_coord;
5422 boundary_segment_final_coordinate(b)[is] =
5423 updated_segment_final_coord;
5427 #endif // #ifdef OOMPH_HAS_MPI 5433 if (zeta_max < boundary_arclength)
5435 zeta_max = boundary_arclength;
5440 for (std::set<Node*>::iterator it = all_nodes_pt.begin(); it
5441 != all_nodes_pt.end(); it++)
5444 Node* nod_pt = (*it);
5450 zeta[0] /= zeta_max;
5466 for (
unsigned e = 0;
e < nel;
e++)
5468 delete face_el_pt[
e];
5475 Boundary_coordinate_exists[b] =
true;
5488 namespace TriangleBoundaryHelper
std::map< unsigned, Vector< unsigned > > Boundary_segment_inverted
Stores the info. to know if it is necessary to reverse the segment based on a previous mesh...
Vector< unsigned > polygon_boundary_id()
Return vector of boundary ids of associated polylines.
unsigned & initial_vertex_connected_n_chunk()
Sets the boundary chunk to which the initial end is connected.
unsigned nregion_attribute()
Return the number of attributes used in the mesh.
~UnstructuredTwoDMeshGeometryBase()
Empty destructor.
bool is_redistribution_of_segments_between_polylines_enabled()
Is re-distribution of polyline segments in the curve between different boundaries during adaptation e...
void disable_automatic_creation_of_vertices_on_boundaries()
std::map< unsigned, Vector< double > > & boundary_segment_initial_zeta()
Return direct access to the initial zeta for the segments that are part of a boundary.
void set_geom_objects_and_coordinate_limits_for_close_curve(TriangleMeshClosedCurve *input_closed_curve_pt)
Stores the geometric objects associated to the curve sections that compound the closed curve...
virtual TriangleMeshCurveSection * curve_section_pt(const unsigned &i) const
Pointer to i-th constituent curve section.
void add_boundary_segment_node(const unsigned &b, const unsigned &s, Node *const &node_pt)
std::map< unsigned, Vector< Vector< double > > > & boundary_segment_initial_coordinate()
Return direct access to the initial coordinates for the segments that are part of a boundary...
unsigned nboundary_segment(const unsigned &b)
Return the number of segments associated with a boundary.
std::map< unsigned, Vector< double > > & boundary_final_coordinate()
Return direct access to the final coordinates of a boundary.
unsigned boundary_chunk() const
std::map< unsigned, Vector< FiniteElement *> > Region_element_pt
Vector of elements in each region differentiated by attribute (the key of the map is the attribute) ...
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
TriangleMeshCurviLine(GeomObject *geom_object_pt, const double &zeta_start, const double &zeta_end, const unsigned &nsegment, const unsigned &boundary_id, const bool &space_vertices_evenly_in_arclength=true, const unsigned &boundary_chunk=0)
Constructor: Specify GeomObject, the start and end coordinates of the relevant boundary in terms of t...
void set_geom_objects_and_coordinate_limits_for_open_curve(TriangleMeshOpenCurve *input_open_curve_pt)
Stores the geometric objects associated to the curve sections that compound the open curve...
virtual void set_coordinates_on_boundary(const unsigned &b, const unsigned &k, const Vector< double > &boundary_zeta)
Set the vector of the k-th generalised boundary coordinates on mesh boundary b. Broken virtual interf...
unsigned nsegment() const
Number of (initially straight-line) segments that this part of the boundary is to be represented by...
double * pointlist
Pointer to list of points x coordinate followed by y coordinate.
void set_initial_vertex_connected()
Sets the initial vertex as connected.
unsigned nboundary_element_in_region(const unsigned &b, const unsigned &r) const
Return the number of elements adjacent to boundary b in region r.
double * pointattributelist
Pointer to list of point attributes.
void enable_polyline_unrefinement(const double &tolerance=0.04)
Enable unrefinement of polylines to avoid unnecessarily large numbers of elements on of curvilinear b...
double Zeta_end
End coordinate in terms of the GeomObject's intrinsic coordinate.
void final_vertex_coordinate(Vector< double > &vertex)
Get last vertex coordinates.
void set_polyline_unrefinement_tolerance(const double &tolerance)
Set tolerance for unrefinement of polylines to avoid unnecessarily large numbers of elements on of cu...
std::map< unsigned, std::set< Node * > > Nodes_on_boundary_pt
Stores a pointer to a set with all the nodes related with a boundary.
TriangleMeshPolygon * closed_curve_to_polygon_helper(TriangleMeshClosedCurve *closed_curve_pt, unsigned &max_bnd_id_local)
Helper function that returns a polygon representation for the given closed curve, it also computes th...
bool is_automatic_creation_of_vertices_on_boundaries_allowed()
Vector< TriangleMeshOpenCurve * > Internal_open_curve_pt
Vector of open polylines that define internal curves.
unsigned max_boundary_id()
Return max boundary id of associated curves.
TriangleMeshPolyLine * polyline_pt(const unsigned &i)
Pointer to i-th constituent polyline.
unsigned Initial_vertex_connected_bnd_id
Stores the id to which the initial end is connected.
int * pointmarkerlist
Pointer to list of point markers.
void create_vertex_coordinates_for_polyline_no_connections(TriangleMeshCurviLine *boundary_pt, Vector< Vector< double > > &vertex_coord, Vector< std::pair< double, double > > &polygonal_vertex_arclength_info)
Helper function to create polyline vertex coordinates for curvilinear boundary specified by boundary_...
double Unrefinement_tolerance
bool Final_vertex_connected_suspended
Indicates if the connection is suspended because the boundary to connect is no longer part of the dom...
void write_triangulateio_to_polyfile(TriangulateIO &triangle_io, std::ostream &poly_file)
Write the triangulateio data to disk as a poly file, mainly used for debugging.
TriangleMeshPolyLine * polyline_pt(const unsigned &i) const
Pointer to i-th constituent polyline.
unsigned Initial_vertex_connected_n_chunk
Stores the chunk number of the boundary to which is connected th initial end.
Data structure filled when the connection matrix is created, for each polyline, there are two vertex_...
bool Initial_vertex_connected_suspended
Indicates if the connection is suspended because the boundary to connect is no longer part of the dom...
void output(std::ostream &outfile, const unsigned &n_sample=50)
Output curvilinear boundary at n_sample (default: 50) points.
double final_s_connection_value() const
Gets the s value to which the final end is connected.
double zeta_end()
End coordinate in terms of the GeomObject's intrinsic coordinate.
bool has_base_vertex_assigned
FiniteElement * boundary_element_in_region_pt(const unsigned &b, const unsigned &r, const unsigned &e) const
Return pointer to the e-th element adjacent to boundary b in region r.
unsigned Initial_vertex_connected_n_vertex
Stores the vertex number used for connection with the initial end.
std::map< unsigned, TriangleMeshCurveSection * > Boundary_curve_section_pt
A map that stores the associated curve section of the specified boundary id.
void set_initial_vertex_connected_to_curviline()
Sets the initial vertex as connected to a curviline.
void operator=(const UnstructuredTwoDMeshGeometryBase &)
Broken assignment operator.
unsigned nsegment() const
Number of segments.
void unset_initial_vertex_connected_to_curviline()
Sets the initial vertex as non connected to a curviline.
double Polyline_refinement_tolerance
Tolerance for refinement of polylines (neg if refinement is disabled)
TriangleMeshCurve(const Vector< TriangleMeshCurveSection *> &curve_section_pt)
Empty constructor.
std::map< unsigned, Vector< double > > & boundary_coordinate_limits()
Return access to the vector of boundary coordinates associated with each geometric object...
bool Final_vertex_connected
Used for stating if the final end is connected to another boundary.
TriangleMeshPolyLine * boundary_polyline_pt(const unsigned &b)
Return pointer to the current polyline that describes the b-th mesh boundary.
bool are_there_connection_points()
Does the vector for storing connections has elements?
void disable_polyline_refinement()
Disable refinement of polylines.
virtual TriangleMeshCurveSection *& curve_section_pt(const unsigned &i)
Pointer to i-th constituent curve section.
bool Initial_vertex_connected
Used for stating if the initial end is connected to another boundary.
Vector< double > & boundary_final_zeta_coordinate(const unsigned &b)
Return the final zeta coordinate for the boundary.
unsigned & nsegment()
Number of (initially straight-line) segments that this part of the boundary is to be represented by...
unsigned Final_vertex_connected_n_chunk
Stores the chunk number of the boundary to which is connected th initial end.
A general Finite Element class.
unsigned final_vertex_connected_n_chunk() const
Gets the boundary chunk to which the final end is connected.
unsigned vertex_number_to_connect
virtual void reset_reference_configuration()
Virtual function that should be overloaded to update the polygons reference configuration.
unsigned nvertex() const
Number of vertices.
double zeta_start()
Start coordinate in terms of the GeomObject's intrinsic coordinate.
unsigned Final_vertex_connected_bnd_id
Stores the id to which the initial end is connected.
Vector< double > & boundary_initial_zeta_coordinate(const unsigned &b)
Return the initial zeta coordinate for the boundary.
Vector< TriangleMeshPolygon * > Internal_polygon_pt
Vector of polygons that define internal polygons.
std::map< unsigned, Vector< double > > & boundary_initial_coordinate()
Return direct access to the initial coordinates of a boundary.
unsigned boundary_chunk_to_connect
Vector< Vector< double > > & boundary_segment_final_coordinate(const unsigned &b)
Return the final coordinates for the segments that are part of a boundary.
virtual ~TriangleMeshPolygon()
Empty virtual destructor.
Vector< double > internal_point() const
Coordinates of the internal point.
std::map< unsigned, Vector< double > > Boundary_segment_initial_zeta
Stores the initial zeta coordinate for the segments that appear when a boundary is splited among proc...
double refinement_tolerance()
Get tolerance for refinement of curve sections to create a better representation of curvilinear bound...
void enable_polyline_refinement(const double &tolerance=0.08)
Enable refinement of polylines to create a better representation of curvilinear boundaries (e...
bool is_halo() const
Is this element a halo?
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
TriangleMeshCurveSection()
Empty constructor. Initialises the curve section as non connected.
std::map< unsigned, Vector< unsigned > > & boundary_segment_inverted()
Return the info. to know if it is necessary to reverse the segment based on a previous mesh...
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
void set_final_vertex_connected_to_curviline()
Sets the final vertex as connected to a curviline.
TriangleMeshPolyLine * polyline_pt(const unsigned &i) const
Pointer to i-th constituent polyline.
std::map< unsigned, Vector< double > > & boundary_final_zeta_coordinate()
Return direct access to the final zeta coordinates of a boundary.
unsigned Boundary_id
Boundary ID.
double Zeta_start
Start coordinate in terms of the GeomObject's intrinsic coordinate.
void disable_redistribution_of_segments_between_polylines()
Disable re-distribution of polyline segments in the curve between different boundaries during adaptat...
std::map< unsigned, Vector< Vector< Node * > > > Boundary_segment_node_pt
Used to store the nodes associated to a boundary and to an specific segment (this only applies in dis...
void flush_boundary_segment_node(const unsigned &b)
Flush the boundary segment node storage.
void initial_vertex_coordinate(Vector< double > &vertex)
Get first vertex coordinates.
double Refinement_tolerance
std::set< TriangleMeshCurveSection * > Free_curve_section_pt
A set that contains the curve sections created by this object therefore it is necessary to free their...
unsigned boundary_id() const
Boundary ID.
void set_fixed()
Set the polygon to be fixed.
bool is_initial_vertex_connected() const
Test whether initial vertex is connected or not.
unsigned nsegments() const
Total number of segments.
std::map< unsigned, GeomObject * > Boundary_geom_object_pt
Storage for the geometric objects associated with any boundaries.
std::set< TriangleMeshPolygon * > Free_polygon_pt
A set that contains the polygons created by this object therefore it is necessary to free their assoc...
virtual void get_coordinates_on_boundary(const unsigned &b, const unsigned &k, Vector< double > &boundary_zeta)
Return the vector of the k-th generalised boundary coordinates on mesh boundary b. Broken virtual interface provides run-time error checking.
double region_attribute(const unsigned &i)
Return the attribute associated with region i.
Vector< double > Region_attribute
Vector of attributes associated with the elements in each region.
void resume_initial_vertex_connected()
Vector< double > * connection_points_pt()
Returns the connection points vector.
void disable_unrefinement_tolerance()
Disable unrefinement of curve sections.
unsigned get_associated_vertex_to_svalue(double &target_s_value, unsigned &bnd_id)
Get the associated vertex to the given s value by looking to the list of s values created when changi...
void set_nboundary_segment_node(const unsigned &b, const unsigned &s)
Set the number of segments associated with a boundary.
void set_refinement_tolerance(const double &tolerance)
Set tolerance for refinement of curve sections to create a better representation of curvilinear bound...
Vector< double > Connection_points_pt
Stores the information for connections received on the curviline. Used when converting to polyline...
double maximum_length()
Gets access to the maximum length variable.
double Final_s_connection_value
Stores the s value used for connecting the final end with a curviline.
Vector< std::map< unsigned, Vector< int > > > Face_index_region_at_boundary
Storage for the face index adjacent to a boundary in a particular region.
Data structure to store the base vertex info, initial or final vertex in the polylines have an associ...
double Tolerance_for_s_connection
Tolerance used for connecting the ends to a curviline.
std::map< unsigned, Vector< Vector< double > > > Boundary_segment_final_coordinate
Stores the final coordinates for the segments that appear when a boundary is splited among processors...
void create_triangulateio_from_polyfiles(const std::string &node_file_name, const std::string &element_file_name, const std::string &poly_file_name, TriangulateIO &triangle_io, bool &use_attributes)
Vector< std::map< unsigned, Vector< FiniteElement * > > > Boundary_region_element_pt
Storage for elements adjacent to a boundary in a particular region.
void disable_use_maximum_length()
Disables the use of the maximum length criteria on the unrefinement or refinement steps...
void enable_unrefinement_tolerance(const double &tolerance=0.04)
Enable unrefinement of curve sections to avoid unnecessarily large numbers of elements on of curvilin...
bool space_vertices_evenly_in_arclength() const
Boolean to indicate if vertices in polygonal representation of the Curvline are spaced (approximately...
bool is_final_vertex_connected_to_curviline() const
Test whether the final vertex is connected to a curviline.
void disable_polyline_unrefinement()
Disable unrefinement of polylines.
TriangleMeshOpenCurve * create_open_curve_with_polyline_helper(TriangleMeshOpenCurve *open_curve_pt, unsigned &max_bnd_id_local)
Helper function that creates and returns an open curve with the polyline representation of its consti...
Vector< double > & internal_point()
Coordinates of the internal point.
void output(std::ostream &outfile, const unsigned &n_sample=50)
Output each sub-boundary at n_sample (default: 50) points.
GeomObject * geom_object_pt()
Pointer to GeomObject that represents this part of the boundary.
void unset_initial_vertex_connected()
Sets the initial vertex as non connected.
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Vector< double > Internal_point_pt
Vector of vertex coordinates.
unsigned & initial_vertex_connected_n_vertex()
Sets the vertex number to which the initial end is connected.
unsigned nvertex() const
Number of vertices.
TriangleMeshPolyLine(const Vector< Vector< double > > &vertex_coordinate, const unsigned &boundary_id, const unsigned &boundary_chunk=0)
Constructor: Takes vectors of vertex coordinates in order Also allows the optional specification of a...
void set_polyline_refinement_tolerance(const double &tolerance)
Set tolerance for refinement of polylines to create a better representation of curvilinear boundaries...
Class defining a polyline for use in Triangle Mesh generation.
bool Initial_vertex_connected_to_curviline
States if the initial vertex is connected to a curviline.
std::map< unsigned, Vector< Vector< double > > > & boundary_segment_final_coordinate()
Return direct access to the final coordinates for the segments that are part of a boundary...
void unfix_internal_point()
void enable_automatic_creation_of_vertices_on_boundaries()
unsigned initial_vertex_connected_n_vertex() const
Gets the vertex number to which the initial end is connected.
std::map< unsigned, Vector< double > > Boundary_initial_coordinate
Stores the initial coordinates for the boundary.
unsigned boundary_id() const
Boundary id.
double polyline_refinement_tolerance()
Get tolerance for refinement of polylines to create a better representation of curvilinear boundaries...
FiniteElement * region_element_pt(const unsigned &i, const unsigned &e)
Return the e-th element in the i-th region.
Vector< Vector< double > > Extra_holes_coordinates
Storage for extra coordinates for holes.
void clear_triangulateio(TriangulateIO &triangulate_io, const bool &clear_hole_data)
Clear TriangulateIO structure.
void final_vertex_coordinate(Vector< double > &vertex)
Get last vertex coordinates.
double & final_s_connection_value()
Sets the s value to which the final end is connected.
double * triangleattributelist
std::map< unsigned, GeomObject * > & boundary_geom_object_pt()
Return direct access to the geometric object storage.
std::map< unsigned, Vector< double > > Boundary_segment_initial_arclength
Stores the initial arclength for the segments that appear when a boundary is splited among processors...
unsigned get_associated_vertex_to_svalue(double &target_s_value, unsigned &bnd_id, double &s_tolerance)
Get the associated vertex to the given s value by looking to the list of s values created when changi...
void fix_internal_point()
double Tolerable_error
Acceptable discrepancy for mismatch in vertex coordinates. In paranoid mode, the code will die if the...
void setup_boundary_coordinates(const unsigned &b)
Setup boundary coordinate on boundary b. Boundary coordinate increases continously along polygonal bo...
unsigned boundary_chunk() const
bool is_fixed() const
Test whether the polygon is fixed or not.
std::map< unsigned, Vector< double > > & boundary_initial_zeta_coordinate()
Return direct access to the initial zeta coordinate of a boundary.
bool Allow_automatic_creation_of_vertices_on_boundaries
Flag to indicate whether the automatic creation of vertices along the boundaries by Triangle is allow...
void suspend_final_vertex_connected()
Structure for Boundary Informations.
double & tolerance_for_s_connection()
Sets the tolerance value for connections among curvilines.
unsigned & final_vertex_connected_bnd_id()
Sets the id to which the final end is connected.
std::map< unsigned, Vector< std::pair< double, double > > > Polygonal_vertex_arclength_info
Storage for pairs of doubles representing: .first: the arclength along the polygonal representation o...
void initial_vertex_coordinate(Vector< double > &vertex)
Get first vertex coordinates.
bool is_final_vertex_connected() const
Test whether final vertex is connected or not.
virtual unsigned boundary_id() const =0
Boundary id.
bool Final_vertex_connected_to_curviline
States if the final vertex is connected to a curviline.
unsigned nregion()
Return the number of regions specified by attributes.
void suspend_initial_vertex_connected()
std::map< unsigned, Vector< double > > Boundary_coordinate_limits
std::map< unsigned, Vector< double > > & boundary_segment_final_zeta()
Return direct access to the final zeta for the segments that are part of a boundary.
void set_final_vertex_connected()
Sets the final vertex as connected.
virtual ~TriangleMeshCurviLine()
Empty Destuctor.
UnstructuredTwoDMeshGeometryBase()
Empty constructor.
void output(std::ostream &outfile, const unsigned &n_sample=50)
Output each sub-boundary at n_sample (default: 50) points.
double unrefinement_tolerance()
Get tolerance for unrefinement of curve section to create a better representation of curvilinear boun...
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
std::map< unsigned, Vector< Vector< double > > > Boundary_segment_initial_coordinate
Stores the initial coordinates for the segments that appear when a boundary is splited among processo...
Base class defining a closed curve for the Triangle mesh generation.
void output(std::ostream &outfile, const unsigned &n_sample=50)
Output the polyline – n_sample is ignored.
UnstructuredTwoDMeshGeometryBase(const UnstructuredTwoDMeshGeometryBase &dummy)
Broken copy constructor.
Vector< TriangleMeshCurveSection * > Curve_section_pt
Vector of curve sections.
virtual ~TriangleMeshOpenCurve()
Empty destructor.
bool Is_internal_point_fixed
Indicate whether the internal point should be updated automatically.
void output(std::ostream &outfile)
Output with default number of plot points.
bool Immersed_rigid_body_triangle_mesh_polygon_used
void initialise_triangulateio(TriangulateIO &triangle_io)
Initialise TriangulateIO structure.
double polyline_unrefinement_tolerance()
Get tolerance for unrefinement of polylines to create a better representation of curvilinear boundari...
FiniteElement * FE_pt
Pointer to bulk finite element.
virtual ~TriangleMeshPolyLine()
Empty destructor.
void set_maximum_length(const double &maximum_length)
Allows to specify the maximum distance between two vertices that define the associated polyline of th...
double Initial_s_connection_value
Stores the s value used for connecting the initial end with a curviline.
void set_unrefinement_tolerance(const double &tolerance)
Set tolerance for unrefinement of curve sections to avoid unnecessarily large numbers of elements on ...
double tolerance_for_s_connection() const
Gets the tolerance value for connections among curvilines.
int numberoftriangleattributes
unsigned & final_vertex_connected_n_vertex()
Gets the vertex number to which the final end is connected.
int numberofpointattributes
TriangulateIO deep_copy_of_triangulateio_representation(TriangulateIO &triangle_io, const bool &quiet)
Make (partial) deep copy of TriangulateIO object. We only copy those items we need within oomph-lib's...
void resume_final_vertex_connected()
TriangleMeshCurveSection * curviline_to_polyline(TriangleMeshCurviLine *&curviline_pt, unsigned &bnd_id)
Helper function that creates the associated polyline representation for curvilines.
unsigned long nboundary_segment_node(const unsigned &b, const unsigned &s)
std::map< unsigned, bool > Assigned_segments_initial_zeta_values
Flag used at the setup_boundary_coordinate function to know if initial zeta values for segments have ...
void enable_refinement_tolerance(const double &tolerance=0.08)
Enable refinement of curve section to create a better representation of curvilinear boundaries (e...
Vector< unsigned > & boundary_segment_inverted(const unsigned &b)
Return the info. to know if it is necessary to reverse the segment based on a previous mesh...
Vector< double > & vertex_coordinate(const unsigned &i)
Coordinate vector of i-th vertex.
Vector< double > & boundary_coordinate_limits(const unsigned &b)
Return access to the coordinate limits associated with the geometric object associated with boundary ...
bool Enable_redistribution_of_segments_between_polylines
Is re-distribution of polyline segments between different boundaries during adaptation enabled...
bool Can_update_configuration
Boolean flag to indicate whether the polygon can update its own reference configuration after it has ...
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
Vector< double > & boundary_segment_initial_zeta(const unsigned &b)
Return the initial zeta for the segments that are part of a boundary.
std::map< unsigned, std::set< Node * > > & nodes_on_boundary_pt()
Gets a pointer to a set with all the nodes related with a boundary.
void dump_triangulateio(TriangulateIO &triangle_io, std::ostream &dump_file)
Write all the triangulateio data to disk in a dump file that can then be used to restart simulations...
Vector< Vector< double > > Vertex_coordinate
Vector of Vector of vertex coordinates.
unsigned nsegments() const
Total number of segments.
std::set< TriangleMeshOpenCurve * > Free_open_curve_pt
A set that contains the open curves created by this object therefore it is necessary to free their as...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
unsigned boundary_id_to_connect
Vector< double > & boundary_segment_final_zeta(const unsigned &b)
Return the final zeta for the segments that are part of a boundary.
Vector< double > & boundary_initial_coordinate(const unsigned &b)
Return the initial coordinates for the boundary.
virtual ~TriangleMeshCurve()
Empty destructor.
double * trianglearealist
std::map< unsigned, Vector< double > > Boundary_final_zeta_coordinate
Stores the final zeta coordinate for the boundary.
std::map< unsigned, Vector< double > > Boundary_final_coordinate
Stores the final coordinates for the boundary.
bool is_internal_point_fixed() const
Test whether the internal point is fixed.
Vector< double > vertex_coordinate(const unsigned &i) const
Coordinate vector of i-th vertex (const version)
unsigned & initial_vertex_connected_bnd_id()
Sets the id to which the initial end is connected.
Vector< double > & boundary_final_coordinate(const unsigned &b)
Return the final coordinates for the boundary.
Vector< Vector< double > > & boundary_segment_initial_coordinate(const unsigned &b)
Return the initial coordinates for the segments that are part of a boundary.
void disable_refinement_tolerance()
Disable refinement of curve section.
std::map< unsigned, Vector< double > > Boundary_initial_zeta_coordinate
Stores the initial zeta coordinate for the boundary.
void enable_redistribution_of_segments_between_polylines()
Enable re-distribution of polyline segments in the curve between different boundaries during adaptati...
std::map< unsigned, Vector< double > > Regions_coordinates
double initial_s_connection_value() const
Gets the s value to which the initial end is connected.
std::map< unsigned, Vector< double > > & boundary_segment_initial_arclength()
Return direct access to the initial arclength for the segments that are part of a boundary...
const Vector< unsigned > boundary_segment_inverted(const unsigned &b) const
Return the info. to know if it is necessary to reverse the segment based on a previous mesh...
Vector< double > & boundary_segment_final_arclength(const unsigned &b)
Return the final arclength for the segments that are part of a boundary.
virtual ~TriangleMeshCurveSection()
Empty destructor.
double & initial_s_connection_value()
Sets the s value to which the initial end is connected.
void create_vertex_coordinates_for_polyline_connections(TriangleMeshCurviLine *boundary_pt, Vector< Vector< double > > &vertex_coord, Vector< std::pair< double, double > > &polygonal_vertex_arclength_info)
Helper function to create polyline vertex coordinates for curvilinear boundary specified by boundary_...
unsigned nvertices() const
Number of vertices.
unsigned final_vertex_connected_bnd_id() const
Gets the id to which the final end is connected.
std::map< unsigned, Vector< double > > Boundary_segment_final_zeta
Stores the final zeta coordinate for the segments that appear when a boundary is splited among proces...
int face_index_at_boundary_in_region(const unsigned &b, const unsigned &r, const unsigned &e) const
Return face index of the e-th element adjacent to boundary b in region r.
unsigned initial_vertex_connected_n_chunk() const
Gets the boundary chunk to which the initial end is connected.
void read_triangulateio(std::istream &restart_file, TriangulateIO &triangle_io)
Read the triangulateio data from a dump file on disk, which can then be used to restart simulations...
void unset_final_vertex_connected_to_curviline()
Sets the final vertex as non connected to a curviline.
unsigned long nboundary_segment_node(const unsigned &b)
Return the number of segments associated with a boundary.
static bool Suppress_warning_about_regions_and_boundaries
Public static flag to suppress warning; defaults to false.
unsigned nvertices() const
Number of vertices.
unsigned nregion_element(const unsigned &i)
Return the number of elements in the i-th region.
unsigned & final_vertex_connected_n_chunk()
Sets the boundary chunk to which the final end is connected.
unsigned Final_vertex_connected_n_vertex
Stores the vertex number used for connection with the final end.
virtual ~TriangleMeshClosedCurve()
Empty destructor.
unsigned Boundary_id
Boundary ID.
unsigned nnode() const
Return the number of nodes.
unsigned ncurve_section() const
Number of constituent curves.
unsigned final_vertex_connected_n_vertex() const
Sets the vertex number to which the final end is connected.
bool Polygon_fixed
Boolean flag to indicate whether the polygon can move (default false because if it doesn't move this ...
GeomObject * boundary_geom_object_pt(const unsigned &b)
Return the geometric object associated with the b-th boundary or null if the boundary has associated ...
Vector< double > & boundary_segment_initial_arclength(const unsigned &b)
Return the initial arclength for the segments that are part of a boundary.
void add_connection_point(const double &z_value, const double &tol=1.0e-12)
unsigned Boundary
Boundary ID.
bool is_initial_vertex_connected_to_curviline() const
Test whether the initial vertex is connected to a curviline.
std::map< unsigned, Vector< double > > & boundary_segment_final_arclength()
Return direct access to the final arclength for the segments that are part of a boundary.
Vector< TriangleMeshPolygon * > Outer_boundary_pt
Polygon that defines outer boundaries.
std::map< unsigned, Vector< double > > Boundary_segment_final_arclength
Stores the final arclength for the segments that appear when a boundary is splited among processors...
bool can_update_reference_configuration() const
Test whether curve can update reference.
bool Space_vertices_evenly_in_arclength
Boolean to indicate if vertices in polygonal representation of the Curviline are spaced (approximatel...
virtual unsigned ncurve_section() const
Number of constituent curves.
TriangleMeshPolyLine * polyline_pt(const unsigned &i)
Pointer to i-th constituent polyline.
unsigned initial_vertex_connected_bnd_id() const
Gets the id to which the initial end is connected.
unsigned npolyline() const
Number of constituent polylines.
void set_unfixed()
Set the polygon to be allowed to move (default)
double Polyline_unrefinement_tolerance
Tolerance for unrefinement of polylines (neg if refinement is disabled)
void unset_final_vertex_connected()
Sets the final vertex as non connected.
GeomObject * Geom_object_pt
Pointer to GeomObject that represents this part of the boundary.
Class defining a closed polygon for the Triangle mesh generation.