26 #ifndef OOMPH_PML_MESH_HEADER
27 #define OOMPH_PML_MESH_HEADER
31 #include <oomph-lib-config.h>
35 #include "../meshes/rectangular_quadmesh.template.h"
36 #include "../meshes/rectangular_quadmesh.template.cc"
46 template<
class ELEMENT>
58 template<
unsigned DIM>
83 for (
unsigned direction = 0; direction <
DIM; direction++)
98 const double& interface_border_value,
99 const double& outer_domain_border_value)
145 namespace TwoDimensionalPMLHelper
184 template<
class ELEMENT>
191 const unsigned& n_pml_y,
192 const double& x_pml_start,
193 const double& x_pml_end,
194 const double& y_pml_start,
195 const double& y_pml_end,
232 double tol = 1.0e-12;
241 std::ostringstream error_message_stream;
244 error_message_stream <<
"Point does not lie in the mesh." << std::endl;
256 const unsigned nx = this->
nx();
259 const unsigned ny = this->
ny();
289 bottom_boundary_x_coordinates[0] =
x_min;
292 bottom_boundary_x_coordinates[
nx] =
x_max;
295 right_boundary_y_coordinates[0] =
y_min;
298 right_boundary_y_coordinates[
ny] =
y_max;
306 unsigned lower_boundary_id = 0;
309 unsigned right_boundary_id = 1;
312 for (
unsigned i = 0;
i <
nx;
i++)
318 bottom_boundary_x_coordinates[
i + 1] =
328 for (
unsigned i = 0;
i <
ny;
i++)
334 right_boundary_y_coordinates[
i + 1] = el_pt->
node_pt(
nnode - 1)->
x(1);
343 bool element_x_id_has_been_found =
false;
348 bool element_y_id_has_been_found =
false;
351 unsigned element_x_id = 0;
354 unsigned element_y_id = 0;
357 for (
unsigned i = 0;
i <
nx;
i++)
360 if ((
x[0] >= bottom_boundary_x_coordinates[
i]) &&
361 (
x[0] <= bottom_boundary_x_coordinates[
i + 1]))
367 element_x_id_has_been_found =
true;
372 if (!element_x_id_has_been_found)
375 std::ostringstream error_message_stream;
378 error_message_stream <<
"The ID of the element in the x-direction "
379 <<
"has not been found." << std::endl;
388 for (
unsigned i = 0;
i <
ny;
i++)
391 if ((
x[1] >= right_boundary_y_coordinates[
i]) &&
392 (
x[1] <= right_boundary_y_coordinates[
i + 1]))
398 element_y_id_has_been_found =
true;
403 if (!element_y_id_has_been_found)
406 std::ostringstream error_message_stream;
409 error_message_stream <<
"The ID of the element in the y-direction "
410 <<
"has not been found." << std::endl;
419 unsigned el_id = element_y_id *
nx + element_x_id;
429 template<
class ELEMENT>
442 const unsigned& boundary_id,
443 const unsigned& quad_boundary_id,
444 const unsigned& n_pml_x,
445 const unsigned& n_pml_y,
446 const double& x_pml_start,
447 const double& x_pml_end,
448 const double& y_pml_start,
449 const double& y_pml_end,
459 unsigned n_boundary_node = bulk_mesh_pt->
nboundary_node(boundary_id);
465 for (
unsigned n = 0;
n < n_boundary_node;
n++)
467 ordered_boundary_node_pt[
n] =
474 if (quad_boundary_id == 3)
476 std::sort(ordered_boundary_node_pt.begin(),
477 ordered_boundary_node_pt.end(),
482 if (quad_boundary_id == 0)
484 std::sort(ordered_boundary_node_pt.begin(),
485 ordered_boundary_node_pt.end(),
490 if (quad_boundary_id == 1)
492 std::sort(ordered_boundary_node_pt.begin(),
493 ordered_boundary_node_pt.end(),
498 if (quad_boundary_id == 2)
500 std::sort(ordered_boundary_node_pt.begin(),
501 ordered_boundary_node_pt.end(),
511 unsigned interior_node_nr_helper_1 = nnode_1d * (nnode_1d - 1);
513 unsigned interior_node_nr_helper_2 = nnode_1d - 1;
515 unsigned interior_node_nr_helper_3 = nnode_1d * (nnode_1d - 1) - 1;
520 for (
unsigned j = 0;
j < nnod;
j++)
529 unsigned n_pml_element = this->
nelement();
534 unsigned interior_element_nr_helper_1 = n_pml_element - 1;
543 if (quad_boundary_id == 3)
545 for (
unsigned e = 0;
e < n_pml_element;
e++)
548 if ((
e % n_pml_x) == 0)
551 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
554 unsigned n_node = el_pt->nnode();
555 for (
unsigned inod = 0; inod < n_node; inod++)
557 if (inod % nnode_1d == 0)
560 el_pt->node_pt(inod) = ordered_boundary_node_pt[count];
564 if (inod == interior_node_nr_helper_1)
575 if (quad_boundary_id == 0)
577 for (
unsigned e = 0;
e < n_pml_element;
e++)
580 if ((
int)(
e / n_pml_x) == 0)
583 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
586 unsigned n_node = el_pt->nnode();
587 for (
unsigned inod = 0; inod < n_node; inod++)
589 if ((
int)(inod / nnode_1d) == 0)
592 el_pt->node_pt(inod) = ordered_boundary_node_pt[count];
596 if (inod == interior_node_nr_helper_2)
607 if (quad_boundary_id == 1)
609 for (
unsigned e = interior_element_nr_helper_1;
e < n_pml_element;
e--)
612 if ((
e % n_pml_x) == (n_pml_x - 1))
615 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
618 unsigned n_node = el_pt->nnode();
619 unsigned starter = n_node - 1;
620 for (
unsigned inod = starter; inod <= starter; inod--)
622 if (inod % nnode_1d == interior_node_nr_helper_2)
625 el_pt->node_pt(inod) = ordered_boundary_node_pt[count];
629 if (inod == interior_node_nr_helper_2)
640 if (quad_boundary_id == 2)
642 for (
unsigned e = interior_element_nr_helper_1;
e < n_pml_element;
e--)
645 if (
e >= (n_pml_x * (n_pml_y - 1)))
648 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
651 unsigned n_node = el_pt->nnode();
652 unsigned starter = n_node - 1;
653 for (
unsigned inod = starter; inod <= starter; inod--)
655 if (inod > interior_node_nr_helper_3)
658 el_pt->node_pt(inod) = ordered_boundary_node_pt[count];
662 if (inod == interior_node_nr_helper_1)
680 for (
unsigned e = 0;
e < n_pml_element;
e++)
683 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
684 unsigned n_node = el_pt->nnode();
687 double temp_coordinate = 0.0;
688 for (
unsigned inod = 0; inod < n_node; inod++)
691 if (quad_boundary_id == 3)
694 if (inod % nnode_1d == 0)
697 temp_coordinate = el_pt->node_pt(inod)->x(1);
702 el_pt->node_pt(inod)->x(1) = temp_coordinate;
707 if (quad_boundary_id == 0)
710 if (inod > interior_node_nr_helper_2)
713 el_pt->node_pt(inod)->x(0) =
714 el_pt->node_pt(inod - nnode_1d)->x(0);
721 for (
unsigned e = interior_element_nr_helper_1;
e < n_pml_element;
e--)
724 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
725 unsigned n_node = el_pt->nnode();
728 double temp_coordinate = 0.0;
729 unsigned starter = n_node - 1;
730 for (
unsigned inod = starter; inod <= starter; inod--)
733 if (quad_boundary_id == 1)
736 if (inod % nnode_1d == interior_node_nr_helper_2)
739 temp_coordinate = el_pt->node_pt(inod)->x(1);
744 el_pt->node_pt(inod)->x(1) = temp_coordinate;
749 if (quad_boundary_id == 2)
752 if (inod < interior_node_nr_helper_1)
755 el_pt->node_pt(inod)->x(0) =
756 el_pt->node_pt(inod + nnode_1d)->x(0);
775 template<
class ELEMENT>
784 Mesh* PMLQuad_mesh_y_pt,
786 Node* special_corner_node_pt,
787 const unsigned& parent_boundary_x_id,
788 const unsigned& parent_boundary_y_id,
789 const unsigned& current_boundary_x_id,
790 const unsigned& current_boundary_y_id,
791 const unsigned& n_pml_x,
792 const unsigned& n_pml_y,
793 const double& x_pml_start,
794 const double& x_pml_end,
795 const double& y_pml_start,
796 const double& y_pml_end,
812 unsigned interior_node_nr_helper_1 = nnode_1d * (nnode_1d - 1);
814 unsigned interior_node_nr_helper_2 = nnode_1d - 1;
816 unsigned interior_node_nr_helper_3 = nnode_1d * nnode_1d - 1;
820 if ((parent_boundary_x_id == 2) && (parent_boundary_y_id == 1))
823 unsigned n_boundary_x_node =
830 for (
unsigned n = 0;
n < n_boundary_x_node;
n++)
832 ordered_boundary_x_node_pt[
n] =
837 if (parent_boundary_x_id == 2)
839 std::sort(ordered_boundary_x_node_pt.begin(),
840 ordered_boundary_x_node_pt.end(),
845 unsigned n_boundary_y_node =
852 for (
unsigned n = 0;
n < n_boundary_y_node;
n++)
854 ordered_boundary_y_node_pt[
n] =
859 if (parent_boundary_y_id == 1)
861 std::sort(ordered_boundary_y_node_pt.begin(),
862 ordered_boundary_y_node_pt.end(),
867 for (
unsigned j = 0;
j < x_nnod;
j++)
873 for (
unsigned j = 0;
j < y_nnod;
j++)
881 unsigned n_pml_element = this->
nelement();
887 if (parent_boundary_y_id == 1)
889 for (
unsigned e = 0;
e < n_pml_element;
e++)
892 if ((
e % n_pml_x) == 0)
895 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
898 unsigned n_node = el_pt->nnode();
899 for (
unsigned inod = 0; inod < n_node; inod++)
904 if (inod == 0) el_pt->node_pt(inod) = special_corner_node_pt;
905 if ((inod % nnode_1d == 0) && (inod > 0))
908 el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
912 if (inod == interior_node_nr_helper_1)
920 if ((inod % nnode_1d) == 0)
923 el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
927 if (inod == interior_node_nr_helper_1)
940 if (parent_boundary_x_id == 2)
942 for (
unsigned e = 0;
e < n_pml_element;
e++)
945 if ((
int)(
e / n_pml_x) == 0)
948 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
951 unsigned n_node = el_pt->nnode();
952 for (
unsigned inod = 0; inod < n_node; inod++)
956 if (((
int)(inod / nnode_1d) == 0) && (inod > 0))
959 el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
963 if (inod == interior_node_nr_helper_2)
971 if ((
int)(inod / nnode_1d) == 0)
974 el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
978 if (inod == interior_node_nr_helper_2)
992 if ((parent_boundary_x_id == 0) && (parent_boundary_y_id == 1))
995 unsigned n_boundary_x_node =
1002 for (
unsigned n = 0;
n < n_boundary_x_node;
n++)
1004 ordered_boundary_x_node_pt[
n] =
1009 if (parent_boundary_x_id == 0)
1011 std::sort(ordered_boundary_x_node_pt.begin(),
1012 ordered_boundary_x_node_pt.end(),
1017 unsigned n_boundary_y_node =
1021 Vector<Node*> ordered_boundary_y_node_pt(n_boundary_y_node);
1024 for (
unsigned n = 0;
n < n_boundary_y_node;
n++)
1026 ordered_boundary_y_node_pt[
n] =
1031 if (parent_boundary_y_id == 1)
1033 std::sort(ordered_boundary_y_node_pt.begin(),
1034 ordered_boundary_y_node_pt.end(),
1039 for (
unsigned j = 0;
j < x_nnod;
j++)
1045 for (
unsigned j = 0;
j < y_nnod;
j++)
1054 unsigned n_pml_element = this->
nelement();
1060 if (parent_boundary_y_id == 1)
1062 for (
unsigned e = 0;
e < n_pml_element;
e++)
1065 if ((
e % n_pml_x) == 0)
1068 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
1071 unsigned n_node = el_pt->nnode();
1072 for (
unsigned inod = 0; inod < n_node; inod++)
1074 if (
e == ((n_pml_x) * (n_pml_y - 1)))
1076 if (inod == interior_node_nr_helper_1)
1078 el_pt->node_pt(inod) = special_corner_node_pt;
1080 if ((inod % nnode_1d == 0) &&
1081 (inod < interior_node_nr_helper_1))
1084 el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
1088 if (inod == interior_node_nr_helper_1)
1096 if ((inod % nnode_1d) == 0)
1099 el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
1103 if (inod == interior_node_nr_helper_1)
1116 if (parent_boundary_x_id == 0)
1118 for (
unsigned e = 0;
e < n_pml_element;
e++)
1121 if (
e >= ((n_pml_x - 0) * (n_pml_y - 1)))
1124 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
1127 unsigned n_node = el_pt->nnode();
1128 for (
unsigned inod = 0; inod < n_node; inod++)
1130 if (
e == ((n_pml_x) * (n_pml_y - 1)))
1132 if (((
unsigned)(inod / nnode_1d) ==
1133 interior_node_nr_helper_2) &&
1134 (inod > interior_node_nr_helper_1))
1137 el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
1141 if (inod == interior_node_nr_helper_3)
1149 if ((
unsigned)(inod / nnode_1d) == interior_node_nr_helper_2)
1152 el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
1156 if (inod == interior_node_nr_helper_3)
1170 if ((parent_boundary_x_id == 2) && (parent_boundary_y_id == 3))
1173 unsigned n_boundary_x_node =
1177 Vector<Node*> ordered_boundary_x_node_pt(n_boundary_x_node);
1180 for (
unsigned n = 0;
n < n_boundary_x_node;
n++)
1182 ordered_boundary_x_node_pt[
n] =
1187 if (parent_boundary_x_id == 2)
1189 std::sort(ordered_boundary_x_node_pt.begin(),
1190 ordered_boundary_x_node_pt.end(),
1195 unsigned n_boundary_y_node =
1199 Vector<Node*> ordered_boundary_y_node_pt(n_boundary_y_node);
1202 for (
unsigned n = 0;
n < n_boundary_y_node;
n++)
1204 ordered_boundary_y_node_pt[
n] =
1209 if (parent_boundary_y_id == 1)
1211 std::sort(ordered_boundary_y_node_pt.begin(),
1212 ordered_boundary_y_node_pt.end(),
1217 for (
unsigned j = 0;
j < x_nnod;
j++)
1223 for (
unsigned j = 0;
j < y_nnod;
j++)
1232 unsigned n_pml_element = this->
nelement();
1238 if (parent_boundary_y_id == 3)
1240 for (
unsigned e = 0;
e < n_pml_element;
e++)
1243 if ((
e % n_pml_x) == (n_pml_x - 1))
1246 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
1249 unsigned n_node = el_pt->nnode();
1250 for (
unsigned inod = 0; inod < n_node; inod++)
1252 if (
e == (n_pml_x - 1))
1254 if (inod == interior_node_nr_helper_2)
1255 el_pt->node_pt(inod) = special_corner_node_pt;
1256 if ((inod % nnode_1d == interior_node_nr_helper_2) &&
1257 (inod > (nnode_1d - 1)))
1260 el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
1264 if (inod == interior_node_nr_helper_3)
1272 if ((inod % nnode_1d) == interior_node_nr_helper_2)
1275 el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
1279 if (inod == interior_node_nr_helper_3)
1292 if (parent_boundary_x_id == 2)
1294 for (
unsigned e = 0;
e < n_pml_element;
e++)
1297 if ((
int)(
e / n_pml_x) == 0)
1300 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
1303 unsigned n_node = el_pt->nnode();
1304 for (
unsigned inod = 0; inod < n_node; inod++)
1307 if (
e == (n_pml_x - 1))
1309 if (((
int)(inod / nnode_1d) == 0) &&
1310 (inod < interior_node_nr_helper_2))
1313 el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
1317 if (inod == (nnode_1d - 1))
1325 if ((
int)(inod / nnode_1d) == 0)
1328 el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
1332 if (inod == interior_node_nr_helper_2)
1346 if ((parent_boundary_x_id == 0) && (parent_boundary_y_id == 3))
1349 unsigned n_boundary_x_node =
1353 Vector<Node*> ordered_boundary_x_node_pt(n_boundary_x_node);
1356 for (
unsigned n = 0;
n < n_boundary_x_node;
n++)
1358 ordered_boundary_x_node_pt[
n] =
1363 if (parent_boundary_x_id == 0)
1365 std::sort(ordered_boundary_x_node_pt.begin(),
1366 ordered_boundary_x_node_pt.end(),
1371 unsigned n_boundary_y_node =
1375 Vector<Node*> ordered_boundary_y_node_pt(n_boundary_y_node);
1378 for (
unsigned n = 0;
n < n_boundary_y_node;
n++)
1380 ordered_boundary_y_node_pt[
n] =
1385 if (parent_boundary_y_id == 3)
1387 std::sort(ordered_boundary_y_node_pt.begin(),
1388 ordered_boundary_y_node_pt.end(),
1393 for (
unsigned j = 0;
j < x_nnod;
j++)
1399 for (
unsigned j = 0;
j < y_nnod;
j++)
1407 unsigned n_pml_element = this->
nelement();
1413 if (parent_boundary_y_id == 3)
1415 for (
unsigned e = 0;
e < n_pml_element;
e++)
1418 if ((
e % n_pml_x) == (n_pml_x - 1))
1421 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
1424 unsigned n_node = el_pt->nnode();
1425 for (
unsigned inod = 0; inod < n_node; inod++)
1427 if (
e == (n_pml_element - 1))
1429 if (inod == interior_node_nr_helper_3)
1431 el_pt->node_pt(inod) = special_corner_node_pt;
1433 if ((inod % nnode_1d == interior_node_nr_helper_2) &&
1434 (inod < interior_node_nr_helper_3))
1437 el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
1441 if (inod == interior_node_nr_helper_3)
1449 if ((inod % nnode_1d) == interior_node_nr_helper_2)
1452 el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
1456 if (inod == interior_node_nr_helper_3)
1469 if (parent_boundary_x_id == 0)
1471 for (
unsigned e = 0;
e < n_pml_element;
e++)
1474 if (
e >= ((n_pml_x) * (n_pml_y - 1)))
1477 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(this->
element_pt(
e));
1480 unsigned n_node = el_pt->nnode();
1481 for (
unsigned inod = 0; inod < n_node; inod++)
1483 if (
e == (n_pml_element - 1))
1485 if (((
unsigned)(inod / nnode_1d) ==
1486 interior_node_nr_helper_2) &&
1487 (inod < interior_node_nr_helper_3))
1490 el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
1494 if (inod == interior_node_nr_helper_3)
1502 if ((
unsigned)(inod / nnode_1d) == interior_node_nr_helper_2)
1505 el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
1509 if (inod == interior_node_nr_helper_3)
1532 namespace TwoDimensionalPMLHelper
1538 template<
class ASSOCIATED_PML_QUAD_ELEMENT>
1541 const unsigned& right_boundary_id,
1542 const unsigned& n_x_right_pml,
1543 const double& width_x_right_pml,
1547 unsigned n_right_boundary_node =
1551 Vector<Node*> ordered_right_boundary_node_pt(n_right_boundary_node);
1554 for (
unsigned n = 0;
n < n_right_boundary_node;
n++)
1556 ordered_right_boundary_node_pt[
n] =
1561 std::sort(ordered_right_boundary_node_pt.begin(),
1562 ordered_right_boundary_node_pt.end(),
1566 unsigned n_y_right_pml =
1570 double l_pml_right_x_start = ordered_right_boundary_node_pt[0]->x(0);
1572 double l_pml_right_x_end =
1573 width_x_right_pml + ordered_right_boundary_node_pt[0]->x(0);
1574 double l_pml_right_y_start = ordered_right_boundary_node_pt[0]->x(1);
1575 double l_pml_right_y_end =
1576 ordered_right_boundary_node_pt[n_right_boundary_node - 1]->x(1);
1579 unsigned right_quadPML_boundary_id = 3;
1582 Mesh* pml_right_mesh_pt = 0;
1588 right_quadPML_boundary_id,
1591 l_pml_right_x_start,
1593 l_pml_right_y_start,
1598 unsigned n_element_pml_right = pml_right_mesh_pt->
nelement();
1599 for (
unsigned e = 0;
e < n_element_pml_right;
e++)
1604 el_pt->
enable_pml(0, l_pml_right_x_start, l_pml_right_x_end);
1613 unsigned npin = values_to_pin.size();
1617 unsigned n_bound_pml_right = pml_right_mesh_pt->
nboundary();
1618 for (
unsigned b = 0;
b < n_bound_pml_right;
b++)
1621 for (
unsigned n = 0;
n < n_node;
n++)
1626 for (
unsigned j = 0;
j < npin;
j++)
1628 unsigned j_val = values_to_pin[
j];
1638 return pml_right_mesh_pt;
1645 template<
class ASSOCIATED_PML_QUAD_ELEMENT>
1648 const unsigned& top_boundary_id,
1649 const unsigned& n_y_top_pml,
1650 const double& width_y_top_pml,
1654 unsigned n_top_boundary_node =
1658 Vector<Node*> ordered_top_boundary_node_pt(n_top_boundary_node);
1661 for (
unsigned n = 0;
n < n_top_boundary_node;
n++)
1663 ordered_top_boundary_node_pt[
n] =
1668 std::sort(ordered_top_boundary_node_pt.begin(),
1669 ordered_top_boundary_node_pt.end(),
1676 double l_pml_top_x_start = ordered_top_boundary_node_pt[0]->x(0);
1677 double l_pml_top_x_end =
1678 ordered_top_boundary_node_pt[n_top_boundary_node - 1]->x(0);
1679 double l_pml_top_y_start = ordered_top_boundary_node_pt[0]->x(1);
1681 double l_pml_top_y_end =
1682 width_y_top_pml + ordered_top_boundary_node_pt[0]->x(1);
1684 unsigned top_quadPML_boundary_id = 0;
1687 Mesh* pml_top_mesh_pt = 0;
1693 top_quadPML_boundary_id,
1703 unsigned n_element_pml_top = pml_top_mesh_pt->
nelement();
1704 for (
unsigned e = 0;
e < n_element_pml_top;
e++)
1709 el_pt->
enable_pml(1, l_pml_top_y_start, l_pml_top_y_end);
1718 unsigned npin = values_to_pin.size();
1723 unsigned n_bound_pml_top = pml_top_mesh_pt->
nboundary();
1724 for (
unsigned b = 0;
b < n_bound_pml_top;
b++)
1727 for (
unsigned n = 0;
n < n_node;
n++)
1732 for (
unsigned j = 0;
j < npin;
j++)
1734 unsigned j_val = values_to_pin[
j];
1744 return pml_top_mesh_pt;
1751 template<
class ASSOCIATED_PML_QUAD_ELEMENT>
1754 const unsigned& left_boundary_id,
1755 const unsigned& n_x_left_pml,
1756 const double& width_x_left_pml,
1760 unsigned n_left_boundary_node =
1764 Vector<Node*> ordered_left_boundary_node_pt(n_left_boundary_node);
1767 for (
unsigned n = 0;
n < n_left_boundary_node;
n++)
1769 ordered_left_boundary_node_pt[
n] =
1774 std::sort(ordered_left_boundary_node_pt.begin(),
1775 ordered_left_boundary_node_pt.end(),
1783 double l_pml_left_x_start =
1785 ordered_left_boundary_node_pt[n_left_boundary_node - 1]->x(0);
1786 double l_pml_left_x_end =
1787 ordered_left_boundary_node_pt[n_left_boundary_node - 1]->x(0);
1788 double l_pml_left_y_start =
1789 ordered_left_boundary_node_pt[n_left_boundary_node - 1]->x(1);
1790 double l_pml_left_y_end = ordered_left_boundary_node_pt[0]->x(1);
1792 unsigned left_quadPML_boundary_id = 1;
1795 Mesh* pml_left_mesh_pt = 0;
1801 left_quadPML_boundary_id,
1811 unsigned n_element_pml_left = pml_left_mesh_pt->
nelement();
1812 for (
unsigned e = 0;
e < n_element_pml_left;
e++)
1817 el_pt->
enable_pml(0, l_pml_left_x_end, l_pml_left_x_start);
1826 unsigned npin = values_to_pin.size();
1831 unsigned n_bound_pml_left = pml_left_mesh_pt->
nboundary();
1832 for (
unsigned b = 0;
b < n_bound_pml_left;
b++)
1835 for (
unsigned n = 0;
n < n_node;
n++)
1840 for (
unsigned j = 0;
j < npin;
j++)
1842 unsigned j_val = values_to_pin[
j];
1852 return pml_left_mesh_pt;
1859 template<
class ASSOCIATED_PML_QUAD_ELEMENT>
1862 const unsigned& bottom_boundary_id,
1863 const unsigned& n_y_bottom_pml,
1864 const double& width_y_bottom_pml,
1868 unsigned n_bottom_boundary_node =
1872 Vector<Node*> ordered_bottom_boundary_node_pt(n_bottom_boundary_node);
1875 for (
unsigned n = 0;
n < n_bottom_boundary_node;
n++)
1877 ordered_bottom_boundary_node_pt[
n] =
1882 std::sort(ordered_bottom_boundary_node_pt.begin(),
1883 ordered_bottom_boundary_node_pt.end(),
1887 unsigned n_x_bottom_pml =
1891 double l_pml_bottom_x_start =
1892 ordered_bottom_boundary_node_pt[n_bottom_boundary_node - 1]->x(0);
1893 double l_pml_bottom_x_end = ordered_bottom_boundary_node_pt[0]->x(0);
1896 double l_pml_bottom_y_start =
1897 -width_y_bottom_pml + ordered_bottom_boundary_node_pt[0]->x(1);
1898 double l_pml_bottom_y_end = ordered_bottom_boundary_node_pt[0]->x(1);
1900 unsigned bottom_quadPML_boundary_id = 2;
1903 Mesh* pml_bottom_mesh_pt = 0;
1906 pml_bottom_mesh_pt =
1909 bottom_quadPML_boundary_id,
1912 l_pml_bottom_x_start,
1914 l_pml_bottom_y_start,
1919 unsigned n_element_pml_bottom = pml_bottom_mesh_pt->
nelement();
1920 for (
unsigned e = 0;
e < n_element_pml_bottom;
e++)
1925 el_pt->
enable_pml(1, l_pml_bottom_y_end, l_pml_bottom_y_start);
1934 unsigned npin = values_to_pin.size();
1939 unsigned n_bound_pml_bottom = pml_bottom_mesh_pt->
nboundary();
1940 for (
unsigned b = 0;
b < n_bound_pml_bottom;
b++)
1943 for (
unsigned n = 0;
n < n_node;
n++)
1948 for (
unsigned j = 0;
j < npin;
j++)
1950 unsigned j_val = values_to_pin[
j];
1960 return pml_bottom_mesh_pt;
1967 template<
class ASSOCIATED_PML_QUAD_ELEMENT>
1969 Mesh* pml_right_mesh_pt,
1970 Mesh* pml_top_mesh_pt,
1972 const unsigned& right_boundary_id,
1977 unsigned parent_boundary_x_id = 2;
1978 unsigned parent_boundary_y_id = 1;
1980 unsigned current_boundary_x_id = 0;
1981 unsigned current_boundary_y_id = 3;
1984 unsigned n_right_boundary_node =
1988 Vector<Node*> ordered_right_boundary_node_pt(n_right_boundary_node);
1991 for (
unsigned n = 0;
n < n_right_boundary_node;
n++)
1993 ordered_right_boundary_node_pt[
n] =
1998 std::sort(ordered_right_boundary_node_pt.begin(),
1999 ordered_right_boundary_node_pt.end(),
2004 unsigned n_x_right_pml =
2006 unsigned n_y_top_pml =
2008 unsigned n_x_boundary_nodes =
2010 unsigned n_y_boundary_nodes =
2015 double l_pml_right_x_start =
2016 ordered_right_boundary_node_pt[n_right_boundary_node - 1]->x(0);
2017 double l_pml_right_x_end =
2021 double l_pml_top_y_start =
2022 ordered_right_boundary_node_pt[n_right_boundary_node - 1]->x(1);
2023 double l_pml_top_y_end =
2029 Mesh* pml_top_right_mesh_pt = 0;
2032 pml_top_right_mesh_pt =
2037 ordered_right_boundary_node_pt[n_right_boundary_node - 1],
2038 parent_boundary_x_id,
2039 parent_boundary_y_id,
2040 current_boundary_x_id,
2041 current_boundary_y_id,
2044 l_pml_right_x_start,
2053 unsigned n_element_pml_top_right = pml_top_right_mesh_pt->
nelement();
2054 for (
unsigned e = 0;
e < n_element_pml_top_right;
e++)
2059 el_pt->
enable_pml(0, l_pml_right_x_start, l_pml_right_x_end);
2060 el_pt->
enable_pml(1, l_pml_top_y_start, l_pml_top_y_end);
2069 unsigned npin = values_to_pin.size();
2074 unsigned n_bound_pml_top_right = pml_top_right_mesh_pt->
nboundary();
2075 for (
unsigned b = 0;
b < n_bound_pml_top_right;
b++)
2078 for (
unsigned n = 0;
n < n_node;
n++)
2081 if ((
b == 1) || (
b == 2))
2083 for (
unsigned j = 0;
j < npin;
j++)
2085 unsigned j_val = values_to_pin[
j];
2095 return pml_top_right_mesh_pt;
2102 template<
class ASSOCIATED_PML_QUAD_ELEMENT>
2104 Mesh* pml_right_mesh_pt,
2105 Mesh* pml_bottom_mesh_pt,
2107 const unsigned& right_boundary_id,
2112 unsigned parent_boundary_x_id = 0;
2113 unsigned parent_boundary_y_id = 1;
2115 unsigned current_boundary_x_id = 2;
2116 unsigned current_boundary_y_id = 3;
2119 unsigned n_right_boundary_node =
2123 Vector<Node*> ordered_right_boundary_node_pt(n_right_boundary_node);
2126 for (
unsigned n = 0;
n < n_right_boundary_node;
n++)
2128 ordered_right_boundary_node_pt[
n] =
2133 std::sort(ordered_right_boundary_node_pt.begin(),
2134 ordered_right_boundary_node_pt.end(),
2139 unsigned n_x_right_pml =
2141 unsigned n_y_bottom_pml =
2143 unsigned n_x_boundary_nodes =
2148 double l_pml_right_x_start = ordered_right_boundary_node_pt[0]->x(0);
2149 double l_pml_right_x_end =
2153 double l_pml_bottom_y_start =
2155 double l_pml_bottom_y_end = ordered_right_boundary_node_pt[0]->x(1);
2158 Mesh* pml_bottom_right_mesh_pt = 0;
2161 pml_bottom_right_mesh_pt =
2166 ordered_right_boundary_node_pt[0],
2167 parent_boundary_x_id,
2168 parent_boundary_y_id,
2169 current_boundary_x_id,
2170 current_boundary_y_id,
2173 l_pml_right_x_start,
2175 l_pml_bottom_y_start,
2182 unsigned n_element_pml_bottom_right =
2183 pml_bottom_right_mesh_pt->
nelement();
2185 for (
unsigned e = 0;
e < n_element_pml_bottom_right;
e++)
2190 el_pt->
enable_pml(0, l_pml_right_x_start, l_pml_right_x_end);
2191 el_pt->
enable_pml(1, l_pml_bottom_y_end, l_pml_bottom_y_start);
2200 unsigned npin = values_to_pin.size();
2205 unsigned n_bound_pml_bottom_right = pml_bottom_right_mesh_pt->
nboundary();
2206 for (
unsigned b = 0;
b < n_bound_pml_bottom_right;
b++)
2209 for (
unsigned n = 0;
n < n_node;
n++)
2212 if ((
b == 0) || (
b == 1))
2214 for (
unsigned j = 0;
j < npin;
j++)
2216 unsigned j_val = values_to_pin[
j];
2226 return pml_bottom_right_mesh_pt;
2233 template<
class ASSOCIATED_PML_QUAD_ELEMENT>
2235 Mesh* pml_left_mesh_pt,
2236 Mesh* pml_top_mesh_pt,
2238 const unsigned& left_boundary_id,
2243 unsigned parent_boundary_x_id = 2;
2244 unsigned parent_boundary_y_id = 3;
2246 unsigned current_boundary_x_id = 0;
2247 unsigned current_boundary_y_id = 1;
2250 unsigned n_left_boundary_node =
2254 Vector<Node*> ordered_left_boundary_node_pt(n_left_boundary_node);
2257 for (
unsigned n = 0;
n < n_left_boundary_node;
n++)
2259 ordered_left_boundary_node_pt[
n] =
2266 std::sort(ordered_left_boundary_node_pt.begin(),
2267 ordered_left_boundary_node_pt.end(),
2272 unsigned n_x_left_pml =
2274 unsigned n_y_top_pml =
2276 unsigned n_y_boundary_nodes =
2281 double l_pml_left_x_start =
2283 double l_pml_left_x_end =
2284 ordered_left_boundary_node_pt[n_left_boundary_node - 1]->x(0);
2285 double l_pml_top_y_start =
2286 ordered_left_boundary_node_pt[n_left_boundary_node - 1]->x(1);
2287 double l_pml_top_y_end =
2293 Mesh* pml_top_left_mesh_pt = 0;
2300 ordered_left_boundary_node_pt[n_left_boundary_node - 1],
2301 parent_boundary_x_id,
2302 parent_boundary_y_id,
2303 current_boundary_x_id,
2304 current_boundary_y_id,
2316 unsigned n_element_pml_top_left = pml_top_left_mesh_pt->
nelement();
2318 for (
unsigned e = 0;
e < n_element_pml_top_left;
e++)
2323 el_pt->
enable_pml(0, l_pml_left_x_end, l_pml_left_x_start);
2324 el_pt->
enable_pml(1, l_pml_top_y_start, l_pml_top_y_end);
2333 unsigned npin = values_to_pin.size();
2338 unsigned n_bound_pml_top_left = pml_top_left_mesh_pt->
nboundary();
2339 for (
unsigned b = 0;
b < n_bound_pml_top_left;
b++)
2342 for (
unsigned n = 0;
n < n_node;
n++)
2345 if ((
b == 2) || (
b == 3))
2347 for (
unsigned j = 0;
j < npin;
j++)
2349 unsigned j_val = values_to_pin[
j];
2359 return pml_top_left_mesh_pt;
2366 template<
class ASSOCIATED_PML_QUAD_ELEMENT>
2368 Mesh* pml_left_mesh_pt,
2369 Mesh* pml_bottom_mesh_pt,
2371 const unsigned& left_boundary_id,
2376 unsigned parent_boundary_x_id = 0;
2377 unsigned parent_boundary_y_id = 3;
2379 unsigned current_boundary_x_id = 2;
2380 unsigned current_boundary_y_id = 1;
2383 unsigned n_left_boundary_node =
2387 Vector<Node*> ordered_left_boundary_node_pt(n_left_boundary_node);
2390 for (
unsigned n = 0;
n < n_left_boundary_node;
n++)
2392 ordered_left_boundary_node_pt[
n] =
2399 std::sort(ordered_left_boundary_node_pt.begin(),
2400 ordered_left_boundary_node_pt.end(),
2405 unsigned n_x_left_pml =
2407 unsigned n_y_bottom_pml =
2412 double l_pml_left_x_start =
2414 double l_pml_left_x_end =
2415 ordered_left_boundary_node_pt[n_left_boundary_node - 1]->x(0);
2416 double l_pml_bottom_y_start =
2418 double l_pml_bottom_y_end = ordered_left_boundary_node_pt[0]->x(1);
2421 Mesh* pml_bottom_left_mesh_pt = 0;
2424 pml_bottom_left_mesh_pt =
2429 ordered_left_boundary_node_pt[0],
2430 parent_boundary_x_id,
2431 parent_boundary_y_id,
2432 current_boundary_x_id,
2433 current_boundary_y_id,
2438 l_pml_bottom_y_start,
2445 unsigned n_element_pml_bottom_left = pml_bottom_left_mesh_pt->
nelement();
2446 for (
unsigned e = 0;
e < n_element_pml_bottom_left;
e++)
2451 el_pt->
enable_pml(0, l_pml_left_x_end, l_pml_left_x_start);
2452 el_pt->
enable_pml(1, l_pml_bottom_y_end, l_pml_bottom_y_start);
2461 unsigned npin = values_to_pin.size();
2466 unsigned n_bound_pml_bottom_left = pml_bottom_left_mesh_pt->
nboundary();
2467 for (
unsigned b = 0;
b < n_bound_pml_bottom_left;
b++)
2470 for (
unsigned n = 0;
n < n_node;
n++)
2473 if ((
b == 0) || (
b == 3))
2475 for (
unsigned j = 0;
j < npin;
j++)
2477 unsigned j_val = values_to_pin[
j];
2487 return pml_bottom_left_mesh_pt;
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
void pin(const unsigned &i)
Pin the i-th stored variable.
Definition: nodes.h:385
void set_value(const unsigned &i, const double &value_)
Definition: nodes.h:271
Definition: elements.h:1313
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
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
FiniteElement * finite_element_pt(const unsigned &e) const
Definition: mesh.h:473
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
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
Definition: mesh.h:448
unsigned long nnode() const
Return number of nodes in the mesh.
Definition: mesh.h:596
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
Definition: mesh.h:460
Vector< Node * > prune_dead_nodes()
Definition: mesh.cc:966
Node *& boundary_node_pt(const unsigned &b, const unsigned &n)
Return pointer to node n on boundary b.
Definition: mesh.h:493
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
void set_obsolete()
Mark node as obsolete.
Definition: nodes.h:1436
Definition: oomph_definitions.h:222
PML mesh, derived from RectangularQuadMesh.
Definition: pml_meshes.h:777
PMLCornerQuadMesh(Mesh *PMLQuad_mesh_x_pt, Mesh *PMLQuad_mesh_y_pt, Mesh *bulk_mesh_pt, Node *special_corner_node_pt, const unsigned &parent_boundary_x_id, const unsigned &parent_boundary_y_id, const unsigned ¤t_boundary_x_id, const unsigned ¤t_boundary_y_id, const unsigned &n_pml_x, const unsigned &n_pml_y, const double &x_pml_start, const double &x_pml_end, const double &y_pml_start, const double &y_pml_end, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Definition: pml_meshes.h:783
Base class for elements with pml capabilities.
Definition: pml_meshes.h:60
bool Pml_is_enabled
Boolean indicating if element is used in pml mode.
Definition: pml_meshes.h:119
virtual ~PMLElementBase()
Virtual destructor.
Definition: pml_meshes.h:72
void enable_pml(const int &direction, const double &interface_border_value, const double &outer_domain_border_value)
Definition: pml_meshes.h:97
void disable_pml()
Definition: pml_meshes.h:76
std::vector< bool > Pml_direction_active
Definition: pml_meshes.h:124
Vector< double > Pml_outer_boundary
Definition: pml_meshes.h:134
Vector< double > Pml_inner_boundary
Definition: pml_meshes.h:129
PMLElementBase()
Constructor.
Definition: pml_meshes.h:63
virtual void values_to_be_pinned_on_outer_pml_boundary(Vector< unsigned > &values_to_pin)=0
Definition: pml_meshes.h:48
Definition: pml_meshes.h:171
virtual void pml_locate_zeta(const Vector< double > &x, FiniteElement *&el_pt)=0
PML mesh class. Policy class for 2D PML meshes.
Definition: pml_meshes.h:187
void pml_locate_zeta(const Vector< double > &x, FiniteElement *&coarse_mesh_el_pt)
Definition: pml_meshes.h:212
PMLQuadMeshBase(const unsigned &n_pml_x, const unsigned &n_pml_y, const double &x_pml_start, const double &x_pml_end, const double &y_pml_start, const double &y_pml_end, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Create the underlying rectangular quad mesh.
Definition: pml_meshes.h:190
PML mesh, derived from RectangularQuadMesh.
Definition: pml_meshes.h:431
PMLQuadMesh(Mesh *bulk_mesh_pt, const unsigned &boundary_id, const unsigned &quad_boundary_id, const unsigned &n_pml_x, const unsigned &n_pml_y, const double &x_pml_start, const double &x_pml_end, const double &y_pml_start, const double &y_pml_end, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Definition: pml_meshes.h:441
Definition: rectangular_quadmesh.template.h:59
const double y_min() const
Return the minimum value of y coordinate.
Definition: rectangular_quadmesh.template.h:252
const double x_max() const
Return the maximum value of x coordinate.
Definition: rectangular_quadmesh.template.h:245
const double y_max() const
Return the maximum value of y coordinate.
Definition: rectangular_quadmesh.template.h:259
const unsigned & ny() const
Return number of elements in y direction.
Definition: rectangular_quadmesh.template.h:231
const double x_min() const
Return the minimum value of x coordinate.
Definition: rectangular_quadmesh.template.h:238
const unsigned & nx() const
Return number of elements in x direction.
Definition: rectangular_quadmesh.template.h:224
Definition: timesteppers.h:231
#define DIM
Definition: linearised_navier_stokes_elements.h:44
bool sorter_bottom_boundary(Node *nod_i_pt, Node *nod_j_pt)
helper function for sorting the bottom boundary nodes
Definition: pml_meshes.cc:57
Mesh * create_bottom_right_pml_mesh(Mesh *pml_right_mesh_pt, Mesh *pml_bottom_mesh_pt, Mesh *bulk_mesh_pt, const unsigned &right_boundary_id, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Definition: pml_meshes.h:2103
Mesh * create_top_right_pml_mesh(Mesh *pml_right_mesh_pt, Mesh *pml_top_mesh_pt, Mesh *bulk_mesh_pt, const unsigned &right_boundary_id, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Definition: pml_meshes.h:1968
Mesh * create_top_pml_mesh(Mesh *bulk_mesh_pt, const unsigned &top_boundary_id, const unsigned &n_y_top_pml, const double &width_y_top_pml, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Definition: pml_meshes.h:1646
Mesh * create_top_left_pml_mesh(Mesh *pml_left_mesh_pt, Mesh *pml_top_mesh_pt, Mesh *bulk_mesh_pt, const unsigned &left_boundary_id, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Definition: pml_meshes.h:2234
bool sorter_top_boundary(Node *nod_i_pt, Node *nod_j_pt)
helper function for sorting the top boundary nodes
Definition: pml_meshes.cc:45
Mesh * create_bottom_left_pml_mesh(Mesh *pml_left_mesh_pt, Mesh *pml_bottom_mesh_pt, Mesh *bulk_mesh_pt, const unsigned &left_boundary_id, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Definition: pml_meshes.h:2367
Mesh * create_bottom_pml_mesh(Mesh *bulk_mesh_pt, const unsigned &bottom_boundary_id, const unsigned &n_y_bottom_pml, const double &width_y_bottom_pml, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Definition: pml_meshes.h:1860
Mesh * create_left_pml_mesh(Mesh *bulk_mesh_pt, const unsigned &left_boundary_id, const unsigned &n_x_left_pml, const double &width_x_left_pml, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Definition: pml_meshes.h:1752
bool sorter_right_boundary(Node *nod_i_pt, Node *nod_j_pt)
helper function for sorting the right boundary nodes
Definition: pml_meshes.cc:39
bool sorter_left_boundary(Node *nod_i_pt, Node *nod_j_pt)
helper function for sorting the left boundary nodes
Definition: pml_meshes.cc:51
Mesh * create_right_pml_mesh(Mesh *bulk_mesh_pt, const unsigned &right_boundary_id, const unsigned &n_x_right_pml, const double &width_x_right_pml, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Definition: pml_meshes.h:1539
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
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