oomph::TwoDimensionalPMLHelper Namespace Reference

Functions

bool sorter_right_boundary (Node *nod_i_pt, Node *nod_j_pt)
 helper function for sorting the right boundary nodes More...
 
bool sorter_top_boundary (Node *nod_i_pt, Node *nod_j_pt)
 helper function for sorting the top boundary nodes More...
 
bool sorter_left_boundary (Node *nod_i_pt, Node *nod_j_pt)
 helper function for sorting the left boundary nodes More...
 
bool sorter_bottom_boundary (Node *nod_i_pt, Node *nod_j_pt)
 helper function for sorting the bottom boundary nodes More...
 
template<class ASSOCIATED_PML_QUAD_ELEMENT >
Meshcreate_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)
 
template<class ASSOCIATED_PML_QUAD_ELEMENT >
Meshcreate_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)
 
template<class ASSOCIATED_PML_QUAD_ELEMENT >
Meshcreate_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)
 
template<class ASSOCIATED_PML_QUAD_ELEMENT >
Meshcreate_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)
 
template<class ASSOCIATED_PML_QUAD_ELEMENT >
Meshcreate_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)
 
template<class ASSOCIATED_PML_QUAD_ELEMENT >
Meshcreate_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)
 
template<class ASSOCIATED_PML_QUAD_ELEMENT >
Meshcreate_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)
 
template<class ASSOCIATED_PML_QUAD_ELEMENT >
Meshcreate_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)
 

Detailed Description

Namespace with functions that allow the construction of PML layers on axis aligned boundaries

/////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// All helper routines for 2D bulk boundary mesh usage in order to generate PML meshes aligned to the main mesh

///////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// All helper routines for 2D bulk boundary mesh usage in order to generate PML meshes aligned to the main mesh

Function Documentation

◆ create_bottom_left_pml_mesh()

template<class ASSOCIATED_PML_QUAD_ELEMENT >
Mesh* oomph::TwoDimensionalPMLHelper::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 
)

"Constructor" for PML bottom left corner mesh, aligned with the existing PML meshes

Relevant boundary id's to be used in construction Parent id refers to already existing PML meshes

Sort them from lowest to highest (in y coordinate) sorter_right_boundary is still functional, as the sorting is performed by the same criterion

Number of elements and boundary nodes to be acted upon during construction are extracted from the 'parent' PML meshes

Specific PML sizes needed, taken directly from physical domain and existing PML meshes

The enabling must be perfromed in both x- and y-directions as this is a corner PML mesh

Return the finalized mesh, with PML enabled and boundary conditions added

2373  {
2376  unsigned parent_boundary_x_id = 0;
2377  unsigned parent_boundary_y_id = 3;
2378  // Current id refers to the mesh that is to be constructed
2379  unsigned current_boundary_x_id = 2;
2380  unsigned current_boundary_y_id = 1;
2381 
2382  // Look at the left boundary of the triangular mesh
2383  unsigned n_left_boundary_node =
2384  bulk_mesh_pt->nboundary_node(left_boundary_id);
2385 
2386  // Create a vector of ordered boundary nodes
2387  Vector<Node*> ordered_left_boundary_node_pt(n_left_boundary_node);
2388 
2389  // Fill the vector with the nodes on the respective boundary
2390  for (unsigned n = 0; n < n_left_boundary_node; n++)
2391  {
2392  ordered_left_boundary_node_pt[n] =
2393  bulk_mesh_pt->boundary_node_pt(left_boundary_id, n);
2394  }
2395 
2399  std::sort(ordered_left_boundary_node_pt.begin(),
2400  ordered_left_boundary_node_pt.end(),
2402 
2405  unsigned n_x_left_pml =
2406  pml_left_mesh_pt->nboundary_element(parent_boundary_x_id);
2407  unsigned n_y_bottom_pml =
2408  pml_bottom_mesh_pt->nboundary_element(parent_boundary_y_id);
2409 
2412  double l_pml_left_x_start =
2413  pml_left_mesh_pt->boundary_node_pt(parent_boundary_x_id, 0)->x(0);
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 =
2417  pml_bottom_mesh_pt->boundary_node_pt(parent_boundary_y_id, 0)->x(1);
2418  double l_pml_bottom_y_end = ordered_left_boundary_node_pt[0]->x(1);
2419 
2420  // Create the mesh to be designated to the PML
2421  Mesh* pml_bottom_left_mesh_pt = 0;
2422 
2423  // Build the bottom left corner PML mesh
2424  pml_bottom_left_mesh_pt =
2425  new PMLCornerQuadMesh<ASSOCIATED_PML_QUAD_ELEMENT>(
2426  pml_left_mesh_pt,
2427  pml_bottom_mesh_pt,
2428  bulk_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,
2434  n_x_left_pml,
2435  n_y_bottom_pml,
2436  l_pml_left_x_start,
2437  l_pml_left_x_end,
2438  l_pml_bottom_y_start,
2439  l_pml_bottom_y_end,
2440  time_stepper_pt);
2441 
2442  // Enable PML damping on the entire mesh
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++)
2447  {
2448  // Upcast
2449  PMLElementBase<2>* el_pt = dynamic_cast<PMLElementBase<2>*>(
2450  pml_bottom_left_mesh_pt->element_pt(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);
2453  }
2454 
2455  // Get the values to be pinned from the first element (which we
2456  // assume exists!)
2457  PMLElementBase<2>* el_pt = dynamic_cast<PMLElementBase<2>*>(
2458  pml_bottom_left_mesh_pt->element_pt(0));
2459  Vector<unsigned> values_to_pin;
2460  el_pt->values_to_be_pinned_on_outer_pml_boundary(values_to_pin);
2461  unsigned npin = values_to_pin.size();
2462 
2463  // Exterior boundary needs to be set to Dirichlet 0
2464  // for both real and imaginary parts of all fields
2465  // in the problem
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++)
2468  {
2469  unsigned n_node = pml_bottom_left_mesh_pt->nboundary_node(b);
2470  for (unsigned n = 0; n < n_node; n++)
2471  {
2472  Node* nod_pt = pml_bottom_left_mesh_pt->boundary_node_pt(b, n);
2473  if ((b == 0) || (b == 3))
2474  {
2475  for (unsigned j = 0; j < npin; j++)
2476  {
2477  unsigned j_val = values_to_pin[j];
2478  nod_pt->pin(j_val);
2479  nod_pt->set_value(j_val, 0.0);
2480  }
2481  }
2482  }
2483  }
2484 
2487  return pml_bottom_left_mesh_pt;
2488  }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Scalar * b
Definition: benchVecAdd.cpp:17
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
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References b, oomph::Mesh::boundary_node_pt(), e(), oomph::Mesh::element_pt(), oomph::PMLElementBase< DIM >::enable_pml(), j, n, oomph::Mesh::nboundary(), oomph::Mesh::nboundary_element(), oomph::Mesh::nboundary_node(), oomph::Mesh::nelement(), oomph::Data::pin(), oomph::Data::set_value(), sorter_right_boundary(), oomph::PMLElementBase< DIM >::values_to_be_pinned_on_outer_pml_boundary(), and oomph::Node::x().

Referenced by PMLHelmholtzMGProblem< ELEMENT >::create_pml_meshes(), PMLProblem< ELEMENT >::create_pml_meshes(), ElasticAnnulusProblem< ELASTICITY_ELEMENT >::create_pml_meshes(), and oomph::RefineableQuadMeshWithMovingCylinder< ELEMENT >::RefineableQuadMeshWithMovingCylinder().

◆ create_bottom_pml_mesh()

template<class ASSOCIATED_PML_QUAD_ELEMENT >
Mesh* oomph::TwoDimensionalPMLHelper::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 
)

"Constructor" for PML mesh,aligned with the bottom physical domain boundary

PML layer width subtracted from the bulk mesh lower boundary coordinate

Return the finalized mesh, with PML enabled and boundary conditions added

1866  {
1867  // Look at the bottom boundary of the triangular mesh
1868  unsigned n_bottom_boundary_node =
1869  bulk_mesh_pt->nboundary_node(bottom_boundary_id);
1870 
1871  // Create a vector of ordered boundary nodes
1872  Vector<Node*> ordered_bottom_boundary_node_pt(n_bottom_boundary_node);
1873 
1874  // Fill the vector with the nodes on the respective boundary
1875  for (unsigned n = 0; n < n_bottom_boundary_node; n++)
1876  {
1877  ordered_bottom_boundary_node_pt[n] =
1878  bulk_mesh_pt->boundary_node_pt(bottom_boundary_id, n);
1879  }
1880 
1881  // Sort them from highest to lowest (in x coordinate)
1882  std::sort(ordered_bottom_boundary_node_pt.begin(),
1883  ordered_bottom_boundary_node_pt.end(),
1885 
1886  // The number of elements in y is taken from the triangular mesh
1887  unsigned n_x_bottom_pml =
1888  bulk_mesh_pt->nboundary_element(bottom_boundary_id);
1889 
1890  // Specific PML sizes needed, taken directly from physical domain
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);
1899 
1900  unsigned bottom_quadPML_boundary_id = 2;
1901 
1902  // Create the mesh to be designated to the PML
1903  Mesh* pml_bottom_mesh_pt = 0;
1904 
1905  // Build the bottom PML mesh
1906  pml_bottom_mesh_pt =
1907  new PMLQuadMesh<ASSOCIATED_PML_QUAD_ELEMENT>(bulk_mesh_pt,
1908  bottom_boundary_id,
1909  bottom_quadPML_boundary_id,
1910  n_x_bottom_pml,
1911  n_y_bottom_pml,
1912  l_pml_bottom_x_start,
1913  l_pml_bottom_x_end,
1914  l_pml_bottom_y_start,
1915  l_pml_bottom_y_end,
1916  time_stepper_pt);
1917 
1918  // Enable PML damping on the entire mesh
1919  unsigned n_element_pml_bottom = pml_bottom_mesh_pt->nelement();
1920  for (unsigned e = 0; e < n_element_pml_bottom; e++)
1921  {
1922  // Upcast
1923  PMLElementBase<2>* el_pt =
1924  dynamic_cast<PMLElementBase<2>*>(pml_bottom_mesh_pt->element_pt(e));
1925  el_pt->enable_pml(1, l_pml_bottom_y_end, l_pml_bottom_y_start);
1926  }
1927 
1928  // Get the values to be pinned from the first element (which we
1929  // assume exists!)
1930  PMLElementBase<2>* el_pt =
1931  dynamic_cast<PMLElementBase<2>*>(pml_bottom_mesh_pt->element_pt(0));
1932  Vector<unsigned> values_to_pin;
1933  el_pt->values_to_be_pinned_on_outer_pml_boundary(values_to_pin);
1934  unsigned npin = values_to_pin.size();
1935 
1936  // Exterior boundary needs to be set to Dirichlet 0
1937  // for both real and imaginary parts of all fields
1938  // in the problem
1939  unsigned n_bound_pml_bottom = pml_bottom_mesh_pt->nboundary();
1940  for (unsigned b = 0; b < n_bound_pml_bottom; b++)
1941  {
1942  unsigned n_node = pml_bottom_mesh_pt->nboundary_node(b);
1943  for (unsigned n = 0; n < n_node; n++)
1944  {
1945  Node* nod_pt = pml_bottom_mesh_pt->boundary_node_pt(b, n);
1946  if (b == 0)
1947  {
1948  for (unsigned j = 0; j < npin; j++)
1949  {
1950  unsigned j_val = values_to_pin[j];
1951  nod_pt->pin(j_val);
1952  nod_pt->set_value(j_val, 0.0);
1953  }
1954  }
1955  }
1956  }
1957 
1960  return pml_bottom_mesh_pt;
1961  }
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

References b, oomph::Mesh::boundary_node_pt(), e(), oomph::Mesh::element_pt(), oomph::PMLElementBase< DIM >::enable_pml(), j, n, oomph::Mesh::nboundary(), oomph::Mesh::nboundary_element(), oomph::Mesh::nboundary_node(), oomph::Mesh::nelement(), oomph::Data::pin(), oomph::Data::set_value(), sorter_bottom_boundary(), and oomph::PMLElementBase< DIM >::values_to_be_pinned_on_outer_pml_boundary().

Referenced by PMLHelmholtzMGProblem< ELEMENT >::create_pml_meshes(), PMLFourierDecomposedHelmholtzProblem< ELEMENT >::create_pml_meshes(), PMLProblem< ELEMENT >::create_pml_meshes(), and ElasticAnnulusProblem< ELASTICITY_ELEMENT >::create_pml_meshes().

◆ create_bottom_right_pml_mesh()

template<class ASSOCIATED_PML_QUAD_ELEMENT >
Mesh* oomph::TwoDimensionalPMLHelper::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 
)

"Constructor" for PML bottom right corner mesh, aligned with the existing PML meshes

Relevant boundary id's to be used in construction Parent id refers to already existing PML meshes

Number of elements and boundary nodes to be acted upon during construction are extracted from the 'parent' PML meshes

Specific PML sizes needed, taken directly from physical domain and existing PML meshes

The enabling must be perfromed in both x- and y-directions as this is a corner PML mesh

Return the finalized mesh, with PML enabled and boundary conditions added

2109  {
2112  unsigned parent_boundary_x_id = 0;
2113  unsigned parent_boundary_y_id = 1;
2114  // Current id refers to the mesh that is to be constructed
2115  unsigned current_boundary_x_id = 2;
2116  unsigned current_boundary_y_id = 3;
2117 
2118  // Look at the right boundary of the triangular mesh
2119  unsigned n_right_boundary_node =
2120  bulk_mesh_pt->nboundary_node(right_boundary_id);
2121 
2122  // Create a vector of ordered boundary nodes
2123  Vector<Node*> ordered_right_boundary_node_pt(n_right_boundary_node);
2124 
2125  // Fill the vector with the nodes on the respective boundary
2126  for (unsigned n = 0; n < n_right_boundary_node; n++)
2127  {
2128  ordered_right_boundary_node_pt[n] =
2129  bulk_mesh_pt->boundary_node_pt(right_boundary_id, n);
2130  }
2131 
2132  // Sort them from lowest to highest (in y coordinate)
2133  std::sort(ordered_right_boundary_node_pt.begin(),
2134  ordered_right_boundary_node_pt.end(),
2136 
2139  unsigned n_x_right_pml =
2140  pml_right_mesh_pt->nboundary_element(parent_boundary_x_id);
2141  unsigned n_y_bottom_pml =
2142  pml_bottom_mesh_pt->nboundary_element(parent_boundary_y_id);
2143  unsigned n_x_boundary_nodes =
2144  pml_right_mesh_pt->nboundary_node(parent_boundary_x_id);
2145 
2148  double l_pml_right_x_start = ordered_right_boundary_node_pt[0]->x(0);
2149  double l_pml_right_x_end =
2150  pml_right_mesh_pt
2151  ->boundary_node_pt(parent_boundary_x_id, n_x_boundary_nodes - 1)
2152  ->x(0);
2153  double l_pml_bottom_y_start =
2154  pml_bottom_mesh_pt->boundary_node_pt(parent_boundary_y_id, 0)->x(1);
2155  double l_pml_bottom_y_end = ordered_right_boundary_node_pt[0]->x(1);
2156 
2157  // Create the mesh to be designated to the PML
2158  Mesh* pml_bottom_right_mesh_pt = 0;
2159 
2160  // Build the bottom right corner PML mesh
2161  pml_bottom_right_mesh_pt =
2162  new PMLCornerQuadMesh<ASSOCIATED_PML_QUAD_ELEMENT>(
2163  pml_right_mesh_pt,
2164  pml_bottom_mesh_pt,
2165  bulk_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,
2171  n_x_right_pml,
2172  n_y_bottom_pml,
2173  l_pml_right_x_start,
2174  l_pml_right_x_end,
2175  l_pml_bottom_y_start,
2176  l_pml_bottom_y_end,
2177  time_stepper_pt);
2178 
2179  // Enable PML damping on the entire mesh
2182  unsigned n_element_pml_bottom_right =
2183  pml_bottom_right_mesh_pt->nelement();
2184 
2185  for (unsigned e = 0; e < n_element_pml_bottom_right; e++)
2186  {
2187  // Upcast
2188  PMLElementBase<2>* el_pt = dynamic_cast<PMLElementBase<2>*>(
2189  pml_bottom_right_mesh_pt->element_pt(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);
2192  }
2193 
2194  // Get the values to be pinned from the first element (which we
2195  // assume exists!)
2196  PMLElementBase<2>* el_pt = dynamic_cast<PMLElementBase<2>*>(
2197  pml_bottom_right_mesh_pt->element_pt(0));
2198  Vector<unsigned> values_to_pin;
2199  el_pt->values_to_be_pinned_on_outer_pml_boundary(values_to_pin);
2200  unsigned npin = values_to_pin.size();
2201 
2202  // Exterior boundary needs to be set to Dirichlet 0
2203  // for both real and imaginary parts of all fields
2204  // in the problem
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++)
2207  {
2208  unsigned n_node = pml_bottom_right_mesh_pt->nboundary_node(b);
2209  for (unsigned n = 0; n < n_node; n++)
2210  {
2211  Node* nod_pt = pml_bottom_right_mesh_pt->boundary_node_pt(b, n);
2212  if ((b == 0) || (b == 1))
2213  {
2214  for (unsigned j = 0; j < npin; j++)
2215  {
2216  unsigned j_val = values_to_pin[j];
2217  nod_pt->pin(j_val);
2218  nod_pt->set_value(j_val, 0.0);
2219  }
2220  }
2221  }
2222  }
2223 
2226  return pml_bottom_right_mesh_pt;
2227  }

References b, oomph::Mesh::boundary_node_pt(), e(), oomph::Mesh::element_pt(), oomph::PMLElementBase< DIM >::enable_pml(), j, n, oomph::Mesh::nboundary(), oomph::Mesh::nboundary_element(), oomph::Mesh::nboundary_node(), oomph::Mesh::nelement(), oomph::Data::pin(), oomph::Data::set_value(), sorter_right_boundary(), oomph::PMLElementBase< DIM >::values_to_be_pinned_on_outer_pml_boundary(), and oomph::Node::x().

Referenced by PMLHelmholtzMGProblem< ELEMENT >::create_pml_meshes(), PMLFourierDecomposedHelmholtzProblem< ELEMENT >::create_pml_meshes(), PMLProblem< ELEMENT >::create_pml_meshes(), ElasticAnnulusProblem< ELASTICITY_ELEMENT >::create_pml_meshes(), and oomph::RefineableQuadMeshWithMovingCylinder< ELEMENT >::RefineableQuadMeshWithMovingCylinder().

◆ create_left_pml_mesh()

template<class ASSOCIATED_PML_QUAD_ELEMENT >
Mesh* oomph::TwoDimensionalPMLHelper::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 
)

"Constructor" for PML mesh, aligned with the left physical domain boundary

PML layer width subtracted from left bulk mesh coordinate

Return the finalized mesh, with PML enabled and boundary conditions added

1758  {
1759  // Look at the left boundary of the triangular mesh
1760  unsigned n_left_boundary_node =
1761  bulk_mesh_pt->nboundary_node(left_boundary_id);
1762 
1763  // Create a vector of ordered boundary nodes
1764  Vector<Node*> ordered_left_boundary_node_pt(n_left_boundary_node);
1765 
1766  // Fill the vector with the nodes on the respective boundary
1767  for (unsigned n = 0; n < n_left_boundary_node; n++)
1768  {
1769  ordered_left_boundary_node_pt[n] =
1770  bulk_mesh_pt->boundary_node_pt(left_boundary_id, n);
1771  }
1772 
1773  // Sort them from lowest to highest (in y coordinate)
1774  std::sort(ordered_left_boundary_node_pt.begin(),
1775  ordered_left_boundary_node_pt.end(),
1777 
1778  // The number of elements in y is taken from the triangular mesh
1779  unsigned n_y_left_pml = bulk_mesh_pt->nboundary_element(left_boundary_id);
1780 
1781  // Specific PML sizes needed, taken directly from physical domain
1783  double l_pml_left_x_start =
1784  -width_x_left_pml +
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);
1791 
1792  unsigned left_quadPML_boundary_id = 1;
1793 
1794  // Create the mesh to be designated to the PML
1795  Mesh* pml_left_mesh_pt = 0;
1796 
1797  // Build the left PML mesh
1798  pml_left_mesh_pt =
1799  new PMLQuadMesh<ASSOCIATED_PML_QUAD_ELEMENT>(bulk_mesh_pt,
1800  left_boundary_id,
1801  left_quadPML_boundary_id,
1802  n_x_left_pml,
1803  n_y_left_pml,
1804  l_pml_left_x_start,
1805  l_pml_left_x_end,
1806  l_pml_left_y_start,
1807  l_pml_left_y_end,
1808  time_stepper_pt);
1809 
1810  // Enable PML damping on the entire mesh
1811  unsigned n_element_pml_left = pml_left_mesh_pt->nelement();
1812  for (unsigned e = 0; e < n_element_pml_left; e++)
1813  {
1814  // Upcast
1815  PMLElementBase<2>* el_pt =
1816  dynamic_cast<PMLElementBase<2>*>(pml_left_mesh_pt->element_pt(e));
1817  el_pt->enable_pml(0, l_pml_left_x_end, l_pml_left_x_start);
1818  }
1819 
1820  // Get the values to be pinned from the first element (which we
1821  // assume exists!)
1822  PMLElementBase<2>* el_pt =
1823  dynamic_cast<PMLElementBase<2>*>(pml_left_mesh_pt->element_pt(0));
1824  Vector<unsigned> values_to_pin;
1825  el_pt->values_to_be_pinned_on_outer_pml_boundary(values_to_pin);
1826  unsigned npin = values_to_pin.size();
1827 
1828  // Exterior boundary needs to be set to Dirichlet 0
1829  // for both real and imaginary parts of all fields
1830  // in the problem
1831  unsigned n_bound_pml_left = pml_left_mesh_pt->nboundary();
1832  for (unsigned b = 0; b < n_bound_pml_left; b++)
1833  {
1834  unsigned n_node = pml_left_mesh_pt->nboundary_node(b);
1835  for (unsigned n = 0; n < n_node; n++)
1836  {
1837  Node* nod_pt = pml_left_mesh_pt->boundary_node_pt(b, n);
1838  if (b == 3)
1839  {
1840  for (unsigned j = 0; j < npin; j++)
1841  {
1842  unsigned j_val = values_to_pin[j];
1843  nod_pt->pin(j_val);
1844  nod_pt->set_value(j_val, 0.0);
1845  }
1846  }
1847  }
1848  }
1849 
1852  return pml_left_mesh_pt;
1853  }
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

References b, oomph::Mesh::boundary_node_pt(), e(), oomph::Mesh::element_pt(), oomph::PMLElementBase< DIM >::enable_pml(), j, n, oomph::Mesh::nboundary(), oomph::Mesh::nboundary_element(), oomph::Mesh::nboundary_node(), oomph::Mesh::nelement(), oomph::Data::pin(), oomph::Data::set_value(), sorter_left_boundary(), and oomph::PMLElementBase< DIM >::values_to_be_pinned_on_outer_pml_boundary().

Referenced by PMLHelmholtzMGProblem< ELEMENT >::create_pml_meshes(), PMLProblem< ELEMENT >::create_pml_meshes(), and ElasticAnnulusProblem< ELASTICITY_ELEMENT >::create_pml_meshes().

◆ create_right_pml_mesh()

template<class ASSOCIATED_PML_QUAD_ELEMENT >
Mesh* oomph::TwoDimensionalPMLHelper::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 
)

"Constructor" for PML mesh,aligned with the right physical domain boundary

PML layer with added to the bulk mesh coordinate

Return the finalized mesh, with PML enabled and boundary conditions added

1545  {
1546  // Look at the right boundary of the triangular mesh
1547  unsigned n_right_boundary_node =
1548  bulk_mesh_pt->nboundary_node(right_boundary_id);
1549 
1550  // Create a vector of ordered boundary nodes
1551  Vector<Node*> ordered_right_boundary_node_pt(n_right_boundary_node);
1552 
1553  // Fill the vector with the nodes on the respective boundary
1554  for (unsigned n = 0; n < n_right_boundary_node; n++)
1555  {
1556  ordered_right_boundary_node_pt[n] =
1557  bulk_mesh_pt->boundary_node_pt(right_boundary_id, n);
1558  }
1559 
1560  // Sort them from lowest to highest (in y coordinate)
1561  std::sort(ordered_right_boundary_node_pt.begin(),
1562  ordered_right_boundary_node_pt.end(),
1564 
1565  // The number of elements in y is taken from the triangular mesh
1566  unsigned n_y_right_pml =
1567  bulk_mesh_pt->nboundary_element(right_boundary_id);
1568 
1569  // Specific PML sizes needed, taken directly from physical domain
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);
1577 
1578  // Rectangular boundary id to be merged with triangular mesh
1579  unsigned right_quadPML_boundary_id = 3;
1580 
1581  // Create the mesh to be designated to the PML
1582  Mesh* pml_right_mesh_pt = 0;
1583 
1584  // Build the right one
1585  pml_right_mesh_pt =
1586  new PMLQuadMesh<ASSOCIATED_PML_QUAD_ELEMENT>(bulk_mesh_pt,
1587  right_boundary_id,
1588  right_quadPML_boundary_id,
1589  n_x_right_pml,
1590  n_y_right_pml,
1591  l_pml_right_x_start,
1592  l_pml_right_x_end,
1593  l_pml_right_y_start,
1594  l_pml_right_y_end,
1595  time_stepper_pt);
1596 
1597  // Enable PML damping on the entire mesh
1598  unsigned n_element_pml_right = pml_right_mesh_pt->nelement();
1599  for (unsigned e = 0; e < n_element_pml_right; e++)
1600  {
1601  // Upcast
1602  PMLElementBase<2>* el_pt =
1603  dynamic_cast<PMLElementBase<2>*>(pml_right_mesh_pt->element_pt(e));
1604  el_pt->enable_pml(0, l_pml_right_x_start, l_pml_right_x_end);
1605  }
1606 
1607  // Get the values to be pinned from the first element (which we
1608  // assume exists!)
1609  PMLElementBase<2>* el_pt =
1610  dynamic_cast<PMLElementBase<2>*>(pml_right_mesh_pt->element_pt(0));
1611  Vector<unsigned> values_to_pin;
1612  el_pt->values_to_be_pinned_on_outer_pml_boundary(values_to_pin);
1613  unsigned npin = values_to_pin.size();
1614 
1615  // Exterior boundary needs to be set to Dirichlet 0
1616  // in both real and imaginary parts
1617  unsigned n_bound_pml_right = pml_right_mesh_pt->nboundary();
1618  for (unsigned b = 0; b < n_bound_pml_right; b++)
1619  {
1620  unsigned n_node = pml_right_mesh_pt->nboundary_node(b);
1621  for (unsigned n = 0; n < n_node; n++)
1622  {
1623  Node* nod_pt = pml_right_mesh_pt->boundary_node_pt(b, n);
1624  if (b == 1)
1625  {
1626  for (unsigned j = 0; j < npin; j++)
1627  {
1628  unsigned j_val = values_to_pin[j];
1629  nod_pt->pin(j_val);
1630  nod_pt->set_value(j_val, 0.0);
1631  }
1632  }
1633  }
1634  }
1635 
1638  return pml_right_mesh_pt;
1639  }

References b, oomph::Mesh::boundary_node_pt(), e(), oomph::Mesh::element_pt(), oomph::PMLElementBase< DIM >::enable_pml(), j, n, oomph::Mesh::nboundary(), oomph::Mesh::nboundary_element(), oomph::Mesh::nboundary_node(), oomph::Mesh::nelement(), oomph::Data::pin(), oomph::Data::set_value(), sorter_right_boundary(), and oomph::PMLElementBase< DIM >::values_to_be_pinned_on_outer_pml_boundary().

Referenced by PMLHelmholtzMGProblem< ELEMENT >::create_pml_meshes(), PMLFourierDecomposedHelmholtzProblem< ELEMENT >::create_pml_meshes(), PMLProblem< ELEMENT >::create_pml_meshes(), and ElasticAnnulusProblem< ELASTICITY_ELEMENT >::create_pml_meshes().

◆ create_top_left_pml_mesh()

template<class ASSOCIATED_PML_QUAD_ELEMENT >
Mesh* oomph::TwoDimensionalPMLHelper::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 
)

"Constructor" for PML top left corner mesh, aligned with the existing PML meshes

Relevant boundary id's to be used in construction Parent id refers to already existing PML meshes

Sort them from lowest to highest (in y coordinate) sorter_right_boundary is still functional, as the sorting is performed by the same criterion

Number of elements and boundary nodes to be acted upon during construction are extracted from the 'parent' PML meshes

Specific PML sizes needed, taken directly from physical domain and existing PML meshes

The enabling must be perfromed in both x- and y-directions as this is a corner PML mesh

Return the finalized mesh, with PML enabled and boundary conditions added

2240  {
2243  unsigned parent_boundary_x_id = 2;
2244  unsigned parent_boundary_y_id = 3;
2245  // Current id refers to the mesh that is to be constructed
2246  unsigned current_boundary_x_id = 0;
2247  unsigned current_boundary_y_id = 1;
2248 
2249  // Look at the left boundary of the triangular mesh
2250  unsigned n_left_boundary_node =
2251  bulk_mesh_pt->nboundary_node(left_boundary_id);
2252 
2253  // Create a vector of ordered boundary nodes
2254  Vector<Node*> ordered_left_boundary_node_pt(n_left_boundary_node);
2255 
2256  // Fill the vector with the nodes on the respective boundary
2257  for (unsigned n = 0; n < n_left_boundary_node; n++)
2258  {
2259  ordered_left_boundary_node_pt[n] =
2260  bulk_mesh_pt->boundary_node_pt(left_boundary_id, n);
2261  }
2262 
2266  std::sort(ordered_left_boundary_node_pt.begin(),
2267  ordered_left_boundary_node_pt.end(),
2269 
2272  unsigned n_x_left_pml =
2273  pml_left_mesh_pt->nboundary_element(parent_boundary_x_id);
2274  unsigned n_y_top_pml =
2275  pml_top_mesh_pt->nboundary_element(parent_boundary_y_id);
2276  unsigned n_y_boundary_nodes =
2277  pml_top_mesh_pt->nboundary_node(parent_boundary_y_id);
2278 
2281  double l_pml_left_x_start =
2282  pml_left_mesh_pt->boundary_node_pt(parent_boundary_x_id, 0)->x(0);
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 =
2288  pml_top_mesh_pt
2289  ->boundary_node_pt(parent_boundary_y_id, n_y_boundary_nodes - 1)
2290  ->x(1);
2291 
2292  // Create the mesh to be designated to the PML
2293  Mesh* pml_top_left_mesh_pt = 0;
2294 
2295  // Build the top left corner PML mesh
2296  pml_top_left_mesh_pt = new PMLCornerQuadMesh<ASSOCIATED_PML_QUAD_ELEMENT>(
2297  pml_left_mesh_pt,
2298  pml_top_mesh_pt,
2299  bulk_mesh_pt,
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,
2305  n_x_left_pml,
2306  n_y_top_pml,
2307  l_pml_left_x_start,
2308  l_pml_left_x_end,
2309  l_pml_top_y_start,
2310  l_pml_top_y_end,
2311  time_stepper_pt);
2312 
2313  // Enable PML damping on the entire mesh
2316  unsigned n_element_pml_top_left = pml_top_left_mesh_pt->nelement();
2317 
2318  for (unsigned e = 0; e < n_element_pml_top_left; e++)
2319  {
2320  // Upcast
2321  PMLElementBase<2>* el_pt =
2322  dynamic_cast<PMLElementBase<2>*>(pml_top_left_mesh_pt->element_pt(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);
2325  }
2326 
2327  // Get the values to be pinned from the first element (which we
2328  // assume exists!)
2329  PMLElementBase<2>* el_pt =
2330  dynamic_cast<PMLElementBase<2>*>(pml_top_left_mesh_pt->element_pt(0));
2331  Vector<unsigned> values_to_pin;
2332  el_pt->values_to_be_pinned_on_outer_pml_boundary(values_to_pin);
2333  unsigned npin = values_to_pin.size();
2334 
2335  // Exterior boundary needs to be set to Dirichlet 0
2336  // for both real and imaginary parts of all fields
2337  // in the problem
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++)
2340  {
2341  unsigned n_node = pml_top_left_mesh_pt->nboundary_node(b);
2342  for (unsigned n = 0; n < n_node; n++)
2343  {
2344  Node* nod_pt = pml_top_left_mesh_pt->boundary_node_pt(b, n);
2345  if ((b == 2) || (b == 3))
2346  {
2347  for (unsigned j = 0; j < npin; j++)
2348  {
2349  unsigned j_val = values_to_pin[j];
2350  nod_pt->pin(j_val);
2351  nod_pt->set_value(j_val, 0.0);
2352  }
2353  }
2354  }
2355  }
2356 
2359  return pml_top_left_mesh_pt;
2360  }

References b, oomph::Mesh::boundary_node_pt(), e(), oomph::Mesh::element_pt(), oomph::PMLElementBase< DIM >::enable_pml(), j, n, oomph::Mesh::nboundary(), oomph::Mesh::nboundary_element(), oomph::Mesh::nboundary_node(), oomph::Mesh::nelement(), oomph::Data::pin(), oomph::Data::set_value(), sorter_right_boundary(), oomph::PMLElementBase< DIM >::values_to_be_pinned_on_outer_pml_boundary(), and oomph::Node::x().

Referenced by PMLHelmholtzMGProblem< ELEMENT >::create_pml_meshes(), PMLProblem< ELEMENT >::create_pml_meshes(), ElasticAnnulusProblem< ELASTICITY_ELEMENT >::create_pml_meshes(), and oomph::RefineableQuadMeshWithMovingCylinder< ELEMENT >::RefineableQuadMeshWithMovingCylinder().

◆ create_top_pml_mesh()

template<class ASSOCIATED_PML_QUAD_ELEMENT >
Mesh* oomph::TwoDimensionalPMLHelper::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 
)

"Constructor" for PML mesh, aligned with the top physical domain boundary

PML layer width added to the bulk mesh coordinate

Return the finalized mesh, with PML enabled and boundary conditions added

1652  {
1653  // Look at the top boundary of the triangular mesh
1654  unsigned n_top_boundary_node =
1655  bulk_mesh_pt->nboundary_node(top_boundary_id);
1656 
1657  // Create a vector of ordered boundary nodes
1658  Vector<Node*> ordered_top_boundary_node_pt(n_top_boundary_node);
1659 
1660  // Fill the vector with the nodes on the respective boundary
1661  for (unsigned n = 0; n < n_top_boundary_node; n++)
1662  {
1663  ordered_top_boundary_node_pt[n] =
1664  bulk_mesh_pt->boundary_node_pt(top_boundary_id, n);
1665  }
1666 
1667  // Sort them from lowest to highest (in x coordinate)
1668  std::sort(ordered_top_boundary_node_pt.begin(),
1669  ordered_top_boundary_node_pt.end(),
1671 
1672  // The number of elements in x is taken from the triangular mesh
1673  unsigned n_x_top_pml = bulk_mesh_pt->nboundary_element(top_boundary_id);
1674 
1675  // Specific PML sizes needed, taken directly from physical domain
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);
1683 
1684  unsigned top_quadPML_boundary_id = 0;
1685 
1686  // Create the mesh to be designated to the PML
1687  Mesh* pml_top_mesh_pt = 0;
1688 
1689  // Build the top PML mesh
1690  pml_top_mesh_pt =
1691  new PMLQuadMesh<ASSOCIATED_PML_QUAD_ELEMENT>(bulk_mesh_pt,
1692  top_boundary_id,
1693  top_quadPML_boundary_id,
1694  n_x_top_pml,
1695  n_y_top_pml,
1696  l_pml_top_x_start,
1697  l_pml_top_x_end,
1698  l_pml_top_y_start,
1699  l_pml_top_y_end,
1700  time_stepper_pt);
1701 
1702  // Enable PML damping on the entire mesh
1703  unsigned n_element_pml_top = pml_top_mesh_pt->nelement();
1704  for (unsigned e = 0; e < n_element_pml_top; e++)
1705  {
1706  // Upcast
1707  PMLElementBase<2>* el_pt =
1708  dynamic_cast<PMLElementBase<2>*>(pml_top_mesh_pt->element_pt(e));
1709  el_pt->enable_pml(1, l_pml_top_y_start, l_pml_top_y_end);
1710  }
1711 
1712  // Get the values to be pinned from the first element (which we
1713  // assume exists!)
1714  PMLElementBase<2>* el_pt =
1715  dynamic_cast<PMLElementBase<2>*>(pml_top_mesh_pt->element_pt(0));
1716  Vector<unsigned> values_to_pin;
1717  el_pt->values_to_be_pinned_on_outer_pml_boundary(values_to_pin);
1718  unsigned npin = values_to_pin.size();
1719 
1720  // Exterior boundary needs to be set to Dirichlet 0
1721  // for both real and imaginary parts of all fields
1722  // in the problem
1723  unsigned n_bound_pml_top = pml_top_mesh_pt->nboundary();
1724  for (unsigned b = 0; b < n_bound_pml_top; b++)
1725  {
1726  unsigned n_node = pml_top_mesh_pt->nboundary_node(b);
1727  for (unsigned n = 0; n < n_node; n++)
1728  {
1729  Node* nod_pt = pml_top_mesh_pt->boundary_node_pt(b, n);
1730  if (b == 2)
1731  {
1732  for (unsigned j = 0; j < npin; j++)
1733  {
1734  unsigned j_val = values_to_pin[j];
1735  nod_pt->pin(j_val);
1736  nod_pt->set_value(j_val, 0.0);
1737  }
1738  }
1739  }
1740  }
1741 
1744  return pml_top_mesh_pt;
1745  }
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

References b, oomph::Mesh::boundary_node_pt(), e(), oomph::Mesh::element_pt(), oomph::PMLElementBase< DIM >::enable_pml(), j, n, oomph::Mesh::nboundary(), oomph::Mesh::nboundary_element(), oomph::Mesh::nboundary_node(), oomph::Mesh::nelement(), oomph::Data::pin(), oomph::Data::set_value(), sorter_top_boundary(), and oomph::PMLElementBase< DIM >::values_to_be_pinned_on_outer_pml_boundary().

Referenced by PMLHelmholtzMGProblem< ELEMENT >::create_pml_meshes(), PMLFourierDecomposedHelmholtzProblem< ELEMENT >::create_pml_meshes(), PMLProblem< ELEMENT >::create_pml_meshes(), and ElasticAnnulusProblem< ELASTICITY_ELEMENT >::create_pml_meshes().

◆ create_top_right_pml_mesh()

template<class ASSOCIATED_PML_QUAD_ELEMENT >
Mesh* oomph::TwoDimensionalPMLHelper::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 
)

"Constructor" for PML top right corner mesh, aligned with the existing PML meshes

Relevant boundary id's to be used in construction Parent id refers to already existing PML meshes

Number of elements and boundary nodes to be acted upon during construction are extracted from the 'parent' PML meshes

Specific PML sizes needed, taken directly from physical domain and existing PML meshes

The enabling must be perfromed in both x- and y-directions as this is a corner PML mesh

Return the finalized mesh, with PML enabled and boundary conditions added

1974  {
1977  unsigned parent_boundary_x_id = 2;
1978  unsigned parent_boundary_y_id = 1;
1979  // Current id refers to the mesh that is to be constructed
1980  unsigned current_boundary_x_id = 0;
1981  unsigned current_boundary_y_id = 3;
1982 
1983  // Look at the right boundary of the triangular mesh
1984  unsigned n_right_boundary_node =
1985  bulk_mesh_pt->nboundary_node(right_boundary_id);
1986 
1987  // Create a vector of ordered boundary nodes
1988  Vector<Node*> ordered_right_boundary_node_pt(n_right_boundary_node);
1989 
1990  // Fill the vector with the nodes on the respective boundary
1991  for (unsigned n = 0; n < n_right_boundary_node; n++)
1992  {
1993  ordered_right_boundary_node_pt[n] =
1994  bulk_mesh_pt->boundary_node_pt(right_boundary_id, n);
1995  }
1996 
1997  // Sort them from lowest to highest (in y coordinate)
1998  std::sort(ordered_right_boundary_node_pt.begin(),
1999  ordered_right_boundary_node_pt.end(),
2001 
2004  unsigned n_x_right_pml =
2005  pml_right_mesh_pt->nboundary_element(parent_boundary_x_id);
2006  unsigned n_y_top_pml =
2007  pml_top_mesh_pt->nboundary_element(parent_boundary_y_id);
2008  unsigned n_x_boundary_nodes =
2009  pml_right_mesh_pt->nboundary_node(parent_boundary_x_id);
2010  unsigned n_y_boundary_nodes =
2011  pml_top_mesh_pt->nboundary_node(parent_boundary_y_id);
2012 
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 =
2018  pml_right_mesh_pt
2019  ->boundary_node_pt(parent_boundary_x_id, n_x_boundary_nodes - 1)
2020  ->x(0);
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 =
2024  pml_top_mesh_pt
2025  ->boundary_node_pt(parent_boundary_y_id, n_y_boundary_nodes - 1)
2026  ->x(1);
2027 
2028  // Create the mesh to be designated to the PML
2029  Mesh* pml_top_right_mesh_pt = 0;
2030 
2031  // Build the top right corner PML mesh
2032  pml_top_right_mesh_pt =
2033  new PMLCornerQuadMesh<ASSOCIATED_PML_QUAD_ELEMENT>(
2034  pml_right_mesh_pt,
2035  pml_top_mesh_pt,
2036  bulk_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,
2042  n_x_right_pml,
2043  n_y_top_pml,
2044  l_pml_right_x_start,
2045  l_pml_right_x_end,
2046  l_pml_top_y_start,
2047  l_pml_top_y_end,
2048  time_stepper_pt);
2049 
2050  // Enable PML damping on the entire mesh
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++)
2055  {
2056  // Upcast
2057  PMLElementBase<2>* el_pt = dynamic_cast<PMLElementBase<2>*>(
2058  pml_top_right_mesh_pt->element_pt(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);
2061  }
2062 
2063  // Get the values to be pinned from the first element (which we
2064  // assume exists!)
2065  PMLElementBase<2>* el_pt =
2066  dynamic_cast<PMLElementBase<2>*>(pml_top_right_mesh_pt->element_pt(0));
2067  Vector<unsigned> values_to_pin;
2068  el_pt->values_to_be_pinned_on_outer_pml_boundary(values_to_pin);
2069  unsigned npin = values_to_pin.size();
2070 
2071  // Exterior boundary needs to be set to Dirichlet 0
2072  // for both real and imaginary parts of all fields
2073  // in the problem
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++)
2076  {
2077  unsigned n_node = pml_top_right_mesh_pt->nboundary_node(b);
2078  for (unsigned n = 0; n < n_node; n++)
2079  {
2080  Node* nod_pt = pml_top_right_mesh_pt->boundary_node_pt(b, n);
2081  if ((b == 1) || (b == 2))
2082  {
2083  for (unsigned j = 0; j < npin; j++)
2084  {
2085  unsigned j_val = values_to_pin[j];
2086  nod_pt->pin(j_val);
2087  nod_pt->set_value(j_val, 0.0);
2088  }
2089  }
2090  }
2091  }
2092 
2095  return pml_top_right_mesh_pt;
2096  }

References b, oomph::Mesh::boundary_node_pt(), e(), oomph::Mesh::element_pt(), oomph::PMLElementBase< DIM >::enable_pml(), j, n, oomph::Mesh::nboundary(), oomph::Mesh::nboundary_element(), oomph::Mesh::nboundary_node(), oomph::Mesh::nelement(), oomph::Data::pin(), oomph::Data::set_value(), sorter_right_boundary(), oomph::PMLElementBase< DIM >::values_to_be_pinned_on_outer_pml_boundary(), and oomph::Node::x().

Referenced by PMLHelmholtzMGProblem< ELEMENT >::create_pml_meshes(), PMLFourierDecomposedHelmholtzProblem< ELEMENT >::create_pml_meshes(), PMLProblem< ELEMENT >::create_pml_meshes(), ElasticAnnulusProblem< ELASTICITY_ELEMENT >::create_pml_meshes(), and oomph::RefineableQuadMeshWithMovingCylinder< ELEMENT >::RefineableQuadMeshWithMovingCylinder().

◆ sorter_bottom_boundary()

bool oomph::TwoDimensionalPMLHelper::sorter_bottom_boundary ( Node nod_i_pt,
Node nod_j_pt 
)

helper function for sorting the bottom boundary nodes

58  {
59  return (nod_i_pt->x(0) > nod_j_pt->x(0));
60  }

References oomph::Node::x().

Referenced by create_bottom_pml_mesh(), and oomph::PMLQuadMesh< ELEMENT >::PMLQuadMesh().

◆ sorter_left_boundary()

bool oomph::TwoDimensionalPMLHelper::sorter_left_boundary ( Node nod_i_pt,
Node nod_j_pt 
)

helper function for sorting the left boundary nodes

52  {
53  return (nod_i_pt->x(1) > nod_j_pt->x(1));
54  }

References oomph::Node::x().

Referenced by create_left_pml_mesh(), and oomph::PMLQuadMesh< ELEMENT >::PMLQuadMesh().

◆ sorter_right_boundary()

bool oomph::TwoDimensionalPMLHelper::sorter_right_boundary ( Node nod_i_pt,
Node nod_j_pt 
)

◆ sorter_top_boundary()

bool oomph::TwoDimensionalPMLHelper::sorter_top_boundary ( Node nod_i_pt,
Node nod_j_pt 
)

helper function for sorting the top boundary nodes

46  {
47  return (nod_i_pt->x(0) < nod_j_pt->x(0));
48  }

References oomph::Node::x().

Referenced by create_top_pml_mesh(), oomph::PMLCornerQuadMesh< ELEMENT >::PMLCornerQuadMesh(), and oomph::PMLQuadMesh< ELEMENT >::PMLQuadMesh().