27 #ifndef OOMPH_TET_MESH_HEADER
28 #define OOMPH_TET_MESH_HEADER
32 #include <oomph-lib-config.h>
61 std::ostringstream error_stream;
62 error_stream <<
"TetMeshVertex should only be used in 3D!\n"
63 <<
"Your Vector of coordinates, contains data for "
64 <<
x.size() <<
"-dimensional coordinates." << std::endl;
74 const unsigned n_dim = node_pt->
ndim();
78 std::ostringstream error_stream;
79 error_stream <<
"TetMeshVertex should only be used in 3D!\n"
80 <<
"Your Node contains data for " << n_dim
81 <<
"-dimensional coordinates." << std::endl;
89 for (
unsigned i = 0;
i < n_dim; ++
i)
100 if (
zeta.size() != 2)
102 std::ostringstream error_stream;
104 <<
"TetMeshVertex should only be used in 3D!\n"
105 <<
"Your Vector of intrinisic coordinates, contains data for "
106 <<
zeta.size() <<
"-dimensional coordinates but should be 2!"
124 double x(
const unsigned&
i)
const
218 for (
unsigned j = 0;
j < nv;
j++)
250 const unsigned& one_based_region_id)
266 outfile <<
"ZONE I=" <<
n + 1 << std::endl;
267 for (
unsigned j = 0;
j <
n;
j++)
333 return Facet_pt[
j]->one_based_boundary_id();
395 for (
unsigned j = 0;
j <
n;
j++)
405 std::ofstream outfile;
418 const double& zeta_boundary,
422 zeta_vertex[0] =
Facet_pt[facet_id]->vertex_pt(0)->zeta_in_geom_object();
423 zeta_vertex[1] =
Facet_pt[facet_id]->vertex_pt(1)->zeta_in_geom_object();
424 zeta[0] = zeta_vertex[0][0] +
425 (zeta_vertex[1][0] - zeta_vertex[0][0]) * zeta_boundary;
426 zeta[1] = zeta_vertex[0][1] +
427 (zeta_vertex[1][1] - zeta_vertex[0][1]) * zeta_boundary;
437 const double& zeta_boundary,
441 zeta_vertex[0] =
Facet_pt[facet_id]->vertex_pt(1)->zeta_in_geom_object();
442 zeta_vertex[1] =
Facet_pt[facet_id]->vertex_pt(2)->zeta_in_geom_object();
443 zeta[0] = zeta_vertex[0][0] +
444 (zeta_vertex[1][0] - zeta_vertex[0][0]) * zeta_boundary;
445 zeta[1] = zeta_vertex[0][1] +
446 (zeta_vertex[1][1] - zeta_vertex[0][1]) * zeta_boundary;
456 const double& zeta_boundary,
460 zeta_vertex[0] =
Facet_pt[facet_id]->vertex_pt(2)->zeta_in_geom_object();
461 zeta_vertex[1] =
Facet_pt[facet_id]->vertex_pt(0)->zeta_in_geom_object();
462 zeta[0] = zeta_vertex[0][0] +
463 (zeta_vertex[1][0] - zeta_vertex[0][0]) * zeta_boundary;
464 zeta[1] = zeta_vertex[0][1] +
465 (zeta_vertex[1][1] - zeta_vertex[0][1]) * zeta_boundary;
507 for (
unsigned f = 0;
f < nf;
f++)
511 for (
unsigned v = 0;
v < nv;
v++)
514 for (
unsigned j = 0;
j < nv_overall;
j++)
569 const unsigned&
i)
const
586 std::make_pair(region_point, region_id));
701 template<
class ELEMENT>
705 std::ofstream some_file;
708 bool switch_normal =
false;
709 this->setup_boundary_coordinates<ELEMENT>(
b, switch_normal, some_file);
732 template<
class ELEMENT>
734 const bool& switch_normal)
737 std::ofstream some_file;
739 this->setup_boundary_coordinates<ELEMENT>(
b, switch_normal, some_file);
763 template<
class ELEMENT>
765 const bool& switch_normal,
766 std::ofstream& outfile);
787 template<
class ELEMENT>
791 bool switch_normal =
false;
792 this->setup_boundary_coordinates<ELEMENT>(
b, switch_normal, outfile);
798 const unsigned&
r)
const
802 std::map<unsigned, Vector<FiniteElement*>>::const_iterator it =
806 return (it->second).size();
818 const unsigned&
e)
const
821 std::map<unsigned, Vector<FiniteElement*>>::const_iterator it =
825 return (it->second)[
e];
836 const unsigned&
e)
const
839 std::map<unsigned, Vector<int>>::const_iterator it =
843 return (it->second)[
e];
847 std::ostringstream error_message;
848 error_message <<
"Face indices not set up for boundary " <<
b
849 <<
" in region " <<
r <<
"\n";
850 error_message <<
"This probably means that the boundary is not "
851 "adjacent to region\n";
871 for (
unsigned i = 0;
i <
n;
i++)
879 std::ostringstream error_message;
880 error_message <<
"Region attributes should be unsigneds because we \n"
881 <<
"only use them to set region ids\n";
917 for (
unsigned i = 0;
i <
n;
i++)
925 std::ostringstream error_message;
926 error_message <<
"Region attributes should be unsigneds because we \n"
927 <<
"only use the to set region ids\n";
961 template<
class ELEMENT>
965 const bool& switch_normal,
978 template<
class ELEMENT>
982 const bool& switch_normal)
987 snap_to_quadratic_surface<ELEMENT>(
988 boundary_id, quadratic_surface_file_name, switch_normal, doc_info);
1000 template<
class ELEMENT>
1009 std::ofstream outfile;
1053 std::map<unsigned, Vector<Vector<double>>>
1091 template<
class ELEMENT>
1093 const bool& switch_normal,
1094 std::ofstream& outfile)
1096 Node* lower_left_node_pt = 0;
1097 Node* upper_right_node_pt = 0;
1111 f_pt = (*it).second;
1124 bool vertices_are_in_same_plane =
true;
1125 for (
unsigned do_for_real = 0; do_for_real < 2; do_for_real++)
1136 for (
unsigned e = 0;
e < nel;
e++)
1145 face_el_pt.push_back(
1149 if (outfile.is_open())
1151 face_el_pt[face_el_pt.size() - 1]->output(outfile);
1161 for (
unsigned j = 0;
j < nnod;
j++)
1168 if (nod_pt->
x(2) < lower_left_node_pt->
x(2))
1170 lower_left_node_pt = nod_pt;
1173 else if (nod_pt->
x(2) == lower_left_node_pt->
x(2))
1176 if (nod_pt->
x(1) < lower_left_node_pt->
x(1))
1178 lower_left_node_pt = nod_pt;
1181 else if (nod_pt->
x(1) == lower_left_node_pt->
x(1))
1184 if (nod_pt->
x(0) < lower_left_node_pt->
x(0))
1186 lower_left_node_pt = nod_pt;
1193 if (nod_pt->
x(2) > upper_right_node_pt->
x(2))
1195 upper_right_node_pt = nod_pt;
1198 else if (nod_pt->
x(2) == upper_right_node_pt->
x(2))
1201 if (nod_pt->
x(1) > upper_right_node_pt->
x(1))
1203 upper_right_node_pt = nod_pt;
1206 else if (nod_pt->
x(1) == upper_right_node_pt->
x(1))
1209 if (nod_pt->
x(0) > upper_right_node_pt->
x(0))
1211 upper_right_node_pt = nod_pt;
1228 b0[0] = upper_right_node_pt->
x(0) - lower_left_node_pt->
x(0);
1229 b0[1] = upper_right_node_pt->
x(1) - lower_left_node_pt->
x(1);
1230 b0[2] = upper_right_node_pt->
x(2) - lower_left_node_pt->
x(2);
1234 1.0 /
sqrt(b0[0] * b0[0] + b0[1] * b0[1] + b0[2] * b0[2]);
1235 b0[0] *= inv_length;
1236 b0[1] *= inv_length;
1237 b0[2] *= inv_length;
1248 ->outer_unit_normal(
s,
normal);
1264 normal[0] = t1y * t2z - t1z * t2y;
1265 normal[1] = t1z * t2x - t1x * t2z;
1266 normal[2] = t1x * t2y - t1y * t2x;
1288 for (
unsigned e = 0;
e < nel;
e++)
1293 ->outer_unit_normal(
s, my_normal);
1296 double dot_prod =
normal[0] * my_normal[0] +
1300 double error =
abs(dot_prod) - 1.0;
1303 vertices_are_in_same_plane =
false;
1308 if (vertices_are_in_same_plane)
1320 for (
unsigned j = 0;
j < nnod;
j++)
1327 delta[0] = nod_pt->
x(0) - lower_left_node_pt->
x(0);
1328 delta[1] = nod_pt->
x(1) - lower_left_node_pt->
x(1);
1329 delta[2] = nod_pt->
x(2) - lower_left_node_pt->
x(2);
1342 double error =
pow(lower_left_node_pt->
x(0) +
zeta[0] * b0[0] +
1343 zeta[1] * b1[0] - nod_pt->
x(0),
1345 pow(lower_left_node_pt->
x(1) +
zeta[0] * b0[1] +
1346 zeta[1] * b1[1] - nod_pt->
x(1),
1348 pow(lower_left_node_pt->
x(2) +
zeta[0] * b0[2] +
1349 zeta[1] * b1[2] - nod_pt->
x(2),
1354 std::ostringstream error_message;
1356 <<
"Error in projection of boundary coordinates = "
1357 <<
sqrt(
error) <<
" > Tolerance_for_boundary_finding = "
1359 <<
"nv = " << nv << std::endl
1360 <<
"Lower left: " << lower_left_node_pt->
x(0) <<
" "
1361 << lower_left_node_pt->
x(1) <<
" " << lower_left_node_pt->
x(2)
1363 <<
"Upper right: " << upper_right_node_pt->
x(0) <<
" "
1364 << upper_right_node_pt->
x(1) <<
" " << upper_right_node_pt->
x(2)
1367 for (
unsigned j = 0;
j < nnod;
j++)
1371 error_message << nod_pt->
x(0) <<
" " << nod_pt->
x(1) <<
" "
1372 << nod_pt->
x(2) <<
" " << std::endl;
1380 if (do_for_real == 1)
1390 if (do_for_real == 1)
1401 for (
unsigned j = 0;
j < 3;
j++)
1417 for (
unsigned ii = 0; ii < 2; ii++)
1428 unsigned n = face_el_pt.size();
1429 for (
unsigned e = 0;
e <
n;
e++)
1431 delete face_el_pt[
e];
1435 if (!vertices_are_in_same_plane)
1458 template<
class ELEMENT>
1462 const bool& switch_normal,
1469 std::ofstream the_file_non_snapped;
1471 "non_snapped_nodes_" + doc_info.
label() +
".dat";
1474 std::ifstream infile(quadratic_surface_file_name.c_str(),
1480 infile.getline(dummy, 100);
1487 infile.getline(dummy, 100);
1490 if (nel != boundary_id.size())
1492 std::ostringstream error_message;
1493 error_message <<
"Number of quadratic facets specified in "
1494 << quadratic_surface_file_name <<
"is: " << nel
1495 <<
"\nThis doesn't match the number of planar boundaries \n"
1496 <<
"specified in boundary_id which is "
1497 << boundary_id.size() << std::endl;
1506 for (
unsigned e = 0;
e < nel;
e++)
1514 unsigned n_position_type = 1;
1515 unsigned initial_n_value = 0;
1518 std::map<unsigned, unsigned> node_number;
1519 std::ofstream node_file;
1520 for (
unsigned j = 0;
j < n_node;
j++)
1524 infile >> nod_pt[
j]->x(0);
1525 infile >> nod_pt[
j]->x(1);
1526 infile >> nod_pt[
j]->x(2);
1527 infile >> node_nmbr;
1528 node_number[node_nmbr] =
j;
1535 for (
unsigned e = 0;
e < nel;
e++)
1537 unsigned nnod_el = face_el_pt[
e]->nnode();
1539 for (
unsigned j = 0;
j < nnod_el;
j++)
1542 face_el_pt[
e]->node_pt(
j) = nod_pt[node_number[j_global]];
1543 face_el_pt[
e]->node_pt(
j)->add_to_boundary(boundary_id[
e]);
1545 face_el_pt[
e]->set_boundary_number_in_bulk_mesh(boundary_id[
e]);
1546 face_el_pt[
e]->set_nodal_dimension(3);
1555 for (
unsigned e = 0;
e < nel;
e++)
1560 Node* lower_left_node_pt = face_el_pt[
e]->node_pt(0);
1561 Node* upper_right_node_pt = face_el_pt[
e]->node_pt(0);
1564 for (
unsigned j = 0;
j < 3;
j++)
1567 Node* nod_pt = face_el_pt[
e]->node_pt(
j);
1570 if (nod_pt->
x(2) < lower_left_node_pt->
x(2))
1572 lower_left_node_pt = nod_pt;
1575 else if (nod_pt->
x(2) == lower_left_node_pt->
x(2))
1578 if (nod_pt->
x(1) < lower_left_node_pt->
x(1))
1580 lower_left_node_pt = nod_pt;
1583 else if (nod_pt->
x(1) == lower_left_node_pt->
x(1))
1586 if (nod_pt->
x(0) < lower_left_node_pt->
x(0))
1588 lower_left_node_pt = nod_pt;
1595 if (nod_pt->
x(2) > upper_right_node_pt->
x(2))
1597 upper_right_node_pt = nod_pt;
1600 else if (nod_pt->
x(2) == upper_right_node_pt->
x(2))
1603 if (nod_pt->
x(1) > upper_right_node_pt->
x(1))
1605 upper_right_node_pt = nod_pt;
1608 else if (nod_pt->
x(1) == upper_right_node_pt->
x(1))
1611 if (nod_pt->
x(0) > upper_right_node_pt->
x(0))
1613 upper_right_node_pt = nod_pt;
1624 b0[0] = upper_right_node_pt->
x(0) - lower_left_node_pt->
x(0);
1625 b0[1] = upper_right_node_pt->
x(1) - lower_left_node_pt->
x(1);
1626 b0[2] = upper_right_node_pt->
x(2) - lower_left_node_pt->
x(2);
1630 1.0 /
sqrt(b0[0] * b0[0] + b0[1] * b0[1] + b0[2] * b0[2]);
1631 b0[0] *= inv_length;
1632 b0[1] *= inv_length;
1633 b0[2] *= inv_length;
1643 face_el_pt[
e]->node_pt(1)->x(0) - face_el_pt[
e]->node_pt(0)->x(0);
1645 face_el_pt[
e]->node_pt(1)->x(1) - face_el_pt[
e]->node_pt(0)->x(1);
1647 face_el_pt[
e]->node_pt(1)->x(2) - face_el_pt[
e]->node_pt(0)->x(2);
1649 face_el_pt[
e]->node_pt(2)->x(0) - face_el_pt[
e]->node_pt(0)->x(0);
1651 face_el_pt[
e]->node_pt(2)->x(1) - face_el_pt[
e]->node_pt(0)->x(1);
1653 face_el_pt[
e]->node_pt(2)->x(2) - face_el_pt[
e]->node_pt(0)->x(2);
1654 normal[0] = -(tang1[1] * tang2[2] - tang1[2] * tang2[1]);
1655 normal[1] = -(tang1[2] * tang2[0] - tang1[0] * tang2[2]);
1656 normal[2] = -(tang1[0] * tang2[1] - tang1[1] * tang2[0]);
1680 for (
unsigned j = 0;
j < 3;
j++)
1683 Node* nod_pt = face_el_pt[
e]->node_pt(
j);
1687 delta[0] = nod_pt->
x(0) - lower_left_node_pt->
x(0);
1688 delta[1] = nod_pt->
x(1) - lower_left_node_pt->
x(1);
1689 delta[2] = nod_pt->
x(2) - lower_left_node_pt->
x(2);
1695 vertex_boundary_coord[
j].resize(2);
1696 vertex_boundary_coord[
j][0] =
zeta[0];
1697 vertex_boundary_coord[
j][1] =
zeta[1];
1702 double error =
pow(lower_left_node_pt->
x(0) +
zeta[0] * b0[0] +
1703 zeta[1] * b1[0] - nod_pt->
x(0),
1705 pow(lower_left_node_pt->
x(1) +
zeta[0] * b0[1] +
1706 zeta[1] * b1[1] - nod_pt->
x(1),
1708 pow(lower_left_node_pt->
x(2) +
zeta[0] * b0[2] +
1709 zeta[1] * b1[2] - nod_pt->
x(2),
1714 std::ostringstream error_message;
1716 <<
"Error in setup of boundary coordinate " <<
sqrt(
error)
1718 <<
"exceeds tolerance specified by the static member data\n"
1719 <<
"TetMeshBase::Tolerance_for_boundary_finding = "
1721 <<
"This usually means that the boundary is not planar.\n\n"
1722 <<
"You can suppress this error message by recompiling \n"
1723 <<
"recompiling without PARANOID or by changing the tolerance.\n";
1739 0.5 * (vertex_boundary_coord[0][0] + vertex_boundary_coord[1][0]);
1741 0.5 * (vertex_boundary_coord[0][1] + vertex_boundary_coord[1][1]);
1742 face_el_pt[
e]->node_pt(3)->set_coordinates_on_boundary(boundary_id[
e],
1747 0.5 * (vertex_boundary_coord[1][0] + vertex_boundary_coord[2][0]);
1749 0.5 * (vertex_boundary_coord[1][1] + vertex_boundary_coord[2][1]);
1750 face_el_pt[
e]->node_pt(4)->set_coordinates_on_boundary(boundary_id[
e],
1755 0.5 * (vertex_boundary_coord[2][0] + vertex_boundary_coord[0][0]);
1757 0.5 * (vertex_boundary_coord[2][1] + vertex_boundary_coord[0][1]);
1758 face_el_pt[
e]->node_pt(5)->set_coordinates_on_boundary(boundary_id[
e],
1764 bool success =
true;
1765 for (
unsigned b = 0;
b < nel;
b++)
1768 std::ofstream the_file;
1769 std::ofstream the_file_before;
1770 std::ofstream the_file_after;
1775 << doc_info.
label() <<
b <<
".dat";
1776 the_file.open(
filename.str().c_str());
1778 std::ostringstream filename1;
1779 filename1 << doc_info.
directory() <<
"/quadratic_nodes_before_"
1780 << doc_info.
label() <<
b <<
".dat";
1781 the_file_before.open(filename1.str().c_str());
1783 std::ostringstream filename2;
1784 filename2 << doc_info.
directory() <<
"/quadratic_nodes_after_"
1785 << doc_info.
label() <<
b <<
".dat";
1786 the_file_after.open(filename2.str().c_str());
1798 unsigned n_plot = 3;
1799 the_file << el_pt->tecplot_zone_string(n_plot);
1802 unsigned num_plot_points = el_pt->nplot_points(n_plot);
1803 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
1806 el_pt->get_s_plot(iplot, n_plot,
s);
1807 el_pt->interpolated_zeta(
s,
zeta);
1808 el_pt->interpolated_x(
s,
x);
1809 for (
unsigned i = 0;
i < 3;
i++)
1811 the_file <<
x[
i] <<
" ";
1813 for (
unsigned i = 0;
i < 2;
i++)
1815 the_file <<
zeta[
i] <<
" ";
1817 the_file << std::endl;
1819 el_pt->write_tecplot_zone_footer(the_file, n_plot);
1835 for (
unsigned e = 0;
e < nel;
e++)
1842 unsigned nnod = bulk_elem_pt->
nnode();
1843 for (
unsigned j = 0;
j < nnod;
j++)
1853 the_file_before << nod_pt->
x(0) <<
" " << nod_pt->
x(1) <<
" "
1854 << nod_pt->
x(2) <<
" " << boundary_zeta[0] <<
" "
1855 << boundary_zeta[1] <<
" " << std::endl;
1859 el_pt->locate_zeta(boundary_zeta, geom_obj_pt, s_geom_obj);
1860 if (geom_obj_pt != 0)
1862 geom_obj_pt->
position(s_geom_obj, quadratic_coordinates);
1863 nod_pt->
x(0) = quadratic_coordinates[0];
1864 nod_pt->
x(1) = quadratic_coordinates[1];
1865 nod_pt->
x(2) = quadratic_coordinates[2];
1872 std::ostringstream error_message;
1874 <<
"Warning: Couldn't find GeomObject during snapping to\n"
1875 <<
"quadratic surface for boundary " << boundary_id[
b]
1876 <<
". I'm leaving the node where it was. Will bail out "
1879 "TetgenMesh::snap_to_quadratic_surface()",
1881 if (!the_file_non_snapped.is_open())
1883 the_file_non_snapped.open(non_snapped_filename.c_str());
1885 the_file_non_snapped << nod_pt->
x(0) <<
" " << nod_pt->
x(1) <<
" "
1886 << nod_pt->
x(2) <<
" " << boundary_zeta[0]
1887 <<
" " << boundary_zeta[1] <<
" "
1894 the_file_after << nod_pt->
x(0) <<
" " << nod_pt->
x(1) <<
" "
1895 << nod_pt->
x(2) <<
" " << boundary_zeta[0] <<
" "
1896 << boundary_zeta[1] <<
" " << std::endl;
1904 the_file_before.close();
1905 the_file_after.close();
1911 std::ostringstream error_message;
1913 <<
"Warning: Couldn't find GeomObject during snapping to\n"
1914 <<
"quadratic surface. Bailing out.\n"
1915 <<
"Nodes that couldn't be snapped are contained in \n"
1916 <<
"file: " << non_snapped_filename <<
".\n"
1917 <<
"This problem may arise because the switch_normal flag was \n"
1918 <<
"set wrongly.\n";
1924 if (!the_file_non_snapped.is_open())
1926 the_file_non_snapped.close();
1930 for (
unsigned e = 0;
e < nel;
e++)
1932 delete face_el_pt[
e];
1937 unsigned nn = nod_pt.size();
1938 for (
unsigned j = 0;
j < nn;
j++)
1949 template<
class ELEMENT>
1964 if ((nnode_1d != 2) && (nnode_1d != 3))
1966 std::ostringstream error_message;
1967 error_message <<
"Mesh generation from tetgen currently only works\n";
1968 error_message <<
"for nnode_1d = 2 or 3. You're trying to use it\n";
1969 error_message <<
"for nnode_1d=" << nnode_1d << std::endl;
1976 std::map<FiniteElement*, unsigned> count;
1980 for (
unsigned b = 0;
b <
nb;
b++)
1984 for (
unsigned e = 0;
e < nel;
e++)
1997 std::set<FiniteElement*> elements_to_be_split;
1998 for (std::map<FiniteElement*, unsigned>::iterator it = count.begin();
2008 elements_to_be_split.insert(el_pt);
2015 new_or_retained_el_pt.reserve(nel);
2019 std::map<FiniteElement*, Vector<FiniteElement*>>
2020 old_to_new_corner_element_map;
2023 for (
unsigned e = 0;
e < nel;
e++)
2029 std::set<FiniteElement*>::iterator it = std::find(
2030 elements_to_be_split.begin(), elements_to_be_split.end(), el_pt);
2033 if (it == elements_to_be_split.end())
2036 new_or_retained_el_pt.push_back(el_pt);
2053 Node* node10_pt = 0;
2074 node0_pt = el_pt->
node_pt(14);
2075 el1_pt->
node_pt(2) = node0_pt;
2117 el2_pt->
node_pt(3) = node0_pt;
2120 el2_pt->
node_pt(6) = node1_pt;
2121 el2_pt->
node_pt(9) = node2_pt;
2127 el2_pt->
node_pt(10) = node5_pt;
2148 el3_pt->
node_pt(0) = node0_pt;
2151 el3_pt->
node_pt(4) = node2_pt;
2152 el3_pt->
node_pt(5) = node3_pt;
2153 el3_pt->
node_pt(6) = node4_pt;
2159 el3_pt->
node_pt(10) = node6_pt;
2160 el3_pt->
node_pt(11) = node10_pt;
2181 el4_pt->
node_pt(1) = node0_pt;
2184 el4_pt->
node_pt(4) = node1_pt;
2185 el4_pt->
node_pt(7) = node3_pt;
2186 el4_pt->
node_pt(9) = node4_pt;
2192 el4_pt->
node_pt(10) = node9_pt;
2193 el4_pt->
node_pt(11) = node8_pt;
2195 el4_pt->
node_pt(13) = node7_pt;
2201 new_or_retained_el_pt.push_back(el1_pt);
2202 new_or_retained_el_pt.push_back(el2_pt);
2203 new_or_retained_el_pt.push_back(el3_pt);
2204 new_or_retained_el_pt.push_back(el4_pt);
2208 temp_vec[0] = el1_pt;
2209 temp_vec[1] = el2_pt;
2210 temp_vec[2] = el3_pt;
2211 temp_vec[3] = el4_pt;
2214 old_to_new_corner_element_map.insert(
2235 for (
unsigned i = 0;
i < 3;
i++)
2247 node1_pt->
x(
i) = 0.5 * (el_pt->
node_pt(0)->
x(
i) + node0_pt->
x(
i));
2248 node2_pt->
x(
i) = 0.5 * (el_pt->
node_pt(1)->
x(
i) + node0_pt->
x(
i));
2249 node3_pt->
x(
i) = 0.5 * (el_pt->
node_pt(2)->
x(
i) + node0_pt->
x(
i));
2250 node4_pt->
x(
i) = 0.5 * (el_pt->
node_pt(3)->
x(
i) + node0_pt->
x(
i));
2261 for (
unsigned i = 0;
i < 3; ++
i)
2270 for (
unsigned i = 0;
i < 3; ++
i)
2279 for (
unsigned i = 0;
i < 3; ++
i)
2288 for (
unsigned i = 0;
i < 3; ++
i)
2297 for (
unsigned i = 0;
i < 3; ++
i)
2306 for (
unsigned i = 0;
i < 3; ++
i)
2318 for (
unsigned i = 0;
i < 3; ++
i)
2320 double av_pos = 0.0;
2321 for (
unsigned j = 0;
j < 4;
j++)
2326 temp_nod_pt->
x(
i) = 0.25 * av_pos;
2333 for (
unsigned i = 0;
i < 3; ++
i)
2335 double av_pos = 0.0;
2336 for (
unsigned j = 0;
j < 4;
j++)
2340 temp_nod_pt->
x(
i) = 0.25 * av_pos;
2346 for (
unsigned i = 0;
i < 3; ++
i)
2348 double av_pos = 0.0;
2349 for (
unsigned j = 0;
j < 4;
j++)
2353 temp_nod_pt->
x(
i) = 0.25 * av_pos;
2359 for (
unsigned i = 0;
i < 3; ++
i)
2361 double av_pos = 0.0;
2362 for (
unsigned j = 0;
j < 4;
j++)
2366 temp_nod_pt->
x(
i) = 0.25 * av_pos;
2380 nel = new_or_retained_el_pt.size();
2382 for (
unsigned e = 0;
e < nel;
e++)
2413 if (old_to_new_corner_element_map.size() == 0)
2415 oomph_info <<
"\nNo corner elements need splitting\n\n";
2424 old_to_new_corner_element_map.begin();
2425 map_it != old_to_new_corner_element_map.end();
2432 unsigned original_region_index = 0;
2458 original_region_index = region_index;
2473 std::ostringstream error_message;
2475 <<
"The corner element being split does not appear to be in any "
2476 <<
"region, so something has gone wrong with the region lookup "
2488 for (
unsigned i = 0;
i < 4;
i++)
2506 for (
unsigned e = 0;
e < nel;
e++)
2533 oomph_info <<
"\nNumber of outer corner elements split: "
2534 << old_to_new_corner_element_map.size() <<
"\n\n";
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Scalar * b
Definition: benchVecAdd.cpp:17
Definition: geom_obj_with_boundary.h:67
Definition: oomph_utilities.h:499
bool is_doc_enabled() const
Are we documenting?
Definition: oomph_utilities.h:548
void disable_doc()
Disable documentation.
Definition: oomph_utilities.h:542
std::string & label()
String used (e.g.) for labeling output files.
Definition: oomph_utilities.h:572
std::string directory() const
Output directory.
Definition: oomph_utilities.h:524
Definition: elements.h:5014
Definition: elements.h:1313
virtual Node * construct_node(const unsigned &n)
Definition: elements.h:2509
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
virtual unsigned nnode_1d() const
Definition: elements.h:2218
virtual Node * construct_boundary_node(const unsigned &n)
Definition: elements.h:2538
Definition: elements.h:5119
Definition: geom_objects.h:101
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
unsigned long nboundary_node(const unsigned &ibound) const
Return number of nodes on a particular boundary.
Definition: mesh.h:833
static Steady< 0 > Default_TimeStepper
The Steady Timestepper.
Definition: mesh.h:75
bool Lookup_for_elements_next_boundary_is_setup
Definition: mesh.h:87
std::vector< bool > Boundary_coordinate_exists
Definition: mesh.h:190
FiniteElement * finite_element_pt(const unsigned &e) const
Definition: mesh.h:473
int face_index_at_boundary(const unsigned &b, const unsigned &e) const
Definition: mesh.h:896
unsigned nboundary_element(const unsigned &b) const
Return number of finite elements that are adjacent to boundary b.
Definition: mesh.h:878
unsigned nboundary() const
Return number of boundaries.
Definition: mesh.h:827
FiniteElement * boundary_element_pt(const unsigned &b, const unsigned &e) const
Return pointer to e-th finite element on boundary b.
Definition: mesh.h:840
unsigned long nnode() const
Return number of nodes in the mesh.
Definition: mesh.h:596
void add_node_pt(Node *const &node_pt)
Add a (pointer to a) node to the mesh.
Definition: mesh.h:611
Node *& boundary_node_pt(const unsigned &b, const unsigned &n)
Return pointer to node n on boundary b.
Definition: mesh.h:493
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition: mesh.h:186
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:1060
virtual bool is_on_boundary() const
Definition: nodes.h:1373
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition: nodes.h:1054
virtual void set_coordinates_on_boundary(const unsigned &b, const unsigned &k, const Vector< double > &boundary_zeta)
Definition: nodes.cc:2394
virtual void get_coordinates_on_boundary(const unsigned &b, const unsigned &k, Vector< double > &boundary_zeta)
Definition: nodes.cc:2379
Definition: oomph_definitions.h:222
Definition: oomph_definitions.h:267
Base class for tet meshes (meshes made of 3D tet elements).
Definition: tet_mesh.h:661
virtual ~TetMeshBase()
Destructor (empty)
Definition: tet_mesh.h:673
void snap_nodes_onto_geometric_objects()
Definition: tet_mesh.cc:483
void snap_to_quadratic_surface(const Vector< unsigned > &boundary_id, const std::string &quadratic_surface_file_name, const bool &switch_normal, DocInfo &doc_info)
Definition: tet_mesh.h:1459
int face_index_at_boundary_in_region(const unsigned &b, const unsigned &r, const unsigned &e) const
Return face index of the e-th element adjacent to boundary b in region r.
Definition: tet_mesh.h:834
Vector< double > Region_attribute
Definition: tet_mesh.h:1027
double region_attribute(const unsigned &i)
Definition: tet_mesh.h:906
void setup_boundary_coordinates(const unsigned &b, const bool &switch_normal)
Definition: tet_mesh.h:733
unsigned nregion()
Return the number of regions specified by attributes.
Definition: tet_mesh.h:860
TimeStepper * Time_stepper_pt
Timestepper used to build nodes.
Definition: tet_mesh.h:1057
unsigned nboundary_element_in_region(const unsigned &b, const unsigned &r) const
Return the number of elements adjacent to boundary b in region r.
Definition: tet_mesh.h:797
std::map< unsigned, TetMeshFacetedSurface * > Tet_mesh_faceted_surface_pt
Definition: tet_mesh.h:1045
Vector< TetMeshFacetedSurface * > Internal_surface_pt
Vector to faceted surfaces that define internal boundaries.
Definition: tet_mesh.h:1041
Vector< std::map< unsigned, Vector< FiniteElement * > > > Boundary_region_element_pt
Storage for elements adjacent to a boundary in a particular region.
Definition: tet_mesh.h:1031
void operator=(const TetMeshBase &)=delete
Broken assignment operator.
std::map< unsigned, TetMeshFacet * > Tet_mesh_facet_pt
Definition: tet_mesh.h:1049
void setup_boundary_coordinates(const unsigned &b)
Definition: tet_mesh.h:702
TetMeshFacetedClosedSurface * Outer_boundary_pt
Faceted surface that defines outer boundaries.
Definition: tet_mesh.h:1038
FiniteElement * boundary_element_in_region_pt(const unsigned &b, const unsigned &r, const unsigned &e) const
Return pointer to the e-th element adjacent to boundary b in region r.
Definition: tet_mesh.h:816
static double Tolerance_for_boundary_finding
Definition: tet_mesh.h:677
void assess_mesh_quality(std::ofstream &some_file)
Definition: tet_mesh.cc:373
FiniteElement * region_element_pt(const unsigned &r, const unsigned &e)
Return the e-th element in the r-th region.
Definition: tet_mesh.h:912
TetMeshBase()
Constructor.
Definition: tet_mesh.h:664
void snap_to_quadratic_surface(const Vector< unsigned > &boundary_id, const std::string &quadratic_surface_file_name, const bool &switch_normal)
Definition: tet_mesh.h:979
void setup_boundary_element_info()
Definition: tet_mesh.h:1007
Vector< std::map< unsigned, Vector< int > > > Face_index_region_at_boundary
Definition: tet_mesh.h:1035
std::map< unsigned, Vector< Vector< double > > > Triangular_facet_vertex_boundary_coordinate
Definition: tet_mesh.h:1054
TetMeshBase(const TetMeshBase &node)=delete
Broken copy constructor.
Vector< Vector< FiniteElement * > > Region_element_pt
Definition: tet_mesh.h:1022
void split_elements_in_corners(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Definition: tet_mesh.h:1950
void setup_boundary_coordinates(const unsigned &b, std::ofstream &outfile)
Definition: tet_mesh.h:788
unsigned nregion_element(const unsigned &r)
Return the number of elements in region r.
Definition: tet_mesh.h:866
Definition: tet_mesh.h:168
Vector< TetMeshVertex * > Vertex_pt
Pointer to vertices.
Definition: tet_mesh.h:280
void set_vertex_pt(const unsigned &j, TetMeshVertex *vertex_pt)
Definition: tet_mesh.h:194
TetMeshVertex * vertex_pt(const unsigned &j) const
Pointer to j-th vertex (const)
Definition: tet_mesh.h:187
void output(std::ostream &outfile) const
Output.
Definition: tet_mesh.h:263
void set_one_based_region_that_facet_is_embedded_in(const unsigned &one_based_region_id)
Facet is to be embedded in specified one-based region.
Definition: tet_mesh.h:249
std::set< unsigned > One_based_adjacent_region_id
Definition: tet_mesh.h:287
bool facet_is_embedded_in_a_specified_region()
Boolean indicating that facet is embedded in a specified region.
Definition: tet_mesh.h:243
void set_one_based_boundary_id(const unsigned &one_based_id)
Definition: tet_mesh.h:214
unsigned one_based_boundary_id() const
Constant access to (one-based!) boundary IDs this facet lives on.
Definition: tet_mesh.h:207
unsigned nvertex() const
Number of vertices.
Definition: tet_mesh.h:181
unsigned One_based_boundary_id
(One-based!) boundary IDs this facet lives on
Definition: tet_mesh.h:283
unsigned One_based_region_id_that_facet_is_embedded_in
Definition: tet_mesh.h:292
void set_one_based_adjacent_region_id(const unsigned &one_based_id)
Definition: tet_mesh.h:231
unsigned one_based_region_that_facet_is_embedded_in()
Definition: tet_mesh.h:257
std::set< unsigned > one_based_adjacent_region_id() const
Return set of (one-based!) region IDs this facet is adjacent to.
Definition: tet_mesh.h:237
TetMeshFacet(const unsigned &nvertex)
Constructor: Specify number of vertices.
Definition: tet_mesh.h:171
Definition: tet_mesh.h:634
virtual ~TetMeshFacetedClosedSurfaceForRemesh()
Destructor. Delete allocated memory.
Definition: tet_mesh.cc:73
TetMeshFacetedClosedSurfaceForRemesh(Vector< Node * > const &vertex_node_pt, Vector< Vector< unsigned >> const &facet_connectivity, Vector< unsigned > const &facet_boundary_id)
Definition: tet_mesh.cc:40
Definition: tet_mesh.h:538
TetMeshFacetedClosedSurface()
Constructor:
Definition: tet_mesh.h:541
bool Faceted_volume_represents_hole_for_gmsh
Does closed surface represent hole for gmsh?
Definition: tet_mesh.h:624
void enable_faceted_volume_represents_hole_for_gmsh()
Declare closed surface to represent hole for gmsh.
Definition: tet_mesh.h:550
const int & region_id_for_tetgen(const unsigned &j) const
Definition: tet_mesh.h:598
bool faceted_volume_represents_hole_for_gmsh() const
Does closed surface represent hole for gmsh?
Definition: tet_mesh.h:562
Vector< std::pair< Vector< double >, int > > Internal_point_for_tetgen
Definition: tet_mesh.h:621
virtual ~TetMeshFacetedClosedSurface()
Empty destructor.
Definition: tet_mesh.h:547
unsigned ninternal_point_for_tetgen()
Definition: tet_mesh.h:591
bool internal_point_identifies_region_for_tetgen(const unsigned &j)
Is j-th internal point for tetgen associated with a region?
Definition: tet_mesh.h:611
bool internal_point_identifies_hole_for_tetgen(const unsigned &j)
Is j-th internal point for tetgen associated with a hole?
Definition: tet_mesh.h:605
const double & internal_point_for_tetgen(const unsigned &j, const unsigned &i) const
i=th coordinate of the j-th internal point for tetgen
Definition: tet_mesh.h:568
void disable_faceted_volume_represents_hole_for_gmsh()
Declare closed surface NOT to represent hole for gmsh.
Definition: tet_mesh.h:556
void set_region_for_tetgen(const unsigned ®ion_id, const Vector< double > ®ion_point)
Definition: tet_mesh.h:582
void set_hole_for_tetgen(const Vector< double > &hole_point)
Specify coordinate of hole for tetgen.
Definition: tet_mesh.h:575
Definition: tet_mesh.h:306
unsigned nvertex_on_facet(const unsigned &j) const
Number of vertices defining the j-th facet.
Definition: tet_mesh.h:349
bool Boundaries_can_be_split_in_tetgen
Definition: tet_mesh.h:490
void disable_boundaries_can_be_split_in_tetgen()
Test whether boundaries can be split in tetgen.
Definition: tet_mesh.h:367
virtual void boundary_zeta01(const unsigned &facet_id, const double &zeta_boundary, Vector< double > &zeta)
Definition: tet_mesh.h:417
Vector< TetMeshVertex * > Vertex_pt
Vector pointers to vertices.
Definition: tet_mesh.h:483
unsigned nfacet() const
Number of facets.
Definition: tet_mesh.h:325
Vector< Vector< unsigned > > Facet_vertex_index_in_tetgen
Definition: tet_mesh.h:494
DiskLikeGeomObjectWithBoundaries * Geom_object_with_boundaries_pt
GeomObject with boundaries associated with this surface.
Definition: tet_mesh.h:497
virtual void boundary_zeta12(const unsigned &facet_id, const double &zeta_boundary, Vector< double > &zeta)
Definition: tet_mesh.h:436
bool boundaries_can_be_split_in_tetgen()
Test whether boundary can be split in tetgen.
Definition: tet_mesh.h:355
Vector< TetMeshFacet * > Facet_pt
Vector of pointers to facets.
Definition: tet_mesh.h:486
unsigned one_based_facet_boundary_id(const unsigned &j) const
One-based boundary id of j-th facet.
Definition: tet_mesh.h:331
TetMeshFacet * facet_pt(const unsigned &j) const
Pointer to j-th facet.
Definition: tet_mesh.h:373
Vector< unsigned > vertex_index_in_tetgen(const unsigned &f)
Definition: tet_mesh.h:472
void enable_boundaries_can_be_split_in_tetgen()
Test whether boundaries can be split in tetgen.
Definition: tet_mesh.h:361
virtual void boundary_zeta20(const unsigned &facet_id, const double &zeta_boundary, Vector< double > &zeta)
Definition: tet_mesh.h:455
void setup_facet_connectivity_for_tetgen()
Setup facet connectivity for tetgen.
Definition: tet_mesh.h:502
double vertex_coordinate(const unsigned &j, const unsigned &i) const
i-th coordinate of j-th vertex
Definition: tet_mesh.h:343
unsigned nvertex() const
Number of vertices.
Definition: tet_mesh.h:319
TetMeshFacetedSurface()
Constructor:
Definition: tet_mesh.h:309
void output(const std::string &filename) const
Output.
Definition: tet_mesh.h:403
TetMeshVertex * vertex_pt(const unsigned &j) const
Pointer to j-th vertex.
Definition: tet_mesh.h:379
void output(std::ostream &outfile) const
Output.
Definition: tet_mesh.h:392
virtual ~TetMeshFacetedSurface()
Empty destructor.
Definition: tet_mesh.h:316
DiskLikeGeomObjectWithBoundaries * geom_object_with_boundaries_pt()
Definition: tet_mesh.h:386
unsigned one_based_vertex_boundary_id(const unsigned &j) const
First (of possibly multiple) one-based boundary id of j-th vertex.
Definition: tet_mesh.h:337
Definition: tet_mesh.h:50
void set_zeta_in_geom_object(const Vector< double > &zeta)
Set intrinisic coordinates in GeomObject.
Definition: tet_mesh.h:97
Vector< double > X
Coordinate vector.
Definition: tet_mesh.h:147
TetMeshVertex(Node *const &node_pt)
Definition: tet_mesh.h:72
Vector< double > zeta_in_geom_object() const
Definition: tet_mesh.h:118
std::set< unsigned > One_based_boundary_id
Set of (one-based!) boundary IDs this vertex lives on.
Definition: tet_mesh.h:150
unsigned one_based_boundary_id() const
First (of possibly multiple) one-based boundary id.
Definition: tet_mesh.h:130
Vector< double > Zeta_in_geom_object
Definition: tet_mesh.h:154
void set_one_based_boundary_id(const unsigned &id)
Set of (one-based!) boundary IDs this vertex lives on.
Definition: tet_mesh.h:141
double x(const unsigned &i) const
i-th coordinate
Definition: tet_mesh.h:124
TetMeshVertex(const Vector< double > &x)
Constructor: Pass coordinates (length 3!)
Definition: tet_mesh.h:56
Definition: timesteppers.h:231
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
RealScalar s
Definition: level1_cplx_impl.h:130
int nb
Definition: level2_impl.h:286
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
EIGEN_STRONG_INLINE const Eigen::CwiseBinaryOp< Eigen::internal::scalar_zeta_op< typename DerivedX::Scalar >, const DerivedX, const DerivedQ > zeta(const Eigen::ArrayBase< DerivedX > &x, const Eigen::ArrayBase< DerivedQ > &q)
Definition: SpecialFunctionsArrayAPI.h:152
string filename
Definition: MergeRestartFiles.py:39
bool found
Definition: MergeRestartFiles.py:24
int delta
Definition: MultiOpt.py:96
void normal(const Vector< double > &x, Vector< double > &normal)
Definition: free_surface_rotation.cc:65
Real fabs(const Real &a)
Definition: boostmultiprec.cpp:117
int error
Definition: calibrate.py:297
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
list x
Definition: plotDoE.py:28
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2