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