27 #ifndef OOMPH_REFINEABLE_TETGEN_MESH_TEMPLATE_CC
28 #define OOMPH_REFINEABLE_TETGEN_MESH_TEMPLATE_CC
32 #include <oomph-lib-config.h>
37 #include "../generic/sample_point_parameters.h"
38 #include "../generic/mesh_as_geometric_object.h"
39 #include "../generic/projection.h"
40 #include "../generic/face_element_as_geometric_object.h"
48 template<
class ELEMENT>
50 TetMeshFacetedSurface*& faceted_surface_pt)
57 std::list<Node*> new_vertex_nodes;
59 std::list<std::pair<Vector<unsigned>,
unsigned>> new_facet_list;
62 unsigned n_old_facet = faceted_surface_pt->nfacet();
63 for (
unsigned f = 0; f < n_old_facet; f++)
68 unsigned bound = faceted_surface_pt->one_based_facet_boundary_id(f) - 1;
73 Mesh* face_mesh_pt =
new Mesh;
74 this->
template build_face_mesh<ELEMENT, FaceElementAsGeomObject>(
80 unsigned n_face_element = face_mesh_pt->nelement();
81 for (
unsigned e = 0; e < n_face_element; e++)
84 FaceElementAsGeomObject<ELEMENT>* el_pt =
85 dynamic_cast<FaceElementAsGeomObject<ELEMENT>*
>(
86 face_mesh_pt->element_pt(e));
89 el_pt->set_boundary_number_in_bulk_mesh(bound);
97 Vector<unsigned> new_local_facet(3);
101 for (
unsigned e = 0; e < n_face_element; ++e)
104 FiniteElement
const* elem_pt = face_mesh_pt->finite_element_pt(e);
107 unsigned n_vertex_node = 3;
108 for (
unsigned n = 0; n < n_vertex_node; n++)
111 Node*
const nod_pt = elem_pt->node_pt(n);
113 unsigned counter = 0;
114 bool found_it =
false;
115 for (std::list<Node*>::iterator it = new_vertex_nodes.begin();
116 it != new_vertex_nodes.end();
122 new_local_facet[n] = counter;
132 new_vertex_nodes.push_back(nod_pt);
134 new_local_facet[n] = counter;
139 new_facet_list.push_back(std::make_pair(new_local_facet, bound + 1));
153 unsigned n_facet_vertex = new_vertex_nodes.size();
155 Vector<Node*> facet_nodes_pt(n_facet_vertex);
157 for (std::list<Node*>::iterator it = new_vertex_nodes.begin();
158 it != new_vertex_nodes.end();
161 facet_nodes_pt[count] = *it;
171 unsigned n_facet = new_facet_list.size();
172 Vector<Vector<unsigned>> new_facet(n_facet);
173 Vector<unsigned> new_facet_boundary_id(n_facet);
175 for (std::list<std::pair<Vector<unsigned>,
unsigned>>::iterator it =
176 new_facet_list.begin();
177 it != new_facet_list.end();
180 new_facet[count] = (*it).first;
181 new_facet_boundary_id[count] = (*it).second;
185 for (
unsigned f = 0; f < n_facet; f++)
187 for (
unsigned i = 0; i < 3; i++)
189 oomph_info << new_facet[f][i] <<
" ";
192 oomph_info << new_facet_boundary_id[f] <<
"\n";
196 delete faceted_surface_pt;
197 faceted_surface_pt =
new TetMeshFacetedClosedSurfaceForRemesh(
198 facet_nodes_pt, new_facet, new_facet_boundary_id);
201 this->setup_reverse_lookup_schemes_for_faceted_surface(faceted_surface_pt);
204 Vector<double> inner_point(3, 0.0);
205 for (
unsigned n = 0; n < n_facet_vertex; n++)
207 for (
unsigned i = 0; i < 3; i++)
209 inner_point[i] += facet_nodes_pt[n]->x(i);
213 for (
unsigned i = 0; i < 3; i++)
215 inner_point[i] /= n_facet_vertex;
219 dynamic_cast<TetMeshFacetedClosedSurface*
>(faceted_surface_pt)
220 ->set_hole_for_tetgen(inner_point);
226 template<
class ELEMENT>
230 unsigned n_hole = this->Internal_surface_pt.size();
231 for (
unsigned ihole = 0; ihole < n_hole; ihole++)
238 this->update_faceted_surface_using_face_mesh(
239 this->Internal_surface_pt[ihole]);
245 template<
class ELEMENT>
250 if (!Boundary_coordinate_exists[b])
252 oomph_info <<
"Not snapping nodes on boundary " << b
253 <<
" because no boundary coordinate has been set up.\n";
270 Mesh* face_mesh_pt =
new Mesh;
271 this->
template build_face_mesh<ELEMENT, FaceElementAsGeomObject>(
277 unsigned n_face_element = face_mesh_pt->nelement();
278 for (
unsigned e = 0; e < n_face_element; e++)
281 FaceElementAsGeomObject<ELEMENT>* el_pt =
282 dynamic_cast<FaceElementAsGeomObject<ELEMENT>*
>(
283 face_mesh_pt->element_pt(e));
286 el_pt->set_boundary_number_in_bulk_mesh(b);
292 Mesh* new_face_mesh_pt =
new Mesh;
293 new_mesh_pt->template build_face_mesh<ELEMENT, FaceElementAsGeomObject>(
294 b, new_face_mesh_pt);
296 std::ostringstream filestring;
297 filestring <<
"old_mesh_boundary" << b <<
".dat";
298 face_mesh_pt->output(filestring.str().c_str());
300 filestring <<
"new_mesh_boundary" << b <<
".dat";
301 new_face_mesh_pt->output(filestring.str().c_str());
303 Vector<double> b_coo(2);
304 std::cout <<
"OLD---\n";
306 unsigned n_tmp_node = this->nboundary_node(b);
307 for (
unsigned n = 0; n < n_tmp_node; ++n)
309 Node*
const nod_pt = this->boundary_node_pt(b, n);
310 nod_pt->get_coordinates_on_boundary(b, b_coo);
311 std::cout << nod_pt->x(0) <<
" " << nod_pt->x(1) <<
" " << nod_pt->x(2)
312 <<
" " << b_coo[0] <<
" " << b_coo[1] <<
"\n";
315 std::cout <<
"NEW-----------\n";
317 n_tmp_node = new_mesh_pt->nboundary_node(b);
318 for (
unsigned n = 0; n < n_tmp_node; ++n)
320 Node*
const nod_pt = new_mesh_pt->boundary_node_pt(b, n);
321 nod_pt->get_coordinates_on_boundary(b, b_coo);
322 std::cout << nod_pt->x(0) <<
" " << nod_pt->x(1) <<
" " << nod_pt->x(2)
323 <<
" " << b_coo[0] <<
" " << b_coo[1] <<
"\n";
329 MeshAsGeomObject* mesh_geom_obj_pt =
new MeshAsGeomObject(face_mesh_pt);
333 Vector<double> new_x(3);
334 Vector<double> b_coord(2);
335 unsigned n_new_boundary_node = new_mesh_pt->nboundary_node(b);
336 for (
unsigned n = 0; n < n_new_boundary_node; n++)
339 Node*
const nod_pt = new_mesh_pt->boundary_node_pt(b, n);
340 nod_pt->get_coordinates_on_boundary(b, b_coord);
342 mesh_geom_obj_pt->position(b_coord, new_x);
344 for (
unsigned i = 0; i < 3; i++)
346 nod_pt->x(i) = new_x[i];
352 delete mesh_geom_obj_pt;
353 face_mesh_pt->flush_element_and_node_storage();
357 unsigned n_element = new_mesh_pt->nboundary_element(b);
361 TElement<3, 2> dummy_four_node_element;
363 TElement<3, 3> dummy_ten_node_element;
365 Vector<double> x_new(3);
366 for (
unsigned n = 0; n < 4; n++)
368 dummy_four_node_element.construct_node(n);
370 for (
unsigned n = 0; n < 10; n++)
372 dummy_ten_node_element.construct_node(n);
374 for (
unsigned e = 0; e < n_element; e++)
378 dynamic_cast<ELEMENT*
>(new_mesh_pt->boundary_element_pt(b, e));
381 const unsigned n_node = elem_pt->nnode();
386 for (
unsigned n = 0; n < 4; n++)
388 for (
unsigned i = 0; i < 3; i++)
390 dummy_four_node_element.node_pt(n)->x(i) =
391 elem_pt->node_pt(n)->x(i);
396 for (
unsigned n = 4; n < 10; n++)
400 if (!elem_pt->node_pt(n)->is_on_boundary())
402 elem_pt->local_coordinate_of_node(n, s);
403 dummy_four_node_element.interpolated_x(s, x_new);
404 for (
unsigned i = 0; i < 3; i++)
406 elem_pt->node_pt(n)->x(i) = x_new[i];
416 for (
unsigned n = 0; n < 10; n++)
418 for (
unsigned i = 0; i < 3; i++)
420 dummy_ten_node_element.node_pt(n)->x(i) =
421 elem_pt->node_pt(n)->x(i);
426 for (
unsigned n = 10; n < n_node; n++)
430 if (!elem_pt->node_pt(n)->is_on_boundary())
432 elem_pt->local_coordinate_of_node(n, s);
433 dummy_ten_node_element.interpolated_x(s, x_new);
434 for (
unsigned i = 0; i < 3; i++)
436 elem_pt->node_pt(n)->x(i) = x_new[i];
449 template<
class ELEMENT>
452 double t_start = 0.0;
454 t_start = TimingHelpers::timer();
458 Vector<double> target_size(elem_error.size());
459 double max_edge_ratio =
460 this->compute_volume_target(elem_error, target_size);
462 unsigned n = target_size.size();
463 double max_size = 0.0;
464 double min_size = DBL_MAX;
465 for (
unsigned e = 0; e < n; e++)
467 if (target_size[e] > max_size) max_size = target_size[e];
468 if (target_size[e] < min_size) min_size = target_size[e];
471 oomph_info <<
"Maximum target size: " << max_size << std::endl;
472 oomph_info <<
"Minimum target size: " << min_size << std::endl;
473 oomph_info <<
"Number of elements to be refined " << this->Nrefined
475 oomph_info <<
"Number of elements to be unrefined " << this->Nunrefined
477 oomph_info <<
"Max edge ratio " << max_edge_ratio << std::endl;
479 double orig_max_size, orig_min_size;
480 this->max_and_min_element_size(orig_max_size, orig_min_size);
481 oomph_info <<
"Max/min element size in original mesh: " << orig_max_size
482 <<
" " << orig_min_size << std::endl;
486 <<
"adapt: Time for getting volume targets : "
487 << TimingHelpers::timer() - t_start <<
" sec " << std::endl;
496 bool inner_boundary_update_necessary =
false;
499 if ((Nrefined > 0) || (Nunrefined > this->max_keep_unrefined()) ||
500 (max_edge_ratio > this->max_permitted_edge_ratio()))
502 if (!((Nrefined > 0) || (Nunrefined > max_keep_unrefined())))
504 oomph_info <<
"Mesh regeneration triggered by edge ratio criterion\n";
508 if (inner_boundary_update_necessary)
510 this->surface_remesh_for_inner_hole_boundaries();
516 const unsigned n_boundary = this->nboundary();
517 for (
unsigned b = 0; b < n_boundary; ++b)
521 this->
template setup_boundary_coordinates<ELEMENT>(b);
528 t_start = TimingHelpers::timer();
532 SolidMesh* solid_mesh_pt =
dynamic_cast<SolidMesh*
>(
this);
539 if (solid_mesh_pt != 0)
545 this->Outer_boundary_pt,
546 this->Internal_surface_pt,
548 this->Time_stepper_pt,
549 this->Use_attributes,
550 this->Corner_elements_must_be_split);
555 this->Outer_boundary_pt,
556 this->Internal_surface_pt,
558 this->Time_stepper_pt,
559 this->Use_attributes,
560 this->Corner_elements_must_be_split);
566 <<
"adapt: Time for building temp mesh : "
567 << TimingHelpers::timer() - t_start <<
" sec " << std::endl;
589 tetgenio* tmp_new_tetgenio_pt = tmp_new_mesh_pt->
tetgenio_pt();
594 bool use_eulerian_coords =
false;
595 if (solid_mesh_pt != 0)
597 use_eulerian_coords =
true;
600 #ifdef OOMPH_HAS_CGAL
603 CGALSamplePointContainerParameters cgal_params(
this);
604 if (use_eulerian_coords)
606 cgal_params.enable_use_eulerian_coordinates_during_setup();
608 MeshAsGeomObject* mesh_geom_obj_pt =
new MeshAsGeomObject(&cgal_params);
612 std::ostringstream error_message;
613 error_message <<
"Non-CGAL-based target size transfer not implemented.\n";
615 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
635 std::map<GeneralisedElement*, unsigned> element_number;
636 unsigned nelem = this->nelement();
637 for (
unsigned e = 0; e < nelem; e++)
639 element_number[this->element_pt(e)] = e;
655 unsigned nelem = tmp_new_mesh_pt->nelement();
659 Vector<double> new_transferred_target_size(nelem, 0.0);
660 for (
unsigned e = 0; e < nelem; e++)
663 dynamic_cast<ELEMENT*
>(tmp_new_mesh_pt->element_pt(e));
664 unsigned nint = el_pt->integral_pt()->nweight();
665 for (
unsigned ipt = 0; ipt < nint; ipt++)
669 for (
unsigned i = 0; i < 3; i++)
671 s[i] = el_pt->integral_pt()->knot(ipt, i);
675 el_pt->interpolated_x(s, x);
681 GeomObject* geom_obj_pt = 0;
682 unsigned max_sample_points = 5;
683 dynamic_cast<CGALSamplePointContainer*
>(
684 mesh_geom_obj_pt->sample_point_container_pt())
685 ->limited_locate_zeta(x, max_sample_points, geom_obj_pt, s);
687 if (geom_obj_pt == 0)
689 std::stringstream error_message;
690 error_message <<
"Limited locate zeta failed for zeta = [ "
691 << x[0] <<
" " << x[1] <<
" " << x[2]
692 <<
" ]. Makes no sense!\n";
693 throw OomphLibError(error_message.str(),
694 OOMPH_CURRENT_FUNCTION,
695 OOMPH_EXCEPTION_LOCATION);
700 FiniteElement* fe_pt =
dynamic_cast<FiniteElement*
>(geom_obj_pt);
704 std::stringstream error_message;
705 error_message <<
"Cast to FE for GeomObject returned by "
706 "limited locate zeta failed for zeta = [ "
707 << x[0] <<
" " << x[1] <<
" " << x[2]
708 <<
" ]. Makes no sense!\n";
709 throw OomphLibError(error_message.str(),
710 OOMPH_CURRENT_FUNCTION,
711 OOMPH_EXCEPTION_LOCATION);
718 double tg_size = target_size[element_number[fe_pt]];
725 if (new_transferred_target_size[e] != 0.0)
727 new_transferred_target_size[e] =
728 std::min(new_transferred_target_size[e], tg_size);
732 new_transferred_target_size[e] = tg_size;
742 std::ostringstream error_message;
744 <<
"Non-CGAL-based target size transfer not implemented.\n";
745 throw OomphLibError(error_message.str(),
746 OOMPH_CURRENT_FUNCTION,
747 OOMPH_EXCEPTION_LOCATION);
796 const bool output_target_sizes =
false;
797 if (output_target_sizes)
799 unsigned length = new_transferred_target_size.size();
800 for (
unsigned u = 0; u < length; u++)
802 oomph_info <<
"Element" << u
803 <<
",target size: " << new_transferred_target_size[u]
811 unsigned n_ele_need_refinement_iter = 0;
821 std::ofstream target_sizes_file;
823 sprintf(filename,
"target_sizes%i.dat", iter);
824 if (output_target_sizes)
826 target_sizes_file.open(filename);
829 const unsigned nel_new = tmp_new_mesh_pt->nelement();
830 Vector<double> new_target_size(nel_new);
831 for (
unsigned e = 0; e < nel_new; e++)
834 FiniteElement* f_ele_pt = tmp_new_mesh_pt->finite_element_pt(e);
837 const double new_size = new_transferred_target_size[e];
840 std::ostringstream error_stream;
842 <<
"This shouldn't happen! Element whose centroid is at "
843 << (f_ele_pt->node_pt(0)->x(0) + f_ele_pt->node_pt(1)->x(0) +
844 f_ele_pt->node_pt(2)->x(0) + f_ele_pt->node_pt(3)->x(0)) /
847 << (f_ele_pt->node_pt(0)->x(1) + f_ele_pt->node_pt(1)->x(1) +
848 f_ele_pt->node_pt(2)->x(1) + f_ele_pt->node_pt(3)->x(1)) /
851 << (f_ele_pt->node_pt(0)->x(2) + f_ele_pt->node_pt(1)->x(2) +
852 f_ele_pt->node_pt(2)->x(2) + f_ele_pt->node_pt(3)->x(2)) /
855 <<
" has no target size assigned\n";
856 throw OomphLibError(error_stream.str(),
857 OOMPH_CURRENT_FUNCTION,
858 OOMPH_EXCEPTION_LOCATION);
864 new_target_size[e] = new_size;
865 if (new_target_size[e] < f_ele_pt->size() / 4.0)
867 new_target_size[e] = f_ele_pt->size() / 4.0;
880 if (output_target_sizes)
882 target_sizes_file <<
"ZONE N=4, E=1, F=FEPOINT, ET=TETRAHEDRON\n";
883 for (
unsigned j = 0; j < 4; j++)
885 target_sizes_file << f_ele_pt->node_pt(j)->x(0) <<
" "
886 << f_ele_pt->node_pt(j)->x(1) <<
" "
887 << f_ele_pt->node_pt(j)->x(2) <<
" "
888 << new_size <<
" " << new_target_size[e]
891 target_sizes_file <<
"1 2 3 4\n";
913 n_ele_need_refinement_iter++;
921 if (output_target_sizes)
923 target_sizes_file.close();
929 <<
"All size adjustments accommodated by max. permitted size"
930 <<
" reduction during iter " << iter <<
"\n";
934 oomph_info <<
"NOT all size adjustments accommodated by max. "
935 <<
"permitted size reduction during iter " << iter
941 <<
"\n\n\n==================================================\n"
942 <<
"==================================================\n"
943 <<
"==================================================\n"
944 <<
"==================================================\n"
949 <<
"adapt: Time for new_target_size[.] : "
950 << TimingHelpers::timer() - t_start <<
" sec " << std::endl;
962 t_start = TimingHelpers::timer();
966 if (solid_mesh_pt != 0)
977 this->Outer_boundary_pt,
978 this->Internal_surface_pt,
979 this->Time_stepper_pt,
980 this->Use_attributes);
988 this->Outer_boundary_pt,
989 this->Internal_surface_pt,
990 this->Time_stepper_pt,
991 this->Use_attributes);
996 <<
"adapt: Time for new_mesh_pt : "
997 << TimingHelpers::timer() - t_start <<
" sec " << std::endl;
1009 unsigned nnod = tmp_new_mesh_pt->nnode();
1010 if (nnod == new_mesh_pt->nnode())
1012 unsigned nel = tmp_new_mesh_pt->nelement();
1013 if (nel == new_mesh_pt->nelement())
1015 bool nodes_identical =
true;
1016 for (
unsigned j = 0; j < nnod; j++)
1018 bool coords_identical =
true;
1019 for (
unsigned i = 0; i < 3; i++)
1021 if (new_mesh_pt->node_pt(j)->x(i) !=
1022 tmp_new_mesh_pt->node_pt(j)->x(i))
1024 coords_identical =
false;
1027 if (!coords_identical)
1029 nodes_identical =
false;
1033 if (nodes_identical)
1042 delete tmp_new_mesh_pt;
1047 tmp_new_mesh_pt = new_mesh_pt;
1067 if (!Projection_is_disabled)
1070 t_start = TimingHelpers::timer();
1075 ProjectionProblem<ELEMENT>* project_problem_pt =
1076 new ProjectionProblem<ELEMENT>;
1077 project_problem_pt->mesh_pt() = new_mesh_pt;
1078 project_problem_pt->project(
this);
1079 delete project_problem_pt;
1083 <<
"adapt: Time for project soln onto new mesh : "
1084 << TimingHelpers::timer() - t_start <<
" sec " << std::endl;
1089 t_start = TimingHelpers::timer();
1096 unsigned nnod = nnode();
1097 for (
unsigned j = nnod; j > 0; j--)
1099 delete Node_pt[j - 1];
1102 unsigned nel = nelement();
1103 for (
unsigned e = nel; e > 0; e--)
1105 delete Element_pt[e - 1];
1106 Element_pt[e - 1] = 0;
1111 nnod = new_mesh_pt->nnode();
1112 Node_pt.resize(nnod);
1113 nel = new_mesh_pt->nelement();
1114 Element_pt.resize(nel);
1115 for (
unsigned j = 0; j < nnod; j++)
1117 Node_pt[j] = new_mesh_pt->node_pt(j);
1119 for (
unsigned e = 0; e < nel; e++)
1121 Element_pt[e] = new_mesh_pt->element_pt(e);
1125 unsigned nbound = new_mesh_pt->nboundary();
1126 Boundary_element_pt.resize(nbound);
1127 Face_index_at_boundary.resize(nbound);
1128 Boundary_node_pt.resize(nbound);
1129 for (
unsigned b = 0; b < nbound; b++)
1131 unsigned nel = new_mesh_pt->nboundary_element(b);
1132 Boundary_element_pt[b].resize(nel);
1133 Face_index_at_boundary[b].resize(nel);
1134 for (
unsigned e = 0; e < nel; e++)
1136 Boundary_element_pt[b][e] = new_mesh_pt->boundary_element_pt(b, e);
1137 Face_index_at_boundary[b][e] =
1138 new_mesh_pt->face_index_at_boundary(b, e);
1140 unsigned nnod = new_mesh_pt->nboundary_node(b);
1141 Boundary_node_pt[b].resize(nnod);
1142 for (
unsigned j = 0; j < nnod; j++)
1144 Boundary_node_pt[b][j] = new_mesh_pt->boundary_node_pt(b, j);
1149 unsigned n_region = new_mesh_pt->nregion();
1155 this->Region_element_pt.resize(n_region);
1156 this->Region_attribute.resize(n_region);
1157 for (
unsigned i = 0; i < n_region; i++)
1160 this->Region_attribute[i] = new_mesh_pt->region_attribute(i);
1163 unsigned r = this->Region_attribute[i];
1164 unsigned n_region_element = new_mesh_pt->nregion_element(r);
1165 this->Region_element_pt[i].resize(n_region_element);
1166 for (
unsigned e = 0; e < n_region_element; e++)
1168 this->Region_element_pt[i][e] =
1169 new_mesh_pt->region_element_pt(r, e);
1174 this->Boundary_region_element_pt.resize(nbound);
1175 this->Face_index_region_at_boundary.resize(nbound);
1178 for (
unsigned b = 0; b < nbound; ++b)
1181 for (
unsigned i = 0; i < n_region; ++i)
1183 unsigned r = this->Region_attribute[i];
1185 unsigned n_boundary_el_in_region =
1186 new_mesh_pt->nboundary_element_in_region(b, r);
1187 if (n_boundary_el_in_region > 0)
1190 this->Boundary_region_element_pt[b][r].resize(
1191 n_boundary_el_in_region);
1192 this->Face_index_region_at_boundary[b][r].resize(
1193 n_boundary_el_in_region);
1196 for (
unsigned e = 0; e < n_boundary_el_in_region; ++e)
1198 this->Boundary_region_element_pt[b][r][e] =
1199 new_mesh_pt->boundary_element_in_region_pt(b, r, e);
1200 this->Face_index_region_at_boundary[b][r][e] =
1201 new_mesh_pt->face_index_at_boundary_in_region(b, r, e);
1210 this->set_deep_copy_tetgenio_pt(new_mesh_pt->
tetgenio_pt());
1213 new_mesh_pt->flush_element_and_node_storage();
1221 <<
"adapt: Time for moving nodes etc. to actual mesh : "
1222 << TimingHelpers::timer() - t_start <<
" sec " << std::endl;
1226 if (solid_mesh_pt != 0)
1229 std::stringstream error_message;
1231 <<
"Lagrangian coordinates are currently not projected but are\n"
1232 <<
"are re-set during adaptation. This is not appropriate for\n"
1233 <<
"real solid mechanics problems!\n";
1234 OomphLibWarning(error_message.str(),
1235 OOMPH_CURRENT_FUNCTION,
1236 OOMPH_EXCEPTION_LOCATION);
1239 dynamic_cast<SolidMesh*
>(
this)->set_lagrangian_nodal_coordinates();
1244 this->max_and_min_element_size(max_area, min_area);
1245 oomph_info <<
"Max/min element size in adapted mesh: " << max_area <<
" "
1246 << min_area << std::endl;
1250 oomph_info <<
"Not enough benefit in adaptation.\n";
////////////////////////////////////////////////////////////////////////// //////////////////////////...
void surface_remesh_for_inner_hole_boundaries()
Generate a new faceted representation of the inner hole boundaries.
void update_faceted_surface_using_face_mesh(TetMeshFacetedSurface *&faceted_surface_pt)
Helper function that updates the input faceted surface by using the flattened elements from FaceMesh(...
void snap_nodes_onto_boundary(RefineableTetgenMesh< ELEMENT > *&new_mesh_pt, const unsigned &b)
Snap the boundary nodes onto any curvilinear boundaries.
void adapt(const Vector< double > &elem_error)
Adapt mesh, based on elemental error provided.
tetgenio *& tetgenio_pt()
Access to the triangulateio representation of the mesh.
////////////////////////////////////////////////////////////////////// //////////////////////////////...