35 #ifndef OOMPH_UNSTRUCTURED_TWO_D_MESH_GEOMETRY_BASE_HEADER
36 #define OOMPH_UNSTRUCTURED_TWO_D_MESH_GEOMETRY_BASE_HEADER
48 #ifdef OOMPH_HAS_TRIANGLE_LIB
102 namespace TriangleHelper
106 const bool& clear_hole_data =
true);
121 std::ostream& poly_file);
132 bool& use_attributes);
137 std::ostream& dump_file);
154 class TriangleMeshPolyLine;
155 class TriangleMeshCurviLine;
199 virtual void output(std::ostream& outfile,
200 const unsigned& n_sample = 50) = 0;
315 const unsigned& vertex_number,
316 const double& tolerance_for_connection = 1.0e-14);
325 const unsigned& vertex_number,
326 const double& tolerance_for_connection = 1.0e-14);
336 const double& s_value,
337 const double& tolerance_for_connection = 1.0e-14);
347 const double& s_value,
348 const double& tolerance_for_connection = 1.0e-14);
742 void output(std::ostream& outfile,
const unsigned& n_sample = 50)
744 outfile <<
"ZONE T=\"Boundary " <<
Boundary_id <<
"\"\n";
747 for (
unsigned i = 0;
i < n_sample;
i++)
752 outfile << r[0] <<
" " << r[1] << std::endl;
801 const double& tol = 1.0e-12)
808 std::fabs(z_value -
Zeta_end) < tol)
818 for (
unsigned i = 0;
i < n_size;
i++)
883 for (
unsigned i = 0;
i < nvert;
i++)
887 std::ostringstream error_stream;
888 error_stream <<
"TriangleMeshPolyLine should only be used in 2D!\n"
889 <<
"Your Vector of coordinates, contains data for "
891 <<
"-dimensional coordinates." << std::endl;
893 OOMPH_CURRENT_FUNCTION,
894 OOMPH_EXCEPTION_LOCATION);
953 void output(std::ostream& outfile,
const unsigned& n_sample = 50)
955 outfile <<
"ZONE T=\"TriangleMeshPolyLine with boundary ID" <<
Boundary_id
956 <<
"\"" << std::endl;
958 for (
unsigned i = 0;
i < nvert;
i++)
979 if (initial_connection || final_connection)
986 const unsigned backup_initial_vertex_connected_bnd_id =
989 const unsigned backup_initial_vertex_connected_chunk =
992 const unsigned backup_initial_vertex_connected_n_vertex =
995 const bool backup_initial_vertex_connected_to_curviline =
1005 const unsigned backup_final_vertex_connected_bnd_id =
1008 const unsigned backup_final_vertex_connected_chunk =
1011 const unsigned backup_final_vertex_connected_n_vertex =
1014 const bool backup_final_vertex_connected_to_curviline =
1033 if (initial_connection)
1039 backup_initial_vertex_connected_bnd_id;
1042 backup_initial_vertex_connected_chunk;
1045 backup_initial_vertex_connected_n_vertex;
1047 if (backup_initial_vertex_connected_to_curviline)
1059 if (final_connection)
1065 backup_final_vertex_connected_bnd_id;
1068 backup_final_vertex_connected_chunk;
1071 backup_final_vertex_connected_n_vertex;
1073 if (backup_final_vertex_connected_to_curviline)
1114 namespace ToleranceForVertexMismatchInPolygons
1160 for (
unsigned i = 0;
i < n_curve_section;
i++)
1163 if (boundary_id > max)
1189 for (
unsigned i = 0;
i < n_curve_sections;
i++)
1209 for (
unsigned i = 0;
i < n_curve_sections;
i++)
1232 for (
unsigned i = 0;
i < n_curve_sections;
i++)
1251 for (
unsigned i = 0;
i < n_curve_sections;
i++)
1274 for (
unsigned i = 0;
i < n_curve_sections;
i++)
1297 for (
unsigned i = 0;
i < n_curve_sections;
i++)
1305 const unsigned& n_sample = 50) = 0;
1354 unsigned n_vertices = 0;
1355 for (
unsigned j = 0; j < n_curve_section; j++)
1361 if (n_curve_section == 1)
1373 for (
unsigned j = 0; j < n_curve_section; j++)
1379 if (n_curve_section == 1)
1387 void output(std::ostream& outfile,
const unsigned& n_sample = 50)
1390 for (
unsigned i = 0;
i < nb;
i++)
1397 outfile <<
"ZONE T=\"Internal point\"\n";
1493 if (tmp_polyline == NULL)
1495 std::ostringstream error_stream;
1497 <<
"The (" <<
i <<
") TriangleMeshCurveSection is not a "
1498 <<
"TriangleMeshPolyLine\nThe TriangleMeshPolygon object"
1499 <<
"is constituent of only TriangleMeshPolyLine objects.\n"
1500 <<
"The problem could be generated when changing the constituent "
1501 <<
"objects of the TriangleMeshPolygon.\nCheck where you got "
1502 <<
"access to this objects and review that you are not introducing "
1503 <<
"any other objects than TriangleMeshPolyLines" << std::endl;
1505 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1508 return tmp_polyline;
1517 if (tmp_polyline == NULL)
1519 std::ostringstream error_stream;
1521 <<
"The (" <<
i <<
") TriangleMeshCurveSection is not a "
1522 <<
"TriangleMeshPolyLine\nThe TriangleMeshPolygon object"
1523 <<
"is constituent of only TriangleMeshPolyLine objects.\n"
1524 <<
"The problem could be generated when changing the constituent "
1525 <<
"objects of the TriangleMeshPolygon.\nCheck where you got "
1526 <<
"access to this objects and review that you are not introducing "
1527 <<
"any other objects than TriangleMeshPolyLines" << std::endl;
1529 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1532 return tmp_polyline;
1543 for (
unsigned iline = 0; iline < nline; iline++)
1581 std::ostringstream error_stream;
1583 <<
"Broken Default Called\n"
1584 <<
"This function should be overloaded if Can_update_configuration = "
1586 <<
"\nwhich indicates that the curve in it polylines parts can update "
1588 <<
"own position (i.e. it\n"
1589 <<
"may be a rigid body. Otherwise the update will be via a FaceMesh \n"
1590 <<
"representation of the boundary which is appropriate for \n"
1591 <<
"general deforming surfaces\n";
1594 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1654 unsigned n_vertices = 0;
1656 for (
unsigned i = 0;
i < n_curve_section;
i++)
1659 if (n_curve_section == 1)
1671 for (
unsigned j = 0; j < n_curve_section; j++)
1679 void output(std::ostream& outfile,
const unsigned& n_sample = 50)
1682 for (
unsigned i = 0;
i < nb;
i++)
1694 if (tmp_polyline == NULL)
1696 std::ostringstream error_stream;
1697 error_stream <<
"The (" <<
i
1698 <<
")-th TriangleMeshCurveSection is not a "
1699 <<
"TriangleMeshPolyLine.\nPlease make sure that when you"
1700 <<
"first created this object the (" <<
i <<
")-th\n"
1701 <<
"TriangleCurveSection is a TriangleMeshPolyLine."
1704 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1707 return tmp_polyline;
1716 if (tmp_polyline == NULL)
1718 std::ostringstream error_stream;
1719 error_stream <<
"The (" <<
i
1720 <<
")-th TriangleMeshCurveSection is not a "
1721 <<
"TriangleMeshPolyLine.\nPlease make sure that when you"
1722 <<
"first created this object the (" <<
i <<
")-th\n"
1723 <<
"TriangleCurveSection is a TriangleMeshPolyLine."
1726 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1729 return tmp_polyline;
1766 std::map<unsigned, Vector<FiniteElement*>>::iterator it;
1774 return (it->second).size();
1786 std::map<unsigned, Vector<FiniteElement*>>::iterator it;
1795 return (it->second)[
e];
1800 std::stringstream error_message;
1803 error_message <<
"There are no regions associated with "
1804 <<
"region ID " <<
i <<
".";
1808 OOMPH_CURRENT_FUNCTION,
1809 OOMPH_EXCEPTION_LOCATION);
1829 std::map<unsigned, GeomObject*>::iterator it;
1837 return (*it).second;
1858 std::map<unsigned, Vector<double>>::iterator it;
1863 "No coordinate limits associated with this boundary\n",
1864 OOMPH_CURRENT_FUNCTION,
1865 OOMPH_EXCEPTION_LOCATION);
1869 return (*it).second;
1875 const unsigned& r)
const
1879 std::map<unsigned, Vector<FiniteElement*>>::const_iterator it =
1883 return (it->second).size();
1895 const unsigned&
e)
const
1898 std::map<unsigned, Vector<FiniteElement*>>::const_iterator it =
1902 return (it->second)[
e];
1913 const unsigned&
e)
const
1916 std::map<unsigned, Vector<int>>::const_iterator it =
1920 return (it->second)[
e];
1924 std::ostringstream error_message;
1925 error_message <<
"Face indices not set up for boundary " << b
1926 <<
" in region " << r <<
"\n";
1927 error_message <<
"This probably means that the boundary is not "
1928 "adjacent to region\n";
1930 OOMPH_CURRENT_FUNCTION,
1931 OOMPH_EXCEPTION_LOCATION);
1939 std::map<unsigned, TriangleMeshCurveSection*>::iterator it =
1963 unsigned& vertex_number);
1976 unsigned& index_halo_start,
1977 unsigned& index_halo_end);
2005 #ifdef OOMPH_HAS_MPI
2028 unsigned ntotal_nodes = 0;
2030 for (
unsigned is = 0; is < nsegments; is++)
2034 return ntotal_nodes;
2052 bool node_already_on_this_boundary_segment =
false;
2055 for (
unsigned n = 0; n < nbound_seg_node; n++)
2060 node_already_on_this_boundary_segment =
true;
2065 if (!node_already_on_this_boundary_segment)
2154 std::map<unsigned, Vector<double>>::iterator it =
2161 std::stringstream error_message;
2162 error_message <<
"The boundary (" << b
2163 <<
") has no segments associated with it!!\n\n";
2165 OOMPH_CURRENT_FUNCTION,
2166 OOMPH_EXCEPTION_LOCATION);
2171 return (*it).second;
2178 std::map<unsigned, Vector<double>>::iterator it =
2185 std::stringstream error_message;
2186 error_message <<
"The boundary (" << b
2187 <<
") has no segments associated with it!!\n\n";
2189 OOMPH_CURRENT_FUNCTION,
2190 OOMPH_EXCEPTION_LOCATION);
2195 return (*it).second;
2201 std::map<unsigned, Vector<double>>::iterator it =
2208 std::stringstream error_message;
2209 error_message <<
"The boundary (" << b
2210 <<
") has not established initial coordinates\n";
2212 OOMPH_CURRENT_FUNCTION,
2213 OOMPH_EXCEPTION_LOCATION);
2217 return (*it).second;
2223 std::map<unsigned, Vector<double>>::iterator it =
2230 std::stringstream error_message;
2231 error_message <<
"The boundary (" << b
2232 <<
") has not established final coordinates\n";
2234 OOMPH_CURRENT_FUNCTION,
2235 OOMPH_EXCEPTION_LOCATION);
2240 return (*it).second;
2247 std::map<unsigned, Vector<unsigned>>::const_iterator it =
2254 std::stringstream error_message;
2255 error_message <<
"The boundary (" << b
2256 <<
") has not established inv. segments info\n";
2258 OOMPH_CURRENT_FUNCTION,
2259 OOMPH_EXCEPTION_LOCATION);
2264 return (*it).second;
2271 std::map<unsigned, Vector<unsigned>>::iterator it =
2278 std::stringstream error_message;
2279 error_message <<
"The boundary (" << b
2280 <<
") has not established inv. segments info\n";
2282 OOMPH_CURRENT_FUNCTION,
2283 OOMPH_EXCEPTION_LOCATION);
2288 return (*it).second;
2294 std::map<unsigned, Vector<double>>::iterator it =
2301 std::stringstream error_message;
2302 error_message <<
"The boundary (" << b
2303 <<
") has not established initial zeta "
2306 OOMPH_CURRENT_FUNCTION,
2307 OOMPH_EXCEPTION_LOCATION);
2312 return (*it).second;
2318 std::map<unsigned, Vector<double>>::iterator it =
2325 std::stringstream error_message;
2326 error_message <<
"The boundary (" << b
2327 <<
") has not established final zeta coordinate\n";
2329 OOMPH_CURRENT_FUNCTION,
2330 OOMPH_EXCEPTION_LOCATION);
2335 return (*it).second;
2342 std::map<unsigned, Vector<double>>::iterator it =
2349 std::stringstream error_message;
2350 error_message <<
"The boundary (" << b
2351 <<
") has no segments associated with it!!\n\n";
2353 OOMPH_CURRENT_FUNCTION,
2354 OOMPH_EXCEPTION_LOCATION);
2359 return (*it).second;
2366 std::map<unsigned, Vector<double>>::iterator it =
2373 std::stringstream error_message;
2374 error_message <<
"The boundary (" << b
2375 <<
") has no segments associated with it!!\n\n";
2377 OOMPH_CURRENT_FUNCTION,
2378 OOMPH_EXCEPTION_LOCATION);
2383 return (*it).second;
2391 std::map<unsigned, Vector<Vector<double>>>::iterator it =
2398 std::stringstream error_message;
2399 error_message <<
"The boundary (" << b
2400 <<
") has no segments associated with it!!\n\n";
2402 OOMPH_CURRENT_FUNCTION,
2403 OOMPH_EXCEPTION_LOCATION);
2408 return (*it).second;
2415 std::map<unsigned, Vector<Vector<double>>>::iterator it =
2422 std::stringstream error_message;
2423 error_message <<
"The boundary (" << b
2424 <<
") has no segments associated with it!!\n\n";
2426 OOMPH_CURRENT_FUNCTION,
2427 OOMPH_EXCEPTION_LOCATION);
2432 return (*it).second;
2441 template<
class ELEMENT>
2445 std::ofstream some_file;
2446 setup_boundary_coordinates<ELEMENT>(b, some_file);
2454 template<
class ELEMENT>
2459 #ifdef OOMPH_HAS_TRIANGLE_LIB
2470 std::map<unsigned, double>& regions_areas,
2517 std::map<
unsigned, std::map<unsigned, unsigned>>&
2518 boundary_chunk_nvertices);
2522 #ifdef OOMPH_HAS_MPI
2563 std::map<unsigned, Vector<Vector<double>>>
2568 std::map<unsigned, Vector<Vector<double>>>
2629 std::map<unsigned, Vector<std::pair<double, double>>>
2670 #ifdef OOMPH_HAS_TRIANGLE_LIB
2684 Vector<std::pair<double, double>>& polygonal_vertex_arclength_info)
2693 double zeta_initial = boundary_pt->
zeta_start();
2696 unsigned n_seg = boundary_pt->
nsegment();
2697 vertex_coord.resize(n_seg + 1);
2698 polygonal_vertex_arclength_info.resize(n_seg + 1);
2699 polygonal_vertex_arclength_info[0].first = 0.0;
2700 polygonal_vertex_arclength_info[0].second = zeta_initial;
2707 double zeta_increment =
2712 for (
unsigned s = 0;
s < n_seg + 1;
s++)
2715 zeta[0] = zeta_initial + zeta_increment * double(
s);
2717 vertex_coord[
s] = posn;
2722 polygonal_vertex_arclength_info[
s].first =
2723 polygonal_vertex_arclength_info[
s - 1].first +
2724 sqrt(pow(vertex_coord[
s][0] - vertex_coord[
s - 1][0], 2) +
2725 pow(vertex_coord[
s][1] - vertex_coord[
s - 1][1], 2));
2726 polygonal_vertex_arclength_info[
s].second = zeta[0];
2735 unsigned nsample_per_segment = 100;
2736 unsigned nsample = nsample_per_segment * n_seg;
2739 double zeta_increment =
2745 zeta[0] = zeta_initial;
2753 double total_arclength = 0.0;
2754 for (
unsigned i = 1;
i < nsample;
i++)
2757 zeta[0] += zeta_increment;
2763 total_arclength += sqrt(pow(end_point[0] - start_point[0], 2) +
2764 pow(end_point[1] - start_point[1], 2));
2767 start_point = end_point;
2771 double target_s_increment = total_arclength / (double(n_seg));
2774 zeta[0] = zeta_initial;
2778 vertex_coord[0] = start_point;
2784 for (
unsigned s = 1;
s < n_seg;
s++)
2788 double arclength_increment = 0.0;
2789 for (
unsigned i = i_lo;
i < nsample;
i++)
2792 zeta[0] += zeta_increment;
2798 arclength_increment += sqrt(pow(end_point[0] - start_point[0], 2) +
2799 pow(end_point[1] - start_point[1], 2));
2802 start_point = end_point;
2805 if (arclength_increment > target_s_increment)
2816 vertex_coord[
s] = end_point;
2821 polygonal_vertex_arclength_info[
s].first =
2822 polygonal_vertex_arclength_info[
s - 1].first +
2823 sqrt(pow(vertex_coord[
s][0] - vertex_coord[
s - 1][0], 2) +
2824 pow(vertex_coord[
s][1] - vertex_coord[
s - 1][1], 2));
2825 polygonal_vertex_arclength_info[
s].second = zeta[0];
2833 vertex_coord[
s] = end_point;
2834 polygonal_vertex_arclength_info[
s].first =
2835 polygonal_vertex_arclength_info[
s - 1].first +
2836 sqrt(pow(vertex_coord[
s][0] - vertex_coord[
s - 1][0], 2) +
2837 pow(vertex_coord[
s][1] - vertex_coord[
s - 1][1], 2));
2838 polygonal_vertex_arclength_info[
s].second = zeta[0];
2854 Vector<std::pair<double, double>>& polygonal_vertex_arclength_info)
2857 double zeta_initial = boundary_pt->
zeta_start();
2859 double zeta_final = boundary_pt->
zeta_end();
2864 unsigned n_connections = connection_points_pt->size();
2867 if (n_connections > 1)
2869 std::sort(connection_points_pt->begin(), connection_points_pt->end());
2874 bool out_of_range_connection_points =
false;
2875 std::ostringstream error_message;
2877 bool reversed =
false;
2878 if (zeta_final < zeta_initial)
2884 if (zeta_initial > (*connection_points_pt)[0])
2887 <<
"One of the specified connection points is out of the\n"
2888 <<
"curviline limits. We found that the point ("
2889 << (*connection_points_pt)[0] <<
") is\n"
2891 <<
"initial s value which is (" << zeta_initial <<
").\n"
2892 <<
"Initial value: (" << zeta_initial <<
")\n"
2893 <<
"Final value: (" << zeta_final <<
")\n"
2895 out_of_range_connection_points =
true;
2898 if (zeta_final < (*connection_points_pt)[n_connections - 1])
2901 <<
"One of the specified connection points is out of the\n"
2902 <<
"curviline limits. We found that the point ("
2903 << (*connection_points_pt)[n_connections - 1] <<
") is\n"
2904 <<
"greater than the final s value which is (" << zeta_final
2906 <<
"Initial value: (" << zeta_initial <<
")\n"
2907 <<
"Final value: (" << zeta_final <<
")\n"
2909 out_of_range_connection_points =
true;
2914 if (zeta_initial < (*connection_points_pt)[0])
2917 <<
"One of the specified connection points is out of the\n"
2918 <<
"curviline limits. We found that the point ("
2919 << (*connection_points_pt)[0] <<
") is\n"
2920 <<
"greater than the"
2921 <<
"initial s value which is (" << zeta_initial <<
").\n"
2922 <<
"Initial value: (" << zeta_initial <<
")\n"
2923 <<
"Final value: (" << zeta_final <<
")\n"
2925 out_of_range_connection_points =
true;
2928 if (zeta_final > (*connection_points_pt)[n_connections - 1])
2931 <<
"One of the specified connection points is out of the\n"
2932 <<
"curviline limits. We found that the point ("
2933 << (*connection_points_pt)[n_connections - 1] <<
") is\n"
2934 <<
"less than the final s value which is (" << zeta_final <<
").\n"
2935 <<
"Initial value: (" << zeta_initial <<
")\n"
2936 <<
"Final value: (" << zeta_final <<
")\n"
2938 out_of_range_connection_points =
true;
2942 if (out_of_range_connection_points)
2945 OOMPH_CURRENT_FUNCTION,
2946 OOMPH_EXCEPTION_LOCATION);
2958 unsigned n_seg = boundary_pt->
nsegment();
2961 unsigned i_connection = 0;
2968 if (n_connections >= n_seg - 1)
2970 std::ostringstream warning_message;
2971 std::string output_string =
"UnstructuredTwoDMeshGeometryBase::";
2972 output_string +=
"create_vertex_coordinates_for_polyline_connections()";
2975 <<
"The number of segments specified for the curviline with\n"
2976 <<
"boundary id (" << boundary_pt->
boundary_id() <<
") is less "
2977 <<
"(or equal) than the ones that will be\ngenerated by using "
2978 <<
"the specified number of connection points.\n"
2979 <<
"You specified (" << n_seg <<
") segments but ("
2980 << n_connections + 1 <<
") segments\nwill be generated." << std::endl;
2982 warning_message.str(), output_string, OOMPH_EXCEPTION_LOCATION);
2985 boundary_pt->
nsegment() = n_connections + 1;
2987 vertex_coord.resize(n_seg + 1);
2990 zeta[0] = zeta_initial;
2992 vertex_coord[0] = posn;
2994 polygonal_vertex_arclength_info.resize(n_seg + 1);
2995 polygonal_vertex_arclength_info[0].first = 0.0;
2996 polygonal_vertex_arclength_info[0].second = zeta_initial;
2999 for (i_connection = 0; i_connection < n_connections; i_connection++)
3002 zeta[0] = (*connection_points_pt)[i_connection];
3004 vertex_coord[i_connection + 1] = posn;
3007 polygonal_vertex_arclength_info[i_connection + 1].first =
3008 polygonal_vertex_arclength_info[i_connection].first +
3009 sqrt(pow(vertex_coord[i_connection + 1][0] -
3010 vertex_coord[i_connection][0],
3012 pow(vertex_coord[i_connection + 1][1] -
3013 vertex_coord[i_connection][1],
3015 polygonal_vertex_arclength_info[i_connection + 1].second = zeta[0];
3019 zeta[0] = zeta_final;
3021 vertex_coord[n_seg] = posn;
3023 polygonal_vertex_arclength_info[n_seg].first =
3024 polygonal_vertex_arclength_info[n_seg - 1].first +
3025 sqrt(pow(vertex_coord[n_seg][0] - vertex_coord[n_seg - 1][0], 2) +
3026 pow(vertex_coord[n_seg][1] - vertex_coord[n_seg - 1][1], 2));
3027 polygonal_vertex_arclength_info[n_seg].second = zeta_final;
3032 unsigned n_t_vertices = n_seg + 1;
3035 unsigned l_vertices = n_t_vertices;
3038 unsigned n_assigned_vertices = 0;
3044 std::list<double> zeta_values_pt;
3045 zeta_values_pt.push_back(zeta_initial);
3046 for (
unsigned s = 0;
s < n_connections;
s++)
3048 zeta_values_pt.push_back((*connection_points_pt)[
s]);
3050 zeta_values_pt.push_back(zeta_final);
3053 l_vertices -= n_connections;
3054 n_assigned_vertices += 2;
3055 n_assigned_vertices += n_connections;
3060 double local_zeta_initial;
3061 double local_zeta_final;
3062 double local_zeta_increment;
3063 double local_zeta_insert;
3066 unsigned local_n_vertices;
3068 std::list<double>::iterator l_it = zeta_values_pt.begin();
3069 std::list<double>::iterator r_it = zeta_values_pt.begin();
3072 for (
unsigned h = 0; r_it != zeta_values_pt.end();
3073 l_it++, r_it++, h++)
3075 delta_z[h] = *r_it - *l_it;
3078 l_it = r_it = zeta_values_pt.begin();
3081 for (
unsigned h = 0; r_it != zeta_values_pt.end(); h++)
3084 static_cast<unsigned>(((double)n_t_vertices * delta_z[h]) /
3085 std::fabs(zeta_final - zeta_initial));
3087 local_zeta_initial = *l_it;
3088 local_zeta_final = *r_it;
3089 local_zeta_increment = (local_zeta_final - local_zeta_initial) /
3090 (
double)(local_n_vertices + 1);
3092 for (
unsigned s = 0;
s < local_n_vertices;
s++)
3095 local_zeta_initial + local_zeta_increment * double(
s + 1);
3096 zeta_values_pt.insert(r_it, local_zeta_insert);
3097 n_assigned_vertices++;
3108 unsigned s = zeta_values_pt.size();
3110 if (
s != n_assigned_vertices)
3113 <<
"The total number of assigned vertices is different from\n"
3114 <<
"the number of elements in the z_values list. The number"
3115 <<
"of\nelements in the z_values list is (" <<
s <<
") but "
3117 <<
"of assigned vertices is (" << n_assigned_vertices <<
")."
3121 OOMPH_CURRENT_FUNCTION,
3122 OOMPH_EXCEPTION_LOCATION);
3126 vertex_coord.resize(n_assigned_vertices);
3127 polygonal_vertex_arclength_info.resize(n_assigned_vertices);
3128 polygonal_vertex_arclength_info[0].first = 0.0;
3129 polygonal_vertex_arclength_info[0].second = zeta_initial;
3132 l_it = zeta_values_pt.begin();
3133 for (
unsigned s = 0; l_it != zeta_values_pt.end();
s++, l_it++)
3138 vertex_coord[
s] = posn;
3143 polygonal_vertex_arclength_info[
s].first =
3144 polygonal_vertex_arclength_info[
s - 1].first +
3145 sqrt(pow(vertex_coord[
s][0] - vertex_coord[
s - 1][0], 2) +
3146 pow(vertex_coord[
s][1] - vertex_coord[
s - 1][1], 2));
3156 unsigned nsample_per_segment = 100;
3157 unsigned nsample = nsample_per_segment * n_seg;
3160 double zeta_increment =
3161 (zeta_final - zeta_initial) / (
double(nsample));
3165 zeta[0] = zeta_initial;
3172 double total_arclength = 0.0;
3173 for (
unsigned i = 1;
i < nsample;
i++)
3176 zeta[0] += zeta_increment;
3182 total_arclength += sqrt(pow(end_point[0] - start_point[0], 2) +
3183 pow(end_point[1] - start_point[1], 2));
3186 start_point = end_point;
3189 double local_zeta_initial;
3190 double local_zeta_final;
3191 double local_zeta_increment;
3194 unsigned local_n_vertices;
3196 std::list<double>::iterator l_it = zeta_values_pt.begin();
3197 std::list<double>::iterator r_it = zeta_values_pt.begin();
3200 for (
unsigned h = 0; r_it != zeta_values_pt.end(); h++)
3204 local_zeta_initial = *l_it;
3205 local_zeta_final = *r_it;
3206 local_zeta_increment =
3207 (local_zeta_final - local_zeta_initial) / (
double)(nsample);
3211 zeta[0] = local_zeta_initial;
3216 for (
unsigned i = 1;
i < nsample;
i++)
3219 zeta[0] += local_zeta_increment;
3225 delta_z[h] += sqrt(pow(end_point[0] - start_point[0], 2) +
3226 pow(end_point[1] - start_point[1], 2));
3229 start_point = end_point;
3232 local_n_vertices =
static_cast<unsigned>(
3233 ((double)n_t_vertices * delta_z[h]) / (total_arclength));
3236 double local_target_s_increment =
3237 delta_z[h] / double(local_n_vertices + 1);
3240 zeta[0] = local_zeta_initial;
3247 for (
unsigned s = 0;
s < local_n_vertices;
s++)
3251 double local_arclength_increment = 0.0;
3252 for (
unsigned i = i_lo;
i < nsample;
i++)
3256 zeta[0] += local_zeta_increment;
3262 local_arclength_increment +=
3263 sqrt(pow(end_point[0] - start_point[0], 2) +
3264 pow(end_point[1] - start_point[1], 2));
3267 start_point = end_point;
3270 if (local_arclength_increment > local_target_s_increment)
3280 zeta_values_pt.insert(r_it, zeta[0]);
3281 n_assigned_vertices++;
3292 unsigned h = zeta_values_pt.size();
3294 if (h != n_assigned_vertices)
3297 <<
"The total number of assigned vertices is different from\n"
3298 <<
"the number of elements in the z_values list. The number of\n"
3299 <<
"elements in the z_values list is (" << h
3300 <<
") but the number\n"
3301 <<
"of assigned vertices is (" << n_assigned_vertices <<
")."
3305 OOMPH_CURRENT_FUNCTION,
3306 OOMPH_EXCEPTION_LOCATION);
3310 vertex_coord.resize(n_assigned_vertices);
3311 polygonal_vertex_arclength_info.resize(n_assigned_vertices);
3312 polygonal_vertex_arclength_info[0].first = 0.0;
3313 polygonal_vertex_arclength_info[0].second = zeta_initial;
3316 l_it = zeta_values_pt.begin();
3317 for (
unsigned s = 0; l_it != zeta_values_pt.end();
s++, l_it++)
3322 vertex_coord[
s] = posn;
3327 polygonal_vertex_arclength_info[
s].first =
3328 polygonal_vertex_arclength_info[
s - 1].first +
3329 sqrt(pow(vertex_coord[
s][0] - vertex_coord[
s - 1][0], 2) +
3330 pow(vertex_coord[
s][1] - vertex_coord[
s - 1][1], 2));
3331 polygonal_vertex_arclength_info[
s].second = zeta[0];
3354 std::ostringstream error_message;
3355 error_message <<
"TriangleMeshClosedCurve that defines outer boundary\n"
3356 <<
"must be made up of at least two "
3357 <<
"TriangleMeshCurveSections\n"
3358 <<
"to allow the automatic set up boundary coordinates.\n"
3359 <<
"Yours only has (" << nb <<
")" << std::endl;
3361 OOMPH_CURRENT_FUNCTION,
3362 OOMPH_EXCEPTION_LOCATION);
3379 for (
unsigned b = 0; b < nb; b++)
3390 if (curviline_pt != 0)
3396 my_boundary_polyline_pt[b] =
3415 if (bnd_id > max_bnd_id_local)
3417 max_bnd_id_local = bnd_id;
3420 else if (polyline_pt != 0)
3426 my_boundary_polyline_pt[b] = polyline_pt;
3441 if (bnd_id > max_bnd_id_local)
3443 max_bnd_id_local = bnd_id;
3448 std::ostringstream error_stream;
3449 error_stream <<
"The 'curve_segment' is not a curviline neither a\n "
3450 <<
"polyline: What is it?\n"
3453 OOMPH_CURRENT_FUNCTION,
3454 OOMPH_EXCEPTION_LOCATION);
3476 for (
unsigned b = 0; b < nb; b++)
3479 my_boundary_polyline_pt[b]->set_unrefinement_tolerance(
3480 unrefinement_tolerance[b]);
3482 my_boundary_polyline_pt[b]->set_refinement_tolerance(
3483 refinement_tolerance[b]);
3486 my_boundary_polyline_pt[b]->set_maximum_length(max_length[b]);
3488 return output_polygon_pt;
3513 for (
unsigned i = 0;
i < nb;
i++)
3523 if (curviline_pt != 0)
3529 my_boundary_polyline_pt[
i] =
3551 if (bnd_id > max_bnd_id_local)
3553 max_bnd_id_local = bnd_id;
3556 else if (polyline_pt != 0)
3562 my_boundary_polyline_pt[
i] = polyline_pt;
3580 if (bnd_id > max_bnd_id_local)
3582 max_bnd_id_local = bnd_id;
3587 std::ostringstream error_stream;
3589 <<
"The 'curve_segment' (open) is not a curviline neither a\n "
3590 <<
"polyline: What is it?\n"
3593 OOMPH_CURRENT_FUNCTION,
3594 OOMPH_EXCEPTION_LOCATION);
3613 for (
unsigned b = 0; b < nb; b++)
3616 my_boundary_polyline_pt[b]->set_unrefinement_tolerance(
3617 unrefinement_tolerance[b]);
3619 my_boundary_polyline_pt[b]->set_refinement_tolerance(
3620 refinement_tolerance[b]);
3623 my_boundary_polyline_pt[b]->set_maximum_length(max_length[b]);
3625 return output_open_polyline_pt;
3640 std::ostringstream error_message;
3641 error_message <<
"TriangleMeshCurve that defines closed boundary\n"
3642 <<
"must be made up of at least two "
3643 <<
"TriangleMeshCurveSection\n"
3644 <<
"to allow the automatic set up boundary coordinates.\n"
3645 <<
"Yours only has " << nb << std::endl;
3647 OOMPH_CURRENT_FUNCTION,
3648 OOMPH_EXCEPTION_LOCATION);
3658 dynamic_cast<GeomObject*
>(input_closed_curve_pt);
3661 if (bound_geom_obj_pt != 0)
3664 for (
unsigned p = 0; p < n_poly; p++)
3691 for (
unsigned b = 0; b < nb; b++)
3697 if (curviline_pt != 0)
3702 zeta_bound[1] = curviline_pt->
zeta_end();
3724 for (
unsigned b = 0; b < nb; b++)
3730 if (curviline_pt != 0)
3735 zeta_bound[1] = curviline_pt->
zeta_end();
3750 #ifdef OOMPH_HAS_TRIANGLE_LIB
3764 curviline_pt, bound, polygonal_vertex_arclength);
3769 curviline_pt, bound, polygonal_vertex_arclength);
3784 double s_tolerance = 1.0e-14;
3786 target_s_value, bnd_id, s_tolerance);
3793 double& s_tolerance)
3801 unsigned vector_size = vertex_info->size();
3804 unsigned n_vertex = 0;
3810 double s = (*vertex_info)[n_vertex].second;
3813 if (std::fabs(
s - target_s_value) < s_tolerance)
3820 }
while (n_vertex < vector_size);
3824 if (n_vertex >= vector_size)
3826 std::ostringstream error_message;
3827 error_message <<
"Could not find the associated vertex number in\n"
3828 <<
"boundary " << bnd_id <<
" with the given s\n"
3829 <<
"connection value (" << target_s_value <<
") using\n"
3830 <<
"this tolerance: " << s_tolerance << std::endl;
3832 OOMPH_CURRENT_FUNCTION,
3833 OOMPH_EXCEPTION_LOCATION);
3850 template<
class ELEMENT>
3852 const unsigned& b, std::ofstream& outfile)
3866 unsigned n_repeated_ele = 0;
3868 unsigned n_regions = this->
nregion();
3870 #ifdef OOMPH_HAS_MPI
3874 std::map<FiniteElement*, FiniteElement*> face_to_bulk_element_pt;
3884 for (
unsigned rr = 0; rr < n_regions; rr++)
3894 std::ostringstream error_message;
3895 error_message <<
"Region attributes should be unsigneds because we \n"
3896 <<
"only use them to set region ids\n";
3898 OOMPH_CURRENT_FUNCTION,
3899 OOMPH_EXCEPTION_LOCATION);
3904 unsigned nel_in_region =
3906 unsigned nel_repeated_in_region = 0;
3911 if (nel_in_region == 0)
3913 std::ostringstream warning_message;
3915 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
3917 <<
"There are no elements associated with boundary (" << b
3919 <<
"in region (" << region_id <<
"). This could happen because:\n"
3920 <<
"1) You did not specify boundaries with this boundary id.\n"
3921 <<
"---- Review carefully the indexing of your boundaries.\n"
3922 <<
"2) The boundary (" << b <<
") is not associated with region ("
3923 << region_id <<
").\n"
3924 <<
"---- The boundary does not touch the region.\n"
3925 <<
"You can suppress this warning by setting the static public "
3928 "UnstructuredTwoDMeshGeometryBase::Suppress_warning_about_"
3929 "regions_and_boundaries\n\n"
3932 warning_message.str(), output_string, OOMPH_EXCEPTION_LOCATION);
3939 if (nel_in_region > 0)
3943 bool repeated =
false;
3946 for (
unsigned e = 0;
e < nel_in_region;
e++)
3952 #ifdef OOMPH_HAS_MPI
3973 const unsigned n_nodes = tmp_ele_pt->
nnode();
3975 std::pair<Node*, Node*> tmp_pair = std::make_pair(
3978 std::pair<Node*, Node*> tmp_pair_inverse = std::make_pair(
3982 const unsigned n_done_nodes = done_nodes_pt.size();
3983 for (
unsigned l = 0; l < n_done_nodes; l++)
3985 if (tmp_pair == done_nodes_pt[l] ||
3986 tmp_pair_inverse == done_nodes_pt[l])
3988 nel_repeated_in_region++;
3998 done_nodes_pt.push_back(tmp_pair);
3999 #ifdef OOMPH_HAS_MPI
4006 face_to_bulk_element_pt[tmp_ele_pt] = bulk_elem_pt;
4010 face_el_pt.push_back(tmp_ele_pt);
4023 if (outfile.is_open())
4025 face_el_pt[face_el_pt.size() - 1]->output(outfile);
4029 nel += nel_in_region;
4031 n_repeated_ele += nel_repeated_in_region;
4049 std::ostringstream warning_message;
4051 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
4053 <<
"There are no elements associated with boundary (" << b <<
").\n"
4054 <<
"This could happen because you did not specify boundaries with\n"
4055 <<
"this boundary id. Review carefully the indexing of your\n"
4058 warning_message.str(), output_string, OOMPH_EXCEPTION_LOCATION);
4068 bool repeated =
false;
4071 for (
unsigned e = 0;
e < nel;
e++)
4076 #ifdef OOMPH_HAS_MPI
4097 const unsigned n_nodes = tmp_ele_pt->
nnode();
4099 std::pair<Node*, Node*> tmp_pair = std::make_pair(
4102 std::pair<Node*, Node*> tmp_pair_inverse = std::make_pair(
4106 const unsigned n_done_nodes = done_nodes_pt.size();
4107 for (
unsigned l = 0; l < n_done_nodes; l++)
4109 if (tmp_pair == done_nodes_pt[l] ||
4110 tmp_pair_inverse == done_nodes_pt[l])
4122 done_nodes_pt.push_back(tmp_pair);
4123 #ifdef OOMPH_HAS_MPI
4130 face_to_bulk_element_pt[tmp_ele_pt] = bulk_elem_pt;
4133 face_el_pt.push_back(tmp_ele_pt);
4146 if (outfile.is_open())
4148 face_el_pt[face_el_pt.size() - 1]->output(outfile);
4158 nel -= n_repeated_ele;
4161 if (nel != face_el_pt.size())
4163 std::ostringstream error_message;
4165 <<
"The independent counting of face elements (" << nel <<
") for "
4166 <<
"boundary (" << b <<
") is different\n"
4167 <<
"from the real number of face elements in the container ("
4168 << face_el_pt.size() <<
")\n";
4170 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
4183 std::vector<bool> is_halo_face_element(nel,
false);
4186 unsigned nnon_halo_face_elements = 0;
4188 #ifdef OOMPH_HAS_MPI
4193 for (
unsigned ie = 0; ie < nel; ie++)
4197 FiniteElement* tmp_bulk_ele_pt = face_to_bulk_element_pt[face_ele_pt];
4199 if (!tmp_bulk_ele_pt->
is_halo())
4202 is_halo_face_element[ie] =
false;
4204 nnon_halo_face_elements++;
4209 is_halo_face_element[ie] =
true;
4219 nnon_halo_face_elements = nel;
4221 #ifdef OOMPH_HAS_MPI
4227 const unsigned nhalo_face_element = nel - nnon_halo_face_elements;
4229 if (nhalo_face_element > 0)
4231 std::ostringstream error_message;
4233 <<
"There should not be halo face elements since they were not\n"
4234 <<
"considered when computing the face elements.\n"
4235 <<
"The number of found halo face elements is: ("
4236 << nhalo_face_element <<
").\n\n";
4238 OOMPH_CURRENT_FUNCTION,
4239 OOMPH_EXCEPTION_LOCATION);
4255 unsigned nsorted_face_elements = 0;
4259 std::map<FiniteElement*, bool> done_el;
4264 std::map<FiniteElement*, bool> is_inverted;
4269 while (nsorted_face_elements < nnon_halo_face_elements)
4273 std::list<FiniteElement*> sorted_el_pt;
4279 bool found_initial_face_element =
false;
4284 #ifdef OOMPH_HAS_MPI
4287 for (iface = 0; iface < nel; iface++)
4290 if (!is_halo_face_element[iface])
4292 ele_face_pt = face_el_pt[iface];
4294 if (!done_el[ele_face_pt])
4299 found_initial_face_element =
true;
4302 nsorted_face_elements++;
4306 sorted_el_pt.push_back(ele_face_pt);
4308 done_el[ele_face_pt] =
true;
4320 ele_face_pt = face_el_pt[0];
4323 found_initial_face_element =
true;
4326 nsorted_face_elements++;
4330 sorted_el_pt.push_back(ele_face_pt);
4332 done_el[ele_face_pt] =
true;
4334 #ifdef OOMPH_HAS_MPI
4339 if (!found_initial_face_element)
4341 std::ostringstream error_message;
4342 error_message <<
"Could not find an initial face element for the "
4343 "current segment\n";
4345 OOMPH_CURRENT_FUNCTION,
4346 OOMPH_EXCEPTION_LOCATION);
4351 const unsigned nnod = ele_face_pt->
nnode();
4356 Node* right_node_pt = ele_face_pt->
node_pt(nnod - 1);
4360 bool face_element_added =
false;
4370 for (
unsigned iiface = iface; iiface < nel; iiface++)
4373 face_element_added =
false;
4376 ele_face_pt = face_el_pt[iiface];
4380 if (!(done_el[ele_face_pt] || is_halo_face_element[iiface]))
4383 Node* local_left_node_pt = ele_face_pt->
node_pt(0);
4384 Node* local_right_node_pt = ele_face_pt->
node_pt(nnod - 1);
4387 if (left_node_pt == local_right_node_pt)
4389 left_node_pt = local_left_node_pt;
4390 sorted_el_pt.push_front(ele_face_pt);
4391 is_inverted[ele_face_pt] =
false;
4392 face_element_added =
true;
4395 else if (left_node_pt == local_left_node_pt)
4397 left_node_pt = local_right_node_pt;
4398 sorted_el_pt.push_front(ele_face_pt);
4399 is_inverted[ele_face_pt] =
true;
4400 face_element_added =
true;
4403 else if (right_node_pt == local_left_node_pt)
4405 right_node_pt = local_right_node_pt;
4406 sorted_el_pt.push_back(ele_face_pt);
4407 is_inverted[ele_face_pt] =
false;
4408 face_element_added =
true;
4411 else if (right_node_pt == local_right_node_pt)
4413 right_node_pt = local_left_node_pt;
4414 sorted_el_pt.push_back(ele_face_pt);
4415 is_inverted[ele_face_pt] =
true;
4416 face_element_added =
true;
4419 if (face_element_added)
4421 done_el[ele_face_pt] =
true;
4422 nsorted_face_elements++;
4428 }
while (face_element_added &&
4429 (nsorted_face_elements < nnon_halo_face_elements));
4432 segment_sorted_ele_pt.push_back(sorted_el_pt);
4436 #ifdef OOMPH_HAS_MPI
4441 if (nsorted_face_elements != nel || segment_sorted_ele_pt.size() != 1)
4443 std::ostringstream error_message;
4444 error_message <<
"Was only able to setup boundary coordinate on "
4445 <<
"boundary " << b <<
"\nfor " << nsorted_face_elements
4447 <<
" face elements. This usually means\n"
4448 <<
"that the boundary is not simply connected.\n\n"
4449 <<
"Re-run the setup_boundary_coordintes() function\n"
4450 <<
"with an output file specified "
4451 <<
"as the second argument.\n"
4452 <<
"This file will contain FaceElements that\n"
4453 <<
"oomph-lib believes to be located on the boundary.\n"
4456 OOMPH_CURRENT_FUNCTION,
4457 OOMPH_EXCEPTION_LOCATION);
4459 #ifdef OOMPH_HAS_MPI
4484 const unsigned nsegments = segment_sorted_ele_pt.size();
4487 if (nnon_halo_face_elements > 0 && nsegments == 0)
4489 std::ostringstream error_message;
4491 <<
"The number of segments is zero, but the number of nonhalo\n"
4492 <<
"elements is: (" << nnon_halo_face_elements <<
")\n";
4494 OOMPH_CURRENT_FUNCTION,
4495 OOMPH_EXCEPTION_LOCATION);
4503 #ifdef OOMPH_HAS_MPI
4515 for (
unsigned is = 0; is < nsegments; is++)
4519 if (segment_sorted_ele_pt[is].size() == 0)
4521 std::ostringstream error_message;
4523 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
4524 error_message <<
"The (" << is <<
")-th segment has no elements\n";
4526 error_message.str(), output_string, OOMPH_EXCEPTION_LOCATION);
4532 FiniteElement* first_ele_pt = segment_sorted_ele_pt[is].front();
4535 unsigned nnod = first_ele_pt->
nnode();
4539 if (is_inverted[first_ele_pt])
4541 first_node_pt = first_ele_pt->
node_pt(nnod - 1);
4545 double x_left = first_node_pt->
x(0);
4546 double y_left = first_node_pt->
x(1);
4556 std::set<Node*> local_nodes_pt;
4557 local_nodes_pt.insert(first_node_pt);
4559 #ifdef OOMPH_HAS_MPI
4567 for (std::list<FiniteElement*>::iterator it =
4568 segment_sorted_ele_pt[is].begin();
4569 it != segment_sorted_ele_pt[is].end();
4578 if (is_inverted[el_pt])
4585 for (
unsigned j = 1; j < nnod; j++)
4591 double x_right = nod_pt->
x(0);
4592 double y_right = nod_pt->
x(1);
4595 zeta[0] += sqrt((x_right - x_left) * (x_right - x_left) +
4596 (y_right - y_left) * (y_right - y_left));
4607 local_nodes_pt.insert(nod_pt);
4609 #ifdef OOMPH_HAS_MPI
4620 segment_arclength[is] = zeta[0];
4623 segment_all_nodes_pt.push_back(local_nodes_pt);
4657 #ifdef OOMPH_HAS_MPI
4672 for (
unsigned is = 0; is < nsegments; is++)
4685 FiniteElement* first_ele_pt = segment_sorted_ele_pt[is].front();
4688 const unsigned nnod = first_ele_pt->
nnode();
4692 if (is_inverted[first_ele_pt])
4694 first_node_pt = first_ele_pt->
node_pt(nnod - 1);
4698 FiniteElement* last_ele_pt = segment_sorted_ele_pt[is].back();
4701 Node* last_node_pt = last_ele_pt->
node_pt(nnod - 1);
4702 if (is_inverted[last_ele_pt])
4704 last_node_pt = last_ele_pt->
node_pt(0);
4712 b, current_segment_initial_zeta);
4714 b, current_segment_final_zeta);
4719 if (current_segment_initial_zeta[0] < current_segment_final_zeta[0])
4723 else if (current_segment_initial_zeta[0] >
4724 current_segment_final_zeta[0])
4726 std::stringstream error_message;
4727 std::string output_string =
"UnstructuredTwoDMeshGeometryBase::"
4728 "setup_boundary_coordinates()";
4730 <<
"The zeta values are in decreasing order, this is weird\n"
4731 <<
"since they have just been set-up in increasing order few\n"
4733 <<
"Boundary: (" << b <<
")\n"
4734 <<
"Segment: (" << is <<
")\n"
4735 <<
"Initial zeta value: (" << current_segment_initial_zeta[0]
4737 <<
"Initial coordinate: (" << first_node_pt->
x(0) <<
", "
4738 << first_node_pt->
x(1) <<
")\n"
4739 <<
"Final zeta value: (" << current_segment_final_zeta[0]
4741 <<
"Initial coordinate: (" << last_node_pt->
x(0) <<
", "
4742 << last_node_pt->
x(1) <<
")\n";
4744 error_message.str(), output_string, OOMPH_EXCEPTION_LOCATION);
4748 std::stringstream error_message;
4749 std::string output_string =
"UnstructuredTwoDMeshGeometryBase::"
4750 "setup_boundary_coordinates()";
4752 <<
"It was not possible to determine whether the zeta values on"
4753 <<
"the current segment\nof the boundary are in"
4754 <<
"increasing or decreasing order\n\n"
4755 <<
"Boundary: (" << b <<
")\n"
4756 <<
"Segment: (" << is <<
")\n"
4757 <<
"Arclength: (" << segment_arclength[is] <<
"\n"
4758 <<
"Initial zeta value: (" << current_segment_initial_zeta[0]
4760 <<
"Initial coordinate: (" << first_node_pt->
x(0) <<
", "
4761 << first_node_pt->
x(1) <<
")\n"
4762 <<
"Final zeta value: (" << current_segment_final_zeta[0]
4764 <<
"Initial coordinate: (" << last_node_pt->
x(0) <<
", "
4765 << last_node_pt->
x(1) <<
")\n";
4767 error_message.str(), output_string, OOMPH_EXCEPTION_LOCATION);
4773 const double original_segment_initial_zeta =
4775 const double original_segment_final_zeta =
4780 if (original_segment_final_zeta > original_segment_initial_zeta)
4790 std::set<Node*> all_nodes_pt = segment_all_nodes_pt[is];
4791 for (std::set<Node*>::iterator it = all_nodes_pt.begin();
4792 it != all_nodes_pt.end();
4797 Node* nod_pt = (*it);
4801 zeta[0] = segment_arclength[is] - zeta[0];
4812 else if (original_segment_final_zeta <
4813 original_segment_initial_zeta)
4827 std::set<Node*> all_nodes_pt = segment_all_nodes_pt[is];
4828 for (std::set<Node*>::iterator it = all_nodes_pt.begin();
4829 it != all_nodes_pt.end();
4834 Node* nod_pt = (*it);
4838 zeta[0] = segment_arclength[is] - zeta[0];
4847 std::stringstream error_message;
4848 std::string output_string =
"UnstructuredTwoDMeshGeometryBase::"
4849 "setup_boundary_coordinates()";
4851 <<
"It was not possible to identify if the zeta values on the\n"
4852 <<
"current segment in the boundary should go in increasing\n"
4853 <<
"or decreasing order.\n\n"
4854 <<
"Boundary: (" << b <<
")\n"
4855 <<
"Segment: (" << is <<
")\n"
4856 <<
"Initial zeta value: (" << original_segment_initial_zeta
4858 <<
"Final zeta value: (" << original_segment_final_zeta
4861 error_message.str(), output_string, OOMPH_EXCEPTION_LOCATION);
4879 if (segment_all_nodes_pt.size() != nsegments)
4881 std::ostringstream error_message;
4883 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
4884 error_message <<
"The number of segments (" << nsegments
4885 <<
") and the number of "
4886 <<
"sets of nodes (" << segment_all_nodes_pt.size()
4887 <<
") representing\n"
4888 <<
"the\nsegments is different!!!\n\n";
4890 error_message.str(), output_string, OOMPH_EXCEPTION_LOCATION);
4918 double boundary_arclength = 0.0;
4925 #ifdef OOMPH_HAS_MPI
4943 boundary_arclength =
4944 std::max(first_node_zeta_coordinate[0], last_node_zeta_coordinate[0]);
4947 if (boundary_arclength == 0)
4949 std::ostringstream error_message;
4951 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
4952 error_message <<
"The boundary arclength is zero for boundary (" << b
4955 error_message.str(), output_string, OOMPH_EXCEPTION_LOCATION);
4995 initial_segment_arclength[0] = 0.0;
4997 #ifdef OOMPH_HAS_MPI
5015 for (
unsigned is = 0; is < nsegments; is++)
5018 if (segment_sorted_ele_pt[is].size() == 0)
5020 std::ostringstream error_message;
5022 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
5023 error_message <<
"The (" << is <<
")-th segment has no elements\n";
5025 error_message.str(), output_string, OOMPH_EXCEPTION_LOCATION);
5032 #ifdef OOMPH_HAS_MPI
5042 FiniteElement* first_ele_pt = segment_sorted_ele_pt[is].front();
5045 const unsigned nnod = first_ele_pt->
nnode();
5049 if (is_inverted[first_ele_pt])
5051 first_node_pt = first_ele_pt->
node_pt(nnod - 1);
5055 FiniteElement* last_ele_pt = segment_sorted_ele_pt[is].back();
5058 Node* last_node_pt = last_ele_pt->
node_pt(nnod - 1);
5059 if (is_inverted[last_ele_pt])
5061 last_node_pt = last_ele_pt->
node_pt(0);
5065 for (
unsigned i = 0;
i < 2;
i++)
5067 first_coordinate[
i] = first_node_pt->
x(
i);
5068 last_coordinate[
i] = last_node_pt->
x(
i);
5073 b, first_node_zeta_coordinate);
5075 last_node_zeta_coordinate);
5077 #ifdef OOMPH_HAS_MPI
5082 std::set<Node*> all_nodes_pt = segment_all_nodes_pt[is];
5087 if (geom_object_pt != 0)
5098 zeta[0] = bound_coord_limits[0];
5103 geom_object_pt->
position(zeta, first_geom_object_location);
5107 zeta[0] = bound_coord_limits[1];
5112 geom_object_pt->
position(zeta, last_geom_object_location);
5117 double tmp_error = 0.0;
5118 for (
unsigned i = 0;
i < 2;
i++)
5121 first_geom_object_location[
i] - first_coordinate[
i];
5122 tmp_error += dist * dist;
5124 error += sqrt(tmp_error);
5126 for (
unsigned i = 0;
i < 2;
i++)
5129 last_geom_object_location[
i] - last_coordinate[
i];
5130 tmp_error += dist * dist;
5132 error += sqrt(tmp_error);
5137 double rev_error = 0.0;
5139 for (
unsigned i = 0;
i < 2;
i++)
5142 first_geom_object_location[
i] - last_coordinate[
i];
5143 tmp_error += dist * dist;
5145 rev_error += sqrt(tmp_error);
5147 for (
unsigned i = 0;
i < 2;
i++)
5150 last_geom_object_location[
i] - first_coordinate[
i];
5151 tmp_error += dist * dist;
5153 rev_error += sqrt(tmp_error);
5165 if (error < rev_error)
5172 else if (error > rev_error)
5178 double temp = bound_coord_limits[0];
5179 bound_coord_limits[0] = bound_coord_limits[1];
5180 bound_coord_limits[1] = temp;
5182 #ifdef OOMPH_HAS_MPI
5188 temp = initial_segment_zeta[is];
5189 initial_segment_zeta[is] = final_segment_zeta[is];
5190 final_segment_zeta[is] = temp;
5191 #ifdef OOMPH_HAS_MPI
5195 for (
unsigned v = 0; v < n_vertex; v++)
5197 polygonal_vertex_arclength[v].first =
5200 polygonal_vertex_arclength[v].second =
5206 std::ostringstream error_stream;
5208 "UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates()";
5210 <<
"Something very strange has happened.\n"
5211 <<
"The error between the endpoints of the geometric object\n"
5212 <<
"and the first and last nodes on the boundary is the same\n"
5213 <<
"irrespective of the direction of the coordinate.\n"
5214 <<
"This probably means that things are way off.\n"
5215 <<
"The errors are " << error <<
" and " << rev_error <<
"\n";
5216 std::cout << error_stream.str();
5218 error_stream.str(), output_string, OOMPH_EXCEPTION_LOCATION);
5227 const double zeta_old_range = segment_arclength[is];
5232 double zeta_new_range =
5233 final_segment_zeta[is] - initial_segment_zeta[is];
5235 double initial_local_segment_zeta = initial_segment_zeta[is];
5237 #ifdef OOMPH_HAS_MPI
5247 std::fabs(final_segment_zeta[is] - initial_segment_zeta[is]);
5250 initial_local_segment_zeta =
5251 std::min(initial_segment_zeta[is], final_segment_zeta[is]);
5258 unsigned use_old =
false;
5259 if (n_vertex == 0) use_old =
true;
5262 for (std::set<Node*>::iterator it = all_nodes_pt.begin();
5263 it != all_nodes_pt.end();
5267 Node* nod_pt = (*it);
5275 zeta[0] = initial_local_segment_zeta +
5276 (zeta_new_range / zeta_old_range) * (zeta[0]);
5284 for (
unsigned v = 1; v < n_vertex; v++)
5286 if ((zeta[0] >= polygonal_vertex_arclength[v - 1].first) &&
5287 (zeta[0] <= polygonal_vertex_arclength[v].first))
5291 (polygonal_vertex_arclength[v].second -
5292 polygonal_vertex_arclength[v - 1].second);
5294 double delta_polyarc =
5295 (polygonal_vertex_arclength[v].first -
5296 polygonal_vertex_arclength[v - 1].first);
5300 polygonal_vertex_arclength[v - 1].second +
5302 (zeta[0] - polygonal_vertex_arclength[v - 1].first) /
5318 double diff = std::fabs(
5319 zeta[0] - polygonal_vertex_arclength[n_vertex - 1].first);
5323 std::ostringstream error_stream;
5325 <<
"Wasn't able to locate the polygonal arclength exactly\n"
5326 <<
"during re-setup of boundary coordinates and have\n"
5327 <<
"assumed that we're dealing with the final point along\n"
5328 <<
"the curvilinear segment and encountered some roundoff\n"
5329 <<
"However,the difference in the polygonal zeta "
5331 <<
"between zeta[0] " << zeta[0]
5332 <<
" and the originallly stored value "
5333 << polygonal_vertex_arclength[n_vertex - 1].first <<
"\n"
5335 <<
" which exceeds the threshold specified\n"
5336 <<
"in the publically modifiable variable\n"
5337 <<
"ToleranceForVertexMismatchInPolygons::Tolerable_error\n"
5338 <<
"whose current value is: "
5340 <<
"\nPlease check your mesh carefully and increase the\n"
5341 <<
"threshold if you're sure this is appropriate\n";
5343 OOMPH_CURRENT_FUNCTION,
5344 OOMPH_EXCEPTION_LOCATION);
5347 zeta[0] = polygonal_vertex_arclength[n_vertex - 1].second;
5358 double z_initial = initial_segment_arclength[is];
5365 bottom_left_coordinate = first_coordinate;
5369 bottom_left_zeta_coordinate = first_node_zeta_coordinate;
5373 if (last_coordinate[1] < bottom_left_coordinate[1])
5376 bottom_left_coordinate = last_coordinate;
5379 bottom_left_zeta_coordinate = last_node_zeta_coordinate;
5382 else if (last_coordinate[1] == bottom_left_coordinate[1])
5385 if (last_coordinate[0] < bottom_left_coordinate[0])
5389 bottom_left_coordinate = last_coordinate;
5392 bottom_left_zeta_coordinate = last_node_zeta_coordinate;
5401 zeta = bottom_left_zeta_coordinate;
5402 const double zeta_ref = zeta[0];
5405 double zeta_max = 0.0;
5406 for (std::set<Node*>::iterator it = all_nodes_pt.begin();
5407 it != all_nodes_pt.end();
5410 Node* nod_pt = (*it);
5413 #ifdef OOMPH_HAS_MPI
5426 zeta[0] = segment_arclength[is] - zeta[0];
5433 zeta[0] += z_initial;
5435 zeta[0] -= zeta_ref;
5439 zeta[0] = std::fabs(zeta[0]);
5443 if (zeta[0] > zeta_max)
5450 #ifdef OOMPH_HAS_MPI
5461 FiniteElement* first_seg_ele_pt = segment_sorted_ele_pt[is].front();
5466 if (first_seg_ele_pt->
is_halo())
5468 std::ostringstream error_message;
5469 std::string output_string =
"UnstructuredTwoDMeshGeometryBase::"
5470 "setup_boundary_coordinates()";
5471 error_message <<
"The first face element in the (" << is
5475 error_message.str(), output_string, OOMPH_EXCEPTION_LOCATION);
5480 const unsigned nnod = first_seg_ele_pt->
nnode();
5483 Node* first_seg_node_pt = first_seg_ele_pt->
node_pt(0);
5484 if (is_inverted[first_seg_ele_pt])
5486 first_seg_node_pt = first_seg_ele_pt->
node_pt(nnod - 1);
5490 FiniteElement* last_seg_ele_pt = segment_sorted_ele_pt[is].back();
5495 if (last_seg_ele_pt->
is_halo())
5497 std::ostringstream error_message;
5498 std::string output_string =
"UnstructuredTwoDMeshGeometryBase::"
5499 "setup_boundary_coordinates()";
5500 error_message <<
"The last face element in the (" << is
5504 error_message.str(), output_string, OOMPH_EXCEPTION_LOCATION);
5509 Node* last_seg_node_pt = last_seg_ele_pt->
node_pt(nnod - 1);
5510 if (is_inverted[last_seg_ele_pt])
5512 last_seg_node_pt = last_seg_ele_pt->
node_pt(0);
5529 for (
unsigned k = 0; k < 2; k++)
5531 updated_segment_initial_coord[k] = first_seg_node_pt->
x(k);
5532 updated_segment_final_coord[k] = last_seg_node_pt->
x(k);
5537 updated_segment_initial_coord;
5541 updated_segment_final_coord;
5551 if (zeta_max < boundary_arclength)
5553 zeta_max = boundary_arclength;
5558 for (std::set<Node*>::iterator it = all_nodes_pt.begin();
5559 it != all_nodes_pt.end();
5563 Node* nod_pt = (*it);
5569 zeta[0] /= zeta_max;
5585 for (
unsigned e = 0;
e < nel;
e++)
5587 delete face_el_pt[
e];
5607 namespace TriangleBoundaryHelper
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
A general Finite Element class.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
unsigned nnode() const
Return the number of nodes.
bool is_halo() const
Is this element a halo?
/////////////////////////////////////////////////////////////////////
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
bool is_mesh_distributed() const
Boolean to indicate if Mesh has been distributed.
std::vector< bool > Boundary_coordinate_exists
Vector of boolean data that indicates whether the boundary coordinates have been set for the boundary...
int face_index_at_boundary(const unsigned &b, const unsigned &e) const
For the e-th finite element on boundary b, return int to indicate the face_index of the face adjacent...
unsigned nboundary_element(const unsigned &b) const
Return number of finite elements that are adjacent to boundary b.
FiniteElement * boundary_element_pt(const unsigned &b, const unsigned &e) const
Return pointer to e-th finite element on boundary b.
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
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...
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....
An OomphLibError object which should be thrown when an run-time error is encountered....
An OomphLibWarning object which should be created as a temporary object to issue a warning....
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
void output(std::ostream &outfile, const unsigned &n_sample=50)
Output each sub-boundary at n_sample (default: 50) points.
Vector< double > internal_point() const
Coordinates of the internal point.
TriangleMeshClosedCurve(const Vector< TriangleMeshCurveSection * > &curve_section_pt, const Vector< double > &internal_point_pt=Vector< double >(0), const bool &is_internal_point_fixed=false)
Constructor prototype.
unsigned nvertices() const
Number of vertices.
Vector< double > Internal_point_pt
Vector of vertex coordinates.
bool is_internal_point_fixed() const
Test whether the internal point is fixed.
bool Is_internal_point_fixed
Indicate whether the internal point should be updated automatically.
unsigned nsegments() const
Total number of segments.
void unfix_internal_point()
Unfix the internal point (i.e. allow our automatic machinery to update it)
Vector< double > & internal_point()
Coordinates of the internal point.
void fix_internal_point()
Fix the internal point (i.e. do not allow our automatic machinery to update it)
virtual ~TriangleMeshClosedCurve()
Empty destructor.
Base class for defining a triangle mesh boundary, this class has the methods that allow to connect th...
bool Final_vertex_connected_suspended
Indicates if the connection is suspended because the boundary to connect is no longer part of the dom...
bool Initial_vertex_connected_to_curviline
States if the initial vertex is connected to a curviline.
virtual void initial_vertex_coordinate(Vector< double > &vertex)=0
Get first vertex coordinates.
bool is_initial_vertex_connected_to_curviline() const
Test whether the initial vertex is connected to a curviline.
virtual unsigned boundary_chunk() const =0
Boundary chunk (Used when a boundary is represented by more than one polyline.
virtual void output(std::ostream &outfile, const unsigned &n_sample=50)=0
Output the curve_section.
bool Final_vertex_connected
Used for stating if the final end is connected to another boundary.
double unrefinement_tolerance()
Get tolerance for unrefinement of curve section to create a better representation of curvilinear boun...
void unset_final_vertex_connected_to_curviline()
Sets the final vertex as non connected to a curviline.
unsigned Final_vertex_connected_n_vertex
Stores the vertex number used for connection with the final end.
double final_s_connection_value() const
Gets the s value to which the final end is connected.
double Unrefinement_tolerance
Tolerance for unrefinement of curve sections (neg if refinement is disabled)
unsigned & final_vertex_connected_n_vertex()
Gets the vertex number to which the final end is connected.
bool Final_vertex_connected_to_curviline
States if the final vertex is connected to a curviline.
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 ...
virtual unsigned boundary_id() const =0
Boundary id.
unsigned & final_vertex_connected_bnd_id()
Sets the id to which the final end is connected.
void connect_initial_vertex_to_polyline(TriangleMeshPolyLine *polyline_pt, const unsigned &vertex_number, const double &tolerance_for_connection=1.0e-14)
Connects the initial vertex of the curve section to a desired target polyline by specifying the verte...
double & tolerance_for_s_connection()
Sets the tolerance value for connections among curvilines.
void resume_initial_vertex_connected()
Resumes the initial vertex connection, it may be that after load balancing the boundary to which the ...
double Final_s_connection_value
Stores the s value used for connecting the final end with a curviline.
double tolerance_for_s_connection() const
Gets the tolerance value for connections among curvilines.
unsigned Final_vertex_connected_bnd_id
Stores the id to which the initial end is connected.
void suspend_final_vertex_connected()
Set the final vertex connection as suspended, it will be resumed when the method to resume the connec...
unsigned Initial_vertex_connected_n_chunk
Stores the chunk number of the boundary to which is connected th initial end.
unsigned initial_vertex_connected_n_vertex() const
Gets the vertex number to which the initial end is connected.
void resume_final_vertex_connected()
Resumes the final vertex connection, it may be that after load balancing the boundary to which the co...
double Refinement_tolerance
Tolerance for refinement of curve sections (neg if refinement is disabled)
void set_refinement_tolerance(const double &tolerance)
Set tolerance for refinement of curve sections to create a better representation of curvilinear bound...
virtual unsigned nvertex() const =0
Number of vertices.
virtual ~TriangleMeshCurveSection()
Empty destructor.
virtual unsigned nsegment() const =0
Number of segments that this part of the boundary is to be represented by. This corresponds to the nu...
double Maximum_length
Maximum allowed distance between two vertices on the polyline representation of the curve section.
void connect_final_vertex_to_polyline(TriangleMeshPolyLine *polyline_pt, const unsigned &vertex_number, const double &tolerance_for_connection=1.0e-14)
Connects the final vertex of the curve section to a desired target polyline by specifying the vertex ...
unsigned final_vertex_connected_n_chunk() const
Gets the boundary chunk to which the final end is connected.
void set_maximum_length(const double &maximum_length)
Allows to specify the maximum distance between two vertices that define the associated polyline of th...
void unset_initial_vertex_connected()
Sets the initial vertex as non connected.
bool Initial_vertex_connected
Used for stating if the initial end is connected to another boundary.
unsigned final_vertex_connected_n_vertex() const
Sets the vertex number to which the final end is connected.
double refinement_tolerance()
Get tolerance for refinement of curve sections to create a better representation of curvilinear bound...
unsigned & final_vertex_connected_n_chunk()
Sets the boundary chunk to which the final end is connected.
unsigned Initial_vertex_connected_n_vertex
Stores the vertex number used for connection with the initial end.
bool Initial_vertex_connected_suspended
Indicates if the connection is suspended because the boundary to connect is no longer part of the dom...
TriangleMeshCurveSection()
Empty constructor. Initialises the curve section as non connected.
double & initial_s_connection_value()
Sets the s value to which the initial end is connected.
void disable_refinement_tolerance()
Disable refinement of curve section.
bool is_final_vertex_connected_to_curviline() const
Test whether the final vertex is connected to a curviline.
bool is_final_vertex_connected() const
Test whether final vertex is connected or not.
double Tolerance_for_s_connection
Tolerance used for connecting the ends to a curviline.
void disable_unrefinement_tolerance()
Disable unrefinement of curve sections.
unsigned & initial_vertex_connected_n_chunk()
Sets the boundary chunk to which the initial end is connected.
unsigned & initial_vertex_connected_bnd_id()
Sets the id to which the initial end is connected.
unsigned initial_vertex_connected_bnd_id() const
Gets the id to which the initial end is connected.
virtual void final_vertex_coordinate(Vector< double > &vertex)=0
Get last vertex coordinates.
bool is_initial_vertex_connected() const
Test whether initial vertex is connected or not.
double & final_s_connection_value()
Sets the s value to which the final end is connected.
void enable_refinement_tolerance(const double &tolerance=0.08)
Enable refinement of curve section to create a better representation of curvilinear boundaries (e....
void set_initial_vertex_connected()
Sets the initial vertex as connected.
unsigned Final_vertex_connected_n_chunk
Stores the chunk number of the boundary to which is connected th initial end.
void set_final_vertex_connected()
Sets the final vertex as connected.
void enable_unrefinement_tolerance(const double &tolerance=0.04)
Enable unrefinement of curve sections to avoid unnecessarily large numbers of elements on of curvilin...
void unset_final_vertex_connected()
Sets the final vertex as non connected.
void connect_initial_vertex_to_curviline(TriangleMeshCurviLine *curviline_pt, const double &s_value, const double &tolerance_for_connection=1.0e-14)
Connects the initial vertex of the curve section to a desired target curviline by specifying the s va...
void set_initial_vertex_connected_to_curviline()
Sets the initial vertex as connected to a curviline.
unsigned & initial_vertex_connected_n_vertex()
Sets the vertex number to which the initial end is connected.
double initial_s_connection_value() const
Gets the s value to which the initial end is connected.
void suspend_initial_vertex_connected()
Set the initial vertex connection as suspended, it will be resumed when the method to resume the conn...
unsigned initial_vertex_connected_n_chunk() const
Gets the boundary chunk to which the initial end is connected.
double maximum_length()
Gets access to the maximum length variable.
void connect_final_vertex_to_curviline(TriangleMeshCurviLine *curviline_pt, const double &s_value, const double &tolerance_for_connection=1.0e-14)
Connects the final vertex of the curve section to a desired target curviline by specifying the s valu...
void set_final_vertex_connected_to_curviline()
Sets the final vertex as connected to a curviline.
unsigned final_vertex_connected_bnd_id() const
Gets the id to which the final end is connected.
unsigned Initial_vertex_connected_bnd_id
Stores the id to which the initial end is connected.
void disable_use_maximum_length()
Disables the use of the maximum length criteria on the unrefinement or refinement steps.
void unset_initial_vertex_connected_to_curviline()
Sets the initial vertex as non connected to a curviline.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
double Polyline_unrefinement_tolerance
Tolerance for unrefinement of polylines (neg if refinement is disabled)
void set_polyline_refinement_tolerance(const double &tolerance)
Set tolerance for refinement of polylines to create a better representation of curvilinear boundaries...
void set_polyline_unrefinement_tolerance(const double &tolerance)
Set tolerance for unrefinement of polylines to avoid unnecessarily large numbers of elements on of cu...
void disable_polyline_unrefinement()
Disable unrefinement of polylines.
Vector< TriangleMeshCurveSection * > Curve_section_pt
Vector of curve sections.
TriangleMeshCurve(const Vector< TriangleMeshCurveSection * > &curve_section_pt)
Empty constructor.
virtual void output(std::ostream &outfile, const unsigned &n_sample=50)=0
Output each sub-boundary at n_sample (default: 50) points.
void disable_polyline_refinement()
Disable refinement of polylines.
virtual TriangleMeshCurveSection *& curve_section_pt(const unsigned &i)
Pointer to i-th constituent curve section.
virtual TriangleMeshCurveSection * curve_section_pt(const unsigned &i) const
Pointer to i-th constituent curve section.
double polyline_unrefinement_tolerance()
Get tolerance for unrefinement of polylines to create a better representation of curvilinear boundari...
void enable_polyline_refinement(const double &tolerance=0.08)
Enable refinement of polylines to create a better representation of curvilinear boundaries (e....
virtual ~TriangleMeshCurve()
Empty destructor.
virtual unsigned nsegments() const =0
Total number of segments.
double Polyline_refinement_tolerance
Tolerance for refinement of polylines (neg if refinement is disabled)
double polyline_refinement_tolerance()
Get tolerance for refinement of polylines to create a better representation of curvilinear boundaries...
virtual unsigned nvertices() const =0
Number of vertices.
void enable_polyline_unrefinement(const double &tolerance=0.04)
Enable unrefinement of polylines to avoid unnecessarily large numbers of elements on of curvilinear b...
unsigned max_boundary_id()
Return max boundary id of associated curves.
virtual unsigned ncurve_section() const
Number of constituent curves.
Class definining a curvilinear triangle mesh boundary in terms of a GeomObject. Curvlinear equivalent...
GeomObject * geom_object_pt()
Pointer to GeomObject that represents this part of the boundary.
bool are_there_connection_points()
Does the vector for storing connections has elements?
unsigned Boundary_id
Boundary ID.
void initial_vertex_coordinate(Vector< double > &vertex)
Get first vertex coordinates.
unsigned & nsegment()
Number of (initially straight-line) segments that this part of the boundary is to be represented by....
Vector< double > Connection_points_pt
Stores the information for connections received on the curviline. Used when converting to polyline.
void add_connection_point(const double &z_value, const double &tol=1.0e-12)
Add the connection point (z_value) to the connection points that receive the curviline.
bool Space_vertices_evenly_in_arclength
Boolean to indicate if vertices in polygonal representation of the Curviline are spaced (approximatel...
unsigned boundary_chunk() const
Boundary chunk (Used when a boundary is represented by more than one polyline.
void output(std::ostream &outfile, const unsigned &n_sample=50)
Output curvilinear boundary at n_sample (default: 50) points.
unsigned nvertex() const
Number of vertices.
double Zeta_end
End coordinate in terms of the GeomObject's intrinsic coordinate.
void final_vertex_coordinate(Vector< double > &vertex)
Get last vertex coordinates.
double zeta_start()
Start coordinate in terms of the GeomObject's intrinsic coordinate.
GeomObject * Geom_object_pt
Pointer to GeomObject that represents this part of the boundary.
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...
unsigned Boundary_chunk
Boundary chunk (Used when a boundary is represented by more than one polyline.
double Zeta_start
Start coordinate in terms of the GeomObject's intrinsic coordinate.
Vector< double > * connection_points_pt()
Returns the connection points vector.
virtual ~TriangleMeshCurviLine()
Empty Destuctor.
unsigned boundary_id() const
Boundary ID.
double zeta_end()
End coordinate in terms of the GeomObject's intrinsic coordinate.
unsigned Nsegment
Number of (initially straight-line) segments that this part of the boundary is to be represented by.
bool space_vertices_evenly_in_arclength() const
Boolean to indicate if vertices in polygonal representation of the Curvline are spaced (approximately...
unsigned nsegment() const
Number of (initially straight-line) segments that this part of the boundary is to be represented by.
////////////////////////////////////////////////////////////////////// //////////////////////////////...
TriangleMeshOpenCurve(const Vector< TriangleMeshCurveSection * > &curve_section_pt)
Constructor.
TriangleMeshPolyLine * polyline_pt(const unsigned &i)
Pointer to i-th constituent polyline.
unsigned nsegments() const
Total number of segments.
virtual ~TriangleMeshOpenCurve()
Empty destructor.
unsigned nvertices() const
Number of vertices.
TriangleMeshPolyLine * polyline_pt(const unsigned &i) const
Pointer to i-th constituent polyline.
void output(std::ostream &outfile, const unsigned &n_sample=50)
Output each sub-boundary at n_sample (default: 50) points.
Class defining a polyline for use in Triangle Mesh generation.
unsigned Boundary_id
Boundary ID.
unsigned boundary_chunk() const
Boundary chunk (Used when a boundary is represented by more than one polyline.
unsigned Boundary_chunk
Boundary chunk (Used when a boundary is represented by more than one polyline.
unsigned nsegment() const
Number of segments.
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 final_vertex_coordinate(Vector< double > &vertex)
Get last vertex coordinates.
virtual ~TriangleMeshPolyLine()
Empty destructor.
unsigned nvertex() const
Number of vertices.
void output(std::ostream &outfile, const unsigned &n_sample=50)
Output the polyline – n_sample is ignored.
Vector< double > & vertex_coordinate(const unsigned &i)
Coordinate vector of i-th vertex.
Vector< Vector< double > > Vertex_coordinate
Vector of Vector of vertex coordinates.
void reverse()
Reverse the polyline, this includes the connection information and the vertices order.
void initial_vertex_coordinate(Vector< double > &vertex)
Get first vertex coordinates.
Vector< double > vertex_coordinate(const unsigned &i) const
Coordinate vector of i-th vertex (const version)
unsigned boundary_id() const
Boundary id.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
unsigned npolyline() const
Number of constituent polylines.
TriangleMeshPolyLine * polyline_pt(const unsigned &i)
Pointer to i-th constituent polyline.
bool is_fixed() const
Test whether the polygon is fixed or not.
bool can_update_reference_configuration() const
Test whether curve can update reference.
void set_fixed()
Set the polygon to be fixed.
Vector< unsigned > polygon_boundary_id()
Return vector of boundary ids of associated polylines.
TriangleMeshPolyLine * polyline_pt(const unsigned &i) const
Pointer to i-th constituent polyline.
bool is_redistribution_of_segments_between_polylines_enabled()
Is re-distribution of polyline segments in the curve between different boundaries during adaptation e...
TriangleMeshPolygon(const Vector< TriangleMeshCurveSection * > &boundary_polyline_pt, const Vector< double > &internal_point_pt=Vector< double >(0), const bool &is_internal_point_fixed=false)
Constructor: Specify vector of pointers to TriangleMeshCurveSection that define the boundary of the s...
unsigned ncurve_section() const
Number of constituent curves.
bool Can_update_configuration
Boolean flag to indicate whether the polygon can update its own reference configuration after it has ...
bool Polygon_fixed
Boolean flag to indicate whether the polygon can move (default false because if it doesn't move this ...
void set_unfixed()
Set the polygon to be allowed to move (default)
virtual ~TriangleMeshPolygon()
Empty virtual destructor.
virtual void reset_reference_configuration()
Virtual function that should be overloaded to update the polygons reference configuration.
void disable_redistribution_of_segments_between_polylines()
Disable re-distribution of polyline segments in the curve between different boundaries during adaptat...
bool Enable_redistribution_of_segments_between_polylines
Is re-distribution of polyline segments between different boundaries during adaptation enabled?...
void enable_redistribution_of_segments_between_polylines()
Enable re-distribution of polyline segments in the curve between different boundaries during adaptati...
Contains functions which define the geometry of the mesh, i.e. regions, boundaries,...
std::map< unsigned, GeomObject * > Boundary_geom_object_pt
Storage for the geometric objects associated with any boundaries.
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 check_contiguousness_on_polylines_helper(Vector< TriangleMeshPolyLine * > &polylines_pt, unsigned &index)
Sort the polylines coming from joining them. Check whether it is necessary to reverse them or not....
Vector< TriangleMeshOpenCurve * > Internal_open_curve_pt
Vector of open polylines that define internal curves.
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.
std::map< unsigned, Vector< double > > & boundary_initial_zeta_coordinate()
Return direct access to the initial zeta coordinate of a boundary.
double region_attribute(const unsigned &i)
Return the attribute associated with region i.
Vector< double > & boundary_segment_final_arclength(const unsigned &b)
Return the final arclength for the segments that are part of a boundary.
static bool Suppress_warning_about_regions_and_boundaries
Public static flag to suppress warning; defaults to false.
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...
void disable_automatic_creation_of_vertices_on_boundaries()
Disables the creation of points (by Triangle) on the outer and internal boundaries.
std::map< unsigned, Vector< double > > & boundary_final_coordinate()
Return direct access to the final coordinates of a boundary.
bool is_automatic_creation_of_vertices_on_boundaries_allowed()
Returns the status of the variable Allow_automatic_creation_of_vertices_on_boundaries.
const bool get_connected_vertex_number_on_destination_polyline(TriangleMeshPolyLine *dst_polyline_pt, Vector< double > &vertex_coordinates, unsigned &vertex_number)
Gets the vertex number on the destination polyline (used to create the connections among shared bound...
Vector< double > & boundary_final_zeta_coordinate(const unsigned &b)
Return the final zeta coordinate for the boundary.
Vector< TriangleMeshPolygon * > Outer_boundary_pt
Polygon that defines outer boundaries.
Vector< Vector< double > > & boundary_segment_final_coordinate(const unsigned &b)
Return the final coordinates for the segments that are part of a boundary.
void initialise_base_vertex(TriangleMeshPolyLine *polyline_pt, std::map< unsigned, std::map< unsigned, Vector< base_vertex_info >>> &base_vertices)
Initialise the base vertex structure, set every vertex to no visited and not being a base vertex.
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...
void add_connection_matrix_info_helper(TriangleMeshPolyLine *polyline_pt, std::map< unsigned, std::map< unsigned, Vector< vertex_connection_info >>> &connection_matrix, TriangleMeshPolyLine *next_polyline_pt=0)
Helps to add information to the connection matrix of the given polyline.
void set_nboundary_segment_node(const unsigned &b, const unsigned &s)
Set the number of segments associated with a boundary.
void check_contiguousness_on_polylines_helper(Vector< TriangleMeshPolyLine * > &polylines_pt, unsigned &index_halo_start, unsigned &index_halo_end)
Sort the polylines coming from joining them. Check whether it is necessary to reverse them or not....
Vector< TriangleMeshPolygon * > Internal_polygon_pt
Vector of polygons that define internal polygons.
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.
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...
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.
Vector< double > & boundary_segment_initial_arclength(const unsigned &b)
Return the initial arclength for the segments that are part of a boundary.
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 ...
unsigned nboundary_segment(const unsigned &b)
Return the number of segments associated with a boundary.
void snap_nodes_onto_geometric_objects()
Snap the boundary nodes onto any curvilinear boundaries defined by geometric objects.
std::map< unsigned, Vector< double > > Boundary_initial_zeta_coordinate
Stores the initial zeta coordinate for the boundary.
std::map< unsigned, std::set< Node * > > Nodes_on_boundary_pt
Stores a pointer to a set with all the nodes related with a boundary.
unsigned long nboundary_segment_node(const unsigned &b)
Return the number of segments associated with a boundary.
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...
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.
~UnstructuredTwoDMeshGeometryBase()
Empty destructor.
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...
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.
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.
std::map< unsigned, Vector< double > > Regions_coordinates
Storage for extra coordinates for regions. The key on the map is the region id.
void enable_automatic_creation_of_vertices_on_boundaries()
Enables the creation of points (by Triangle) on the outer and internal boundaries.
Vector< Vector< double > > Extra_holes_coordinates
Storage for extra coordinates for holes.
std::map< unsigned, GeomObject * > & boundary_geom_object_pt()
Return direct access to the geometric object storage.
bool Allow_automatic_creation_of_vertices_on_boundaries
Flag to indicate whether the automatic creation of vertices along the boundaries by Triangle is allow...
UnstructuredTwoDMeshGeometryBase(const UnstructuredTwoDMeshGeometryBase &dummy)=delete
Broken copy constructor.
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.
Vector< std::map< unsigned, Vector< FiniteElement * > > > Boundary_region_element_pt
Storage for elements adjacent to a boundary in a particular region.
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.
std::map< unsigned, Vector< double > > Boundary_coordinate_limits
Storage for the limits of the boundary coordinates defined by the use of geometric objects....
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.
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.
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...
Vector< double > Region_attribute
Vector of attributes associated with the elements in each region.
Vector< std::map< unsigned, Vector< int > > > Face_index_region_at_boundary
Storage for the face index adjacent to a boundary in a particular region.
void copy_connection_information_to_sub_polylines(TriangleMeshCurveSection *input_curve_pt, TriangleMeshCurveSection *output_curve_pt)
Helper function to copy the connection information from the input curve(polyline or curviline) to the...
unsigned nboundary_element_in_region(const unsigned &b, const unsigned &r) const
Return the number of elements adjacent to boundary b in region r.
void add_boundary_segment_node(const unsigned &b, const unsigned &s, Node *const &node_pt)
Add the node node_pt to the b-th boundary and the s-th segment of the mesh.
Vector< double > & boundary_initial_coordinate(const unsigned &b)
Return the initial coordinates for the boundary.
unsigned nregion()
Return the number of regions specified by attributes.
TriangleMeshPolyLine * boundary_polyline_pt(const unsigned &b)
Return pointer to the current polyline that describes the b-th mesh boundary.
Vector< double > & boundary_segment_final_zeta(const unsigned &b)
Return the final zeta for the segments that are part of a boundary.
void add_base_vertex_info_helper(TriangleMeshPolyLine *polyline_pt, std::map< unsigned, std::map< unsigned, Vector< base_vertex_info >>> &base_vertices, std::map< unsigned, std::map< unsigned, Vector< vertex_connection_info >>> &connection_matrix, std::map< unsigned, std::map< unsigned, unsigned >> &boundary_chunk_nvertices)
Helps to identify the base vertex of the given polyline.
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 setup_boundary_coordinates(const unsigned &b)
Setup boundary coordinate on boundary b. Boundary coordinate increases continously along polygonal bo...
void copy_connection_information(TriangleMeshCurveSection *input_curve_pt, TriangleMeshCurveSection *output_curve_pt)
Helper function to copy the connection information from the input curve(polyline or curviline) to the...
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...
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.
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...
Vector< Vector< double > > & boundary_segment_initial_coordinate(const unsigned &b)
Return the initial coordinates for the segments that are part of a boundary.
Vector< double > & boundary_initial_zeta_coordinate(const unsigned &b)
Return the initial zeta coordinate for the boundary.
Vector< double > & boundary_final_coordinate(const unsigned &b)
Return the final coordinates for the boundary.
unsigned nregion_attribute()
Return the number of attributes used in the mesh.
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 build_triangulateio(Vector< TriangleMeshPolygon * > &outer_polygons_pt, Vector< TriangleMeshPolygon * > &internal_polygons_pt, Vector< TriangleMeshOpenCurve * > &open_curves_pt, Vector< Vector< double >> &extra_holes_coordinates, std::map< unsigned, Vector< double >> ®ions_coordinates, std::map< unsigned, double > ®ions_areas, TriangulateIO &triangulate_io)
Create TriangulateIO object from outer boundaries, internal boundaries, and open curves....
FiniteElement * region_element_pt(const unsigned &i, const unsigned &e)
Return the e-th element in the i-th region.
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 ...
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...
Vector< double > & boundary_coordinate_limits(const unsigned &b)
Return access to the coordinate limits associated with the geometric object associated with boundary ...
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...
std::map< unsigned, Vector< double > > Boundary_final_coordinate
Stores the final coordinates for the boundary.
std::map< unsigned, Vector< double > > Boundary_initial_coordinate
Stores the initial coordinates for the boundary.
std::set< TriangleMeshPolygon * > Free_polygon_pt
A set that contains the polygons created by this object therefore it is necessary to free their assoc...
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)
std::map< unsigned, Vector< double > > Boundary_final_zeta_coordinate
Stores the final zeta coordinate for the boundary.
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....
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...
bool Immersed_rigid_body_triangle_mesh_polygon_used
std::map< unsigned, Vector< double > > & boundary_final_zeta_coordinate()
Return direct access to the final zeta coordinates of a boundary.
TriangleMeshCurveSection * curviline_to_polyline(TriangleMeshCurviLine *&curviline_pt, unsigned &bnd_id)
Helper function that creates the associated polyline representation for curvilines.
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....
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...
std::map< unsigned, TriangleMeshCurveSection * > Boundary_curve_section_pt
A map that stores the associated curve section of the specified boundary id.
bool is_point_inside_polygon_helper(Vector< Vector< double >> polygon_vertices, Vector< double > point)
Helper function that checks if a given point is inside a polygon (a set of sorted vertices that conne...
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 nregion_element(const unsigned &i)
Return the number of elements in the i-th region.
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_...
std::map< unsigned, Vector< double > > & boundary_coordinate_limits()
Return access to the vector of boundary coordinates associated with each geometric object.
std::map< unsigned, Vector< double > > & boundary_initial_coordinate()
Return direct access to the initial coordinates of a boundary.
UnstructuredTwoDMeshGeometryBase()
Empty constructor.
void flush_boundary_segment_node(const unsigned &b)
Flush the boundary segment node storage.
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.
unsigned long nboundary_segment_node(const unsigned &b, const unsigned &s)
Return the number of nodes associated with a given segment of a boundary.
void operator=(const UnstructuredTwoDMeshGeometryBase &)=delete
Broken assignment operator.
Vector< double > & boundary_segment_initial_zeta(const unsigned &b)
Return the initial zeta for the segments that are part of a boundary.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
double Tolerable_error
Acceptable discrepancy for mismatch in vertex coordinates. In paranoid mode, the code will die if the...
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)
Create a triangulateio data file from ele node and poly files. This is used if the mesh is generated ...
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.
void initialise_triangulateio(TriangulateIO &triangle_io)
Initialise TriangulateIO structure.
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 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.
void clear_triangulateio(TriangulateIO &triangulate_io, const bool &clear_hole_data)
Clear TriangulateIO structure.
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...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
Structure for Boundary Informations.
FiniteElement * FE_pt
Pointer to bulk finite element.
unsigned Boundary
Boundary ID.
The Triangle data structure, modified from the triangle.h header supplied with triangle 1....
double * pointlist
Pointer to list of points x coordinate followed by y coordinate.
int numberoftriangleattributes
int * pointmarkerlist
Pointer to list of point markers.
double * trianglearealist
double * triangleattributelist
double * pointattributelist
Pointer to list of point attributes.
int numberofpointattributes
Data structure to store the base vertex info, initial or final vertex in the polylines have an associ...
bool has_base_vertex_assigned
Data structure filled when the connection matrix is created, for each polyline, there are two vertex_...
unsigned boundary_id_to_connect
unsigned boundary_chunk_to_connect
unsigned vertex_number_to_connect