oomph::PMLCornerQuadMesh< ELEMENT > Class Template Reference

PML mesh, derived from RectangularQuadMesh. More...

#include <pml_meshes.h>

+ Inheritance diagram for oomph::PMLCornerQuadMesh< ELEMENT >:

Public Member Functions

 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 &current_boundary_x_id, const unsigned &current_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)
 
- Public Member Functions inherited from oomph::PMLQuadMeshBase< ELEMENT >
 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. More...
 
void pml_locate_zeta (const Vector< double > &x, FiniteElement *&coarse_mesh_el_pt)
 
- Public Member Functions inherited from oomph::RectangularQuadMesh< ELEMENT >
 RectangularQuadMesh (const unsigned &nx, const unsigned &ny, const double &lx, const double &ly, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
 RectangularQuadMesh (const unsigned &nx, const unsigned &ny, const double &xmin, const double &xmax, const double &ymin, const double &ymax, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
 RectangularQuadMesh (const unsigned &nx, const unsigned &ny, const double &lx, const double &ly, const bool &periodic_in_x, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
 RectangularQuadMesh (const unsigned &nx, const unsigned &ny, const double &xmin, const double &xmax, const double &ymin, const double &ymax, const bool &periodic_in_x, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
const unsignednx () const
 Return number of elements in x direction. More...
 
const unsignedny () const
 Return number of elements in y direction. More...
 
const double x_min () const
 Return the minimum value of x coordinate. More...
 
const double x_max () const
 Return the maximum value of x coordinate. More...
 
const double y_min () const
 Return the minimum value of y coordinate. More...
 
const double y_max () const
 Return the maximum value of y coordinate. More...
 
virtual void element_reorder ()
 
virtual double x_spacing_function (unsigned xelement, unsigned xnode, unsigned yelement, unsigned ynode)
 
virtual double y_spacing_function (unsigned xelement, unsigned xnode, unsigned yelement, unsigned ynode)
 
- Public Member Functions inherited from oomph::QuadMeshBase
 QuadMeshBase ()
 Constructor (empty) More...
 
 QuadMeshBase (const QuadMeshBase &node)=delete
 Broken copy constructor. More...
 
void operator= (const QuadMeshBase &)=delete
 Broken assignment operator. More...
 
virtual ~QuadMeshBase ()
 Destructor (empty) More...
 
void setup_boundary_element_info ()
 
void setup_boundary_element_info (std::ostream &outfile)
 
- Public Member Functions inherited from oomph::Mesh
 Mesh ()
 Default constructor. More...
 
 Mesh (const Vector< Mesh * > &sub_mesh_pt)
 
void merge_meshes (const Vector< Mesh * > &sub_mesh_pt)
 
virtual void reset_boundary_element_info (Vector< unsigned > &ntmp_boundary_elements, Vector< Vector< unsigned >> &ntmp_boundary_elements_in_region, Vector< FiniteElement * > &deleted_elements)
 Virtual function to perform the reset boundary elements info rutines. More...
 
template<class BULK_ELEMENT >
void doc_boundary_coordinates (const unsigned &b, std::ofstream &the_file)
 
virtual void scale_mesh (const double &factor)
 
 Mesh (const Mesh &dummy)=delete
 Broken copy constructor. More...
 
void operator= (const Mesh &)=delete
 Broken assignment operator. More...
 
virtual ~Mesh ()
 Virtual Destructor to clean up all memory. More...
 
void flush_element_and_node_storage ()
 
void flush_element_storage ()
 
void flush_node_storage ()
 
Node *& node_pt (const unsigned long &n)
 Return pointer to global node n. More...
 
Nodenode_pt (const unsigned long &n) const
 Return pointer to global node n (const version) More...
 
GeneralisedElement *& element_pt (const unsigned long &e)
 Return pointer to element e. More...
 
GeneralisedElementelement_pt (const unsigned long &e) const
 Return pointer to element e (const version) More...
 
const Vector< GeneralisedElement * > & element_pt () const
 Return reference to the Vector of elements. More...
 
Vector< GeneralisedElement * > & element_pt ()
 Return reference to the Vector of elements. More...
 
FiniteElementfinite_element_pt (const unsigned &e) const
 
Node *& boundary_node_pt (const unsigned &b, const unsigned &n)
 Return pointer to node n on boundary b. More...
 
Nodeboundary_node_pt (const unsigned &b, const unsigned &n) const
 Return pointer to node n on boundary b. More...
 
void set_nboundary (const unsigned &nbound)
 Set the number of boundaries in the mesh. More...
 
void remove_boundary_nodes ()
 Clear all pointers to boundary nodes. More...
 
void remove_boundary_nodes (const unsigned &b)
 
void remove_boundary_node (const unsigned &b, Node *const &node_pt)
 Remove a node from the boundary b. More...
 
void add_boundary_node (const unsigned &b, Node *const &node_pt)
 Add a (pointer to) a node to the b-th boundary. More...
 
void copy_boundary_node_data_from_nodes ()
 
bool boundary_coordinate_exists (const unsigned &i) const
 Indicate whether the i-th boundary has an intrinsic coordinate. More...
 
unsigned long nelement () const
 Return number of elements in the mesh. More...
 
unsigned long nnode () const
 Return number of nodes in the mesh. More...
 
unsigned ndof_types () const
 Return number of dof types in mesh. More...
 
unsigned elemental_dimension () const
 Return number of elemental dimension in mesh. More...
 
unsigned nodal_dimension () const
 Return number of nodal dimension in mesh. More...
 
void add_node_pt (Node *const &node_pt)
 Add a (pointer to a) node to the mesh. More...
 
void add_element_pt (GeneralisedElement *const &element_pt)
 Add a (pointer to) an element to the mesh. More...
 
virtual void node_update (const bool &update_all_solid_nodes=false)
 
virtual void reorder_nodes (const bool &use_old_ordering=true)
 
virtual void get_node_reordering (Vector< Node * > &reordering, const bool &use_old_ordering=true) const
 
template<class BULK_ELEMENT , template< class > class FACE_ELEMENT>
void build_face_mesh (const unsigned &b, Mesh *const &face_mesh_pt)
 
unsigned self_test ()
 Self-test: Check elements and nodes. Return 0 for OK. More...
 
void max_and_min_element_size (double &max_size, double &min_size)
 
double total_size ()
 
void check_inverted_elements (bool &mesh_has_inverted_elements, std::ofstream &inverted_element_file)
 
void check_inverted_elements (bool &mesh_has_inverted_elements)
 
unsigned check_for_repeated_nodes (const double &epsilon=1.0e-12)
 
Vector< Node * > prune_dead_nodes ()
 
unsigned nboundary () const
 Return number of boundaries. More...
 
unsigned long nboundary_node (const unsigned &ibound) const
 Return number of nodes on a particular boundary. More...
 
FiniteElementboundary_element_pt (const unsigned &b, const unsigned &e) const
 Return pointer to e-th finite element on boundary b. More...
 
Nodeget_some_non_boundary_node () const
 
unsigned nboundary_element (const unsigned &b) const
 Return number of finite elements that are adjacent to boundary b. More...
 
int face_index_at_boundary (const unsigned &b, const unsigned &e) const
 
virtual void dump (std::ofstream &dump_file, const bool &use_old_ordering=true) const
 Dump the data in the mesh into a file for restart. More...
 
void dump (const std::string &dump_file_name, const bool &use_old_ordering=true) const
 Dump the data in the mesh into a file for restart. More...
 
virtual void read (std::ifstream &restart_file)
 Read solution from restart file. More...
 
void output_paraview (std::ofstream &file_out, const unsigned &nplot) const
 
void output_fct_paraview (std::ofstream &file_out, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt) const
 
void output_fct_paraview (std::ofstream &file_out, const unsigned &nplot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt) const
 
void output (std::ostream &outfile)
 Output for all elements. More...
 
void output (std::ostream &outfile, const unsigned &n_plot)
 Output at f(n_plot) points in each element. More...
 
void output (FILE *file_pt)
 Output for all elements (C-style output) More...
 
void output (FILE *file_pt, const unsigned &nplot)
 Output at f(n_plot) points in each element (C-style output) More...
 
void output (const std::string &output_filename)
 Output for all elements. More...
 
void output (const std::string &output_filename, const unsigned &n_plot)
 Output at f(n_plot) points in each element. More...
 
void output_fct (std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt)
 Output a given Vector function at f(n_plot) points in each element. More...
 
void output_fct (std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt)
 
void output_boundaries (std::ostream &outfile)
 Output the nodes on the boundaries (into separate tecplot zones) More...
 
void output_boundaries (const std::string &output_filename)
 
void assign_initial_values_impulsive ()
 Assign initial values for an impulsive start. More...
 
void shift_time_values ()
 
void calculate_predictions ()
 
void set_nodal_and_elemental_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
virtual void set_mesh_level_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
void set_consistent_pinned_values_for_continuation (ContinuationStorageScheme *const &continuation_stepper_pt)
 Set consistent values for pinned data in continuation. More...
 
bool does_pointer_correspond_to_mesh_data (double *const &parameter_pt)
 Does the double pointer correspond to any mesh data. More...
 
void set_nodal_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 Set the timestepper associated with the nodal data in the mesh. More...
 
void set_elemental_internal_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
virtual void compute_norm (double &norm)
 
virtual void compute_norm (Vector< double > &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
 
virtual void compute_error (FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
 
virtual void compute_error (FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, Vector< double > &error, Vector< double > &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, Vector< double > &error, Vector< double > &norm)
 
virtual void compute_error (std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, Vector< double > &error, Vector< double > &norm)
 
virtual void compute_error (FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
 Returns the norm of the error and that of the exact solution. More...
 
virtual void compute_error (FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, Vector< double > &error, Vector< double > &norm)
 
bool is_mesh_distributed () const
 Boolean to indicate if Mesh has been distributed. More...
 
OomphCommunicatorcommunicator_pt () const
 
void delete_all_external_storage ()
 Wipe the storage for all externally-based elements. More...
 

Additional Inherited Members

- Public Types inherited from oomph::Mesh
typedef void(FiniteElement::* SteadyExactSolutionFctPt) (const Vector< double > &x, Vector< double > &soln)
 
typedef void(FiniteElement::* UnsteadyExactSolutionFctPt) (const double &time, const Vector< double > &x, Vector< double > &soln)
 
- Static Public Attributes inherited from oomph::Mesh
static Steady< 0 > Default_TimeStepper
 The Steady Timestepper. More...
 
static bool Suppress_warning_about_empty_mesh_level_time_stepper_function
 Static boolean flag to control warning about mesh level timesteppers. More...
 
- Protected Member Functions inherited from oomph::RectangularQuadMesh< ELEMENT >
void build_mesh (TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 Generic mesh construction function: contains all the hard work. More...
 
 RectangularQuadMesh (const unsigned &nx, const unsigned &ny, const double &xmin, const double &xmax, const double &ymin, const double &ymax, const bool &periodic_in_x, const bool &build, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
- Protected Member Functions inherited from oomph::Mesh
unsigned long assign_global_eqn_numbers (Vector< double * > &Dof_pt)
 Assign (global) equation numbers to the nodes. More...
 
void describe_dofs (std::ostream &out, const std::string &current_string) const
 
void describe_local_dofs (std::ostream &out, const std::string &current_string) const
 
void assign_local_eqn_numbers (const bool &store_local_dof_pt)
 Assign local equation numbers in all elements. More...
 
void convert_to_boundary_node (Node *&node_pt, const Vector< FiniteElement * > &finite_element_pt)
 
void convert_to_boundary_node (Node *&node_pt)
 
- Protected Attributes inherited from oomph::RectangularQuadMesh< ELEMENT >
unsigned Nx
 Nx: number of elements in x-direction. More...
 
unsigned Ny
 Ny: number of elements in y-direction. More...
 
unsigned Np
 Np: number of (linear) points in the element. More...
 
double Xmin
 Minimum value of x coordinate. More...
 
double Xmax
 Maximum value of x coordinate. More...
 
double Ymin
 Minimum value of y coordinate. More...
 
double Ymax
 Maximum value of y coordinate. More...
 
bool Xperiodic
 
- Protected Attributes inherited from oomph::Mesh
Vector< Vector< Node * > > Boundary_node_pt
 
bool Lookup_for_elements_next_boundary_is_setup
 
Vector< Vector< FiniteElement * > > Boundary_element_pt
 
Vector< Vector< int > > Face_index_at_boundary
 
Vector< Node * > Node_pt
 Vector of pointers to nodes. More...
 
Vector< GeneralisedElement * > Element_pt
 Vector of pointers to generalised elements. More...
 
std::vector< boolBoundary_coordinate_exists
 

Detailed Description

template<class ELEMENT>
class oomph::PMLCornerQuadMesh< ELEMENT >

PML mesh, derived from RectangularQuadMesh.

/////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////

Constructor & Destructor Documentation

◆ PMLCornerQuadMesh()

template<class ELEMENT >
oomph::PMLCornerQuadMesh< ELEMENT >::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 current_boundary_x_id,
const unsigned current_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 
)
inline

Constructor: Pass pointer to "bulk" mesh and the two existing PML meshes in order to construct the corner PML mesh in between them based on their element number and coordinates.

Simple interior node numbering helpers to be precomputed before the main loop

Top left node in element

Lower right node in element

Top right node in element

798  : PMLQuadMeshBase<ELEMENT>(n_pml_x,
799  n_pml_y,
800  x_pml_start,
801  x_pml_end,
802  y_pml_start,
803  y_pml_end,
804  time_stepper_pt)
805  {
806  unsigned nnode_1d = this->finite_element_pt(0)->nnode_1d();
807 
810 
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;
817 
818  // Set up top right corner element
819  //--------------------------------
820  if ((parent_boundary_x_id == 2) && (parent_boundary_y_id == 1))
821  {
822  // Get the number of nodes to be connected on the horizontal boundary
823  unsigned n_boundary_x_node =
824  PMLQuad_mesh_x_pt->nboundary_node(parent_boundary_x_id);
825 
826  // Create a vector of ordered boundary nodes
827  Vector<Node*> ordered_boundary_x_node_pt(n_boundary_x_node);
828 
829  // Fill the vector with the nodes on the respective boundary
830  for (unsigned n = 0; n < n_boundary_x_node; n++)
831  {
832  ordered_boundary_x_node_pt[n] =
833  PMLQuad_mesh_x_pt->boundary_node_pt(parent_boundary_x_id, n);
834  }
835 
836  // Sort them from lowest to highest (in x coordinate)
837  if (parent_boundary_x_id == 2)
838  {
839  std::sort(ordered_boundary_x_node_pt.begin(),
840  ordered_boundary_x_node_pt.end(),
842  }
843 
844  // Get the number of nodes to be connected on the vertical boundary
845  unsigned n_boundary_y_node =
846  PMLQuad_mesh_y_pt->nboundary_node(parent_boundary_y_id);
847 
848  // Create a vector of ordered boundary nodes
849  Vector<Node*> ordered_boundary_y_node_pt(n_boundary_y_node);
850 
851  // Fill the vector with the nodes on the respective boundary
852  for (unsigned n = 0; n < n_boundary_y_node; n++)
853  {
854  ordered_boundary_y_node_pt[n] =
855  PMLQuad_mesh_y_pt->boundary_node_pt(parent_boundary_y_id, n);
856  }
857 
858  // Sort them
859  if (parent_boundary_y_id == 1)
860  {
861  std::sort(ordered_boundary_y_node_pt.begin(),
862  ordered_boundary_y_node_pt.end(),
864  }
865 
866  unsigned x_nnod = this->nboundary_node(current_boundary_x_id);
867  for (unsigned j = 0; j < x_nnod; j++)
868  {
869  this->boundary_node_pt(current_boundary_x_id, j)->set_obsolete();
870  }
871 
872  unsigned y_nnod = this->nboundary_node(current_boundary_y_id);
873  for (unsigned j = 0; j < y_nnod; j++)
874  {
875  this->boundary_node_pt(current_boundary_y_id, j)->set_obsolete();
876  }
877 
878  // Kill the obsolete nodes
879  this->prune_dead_nodes();
880 
881  unsigned n_pml_element = this->nelement();
882 
883  // Connect the elements in the pml mesh to the ones
884  // in the triangular mesh at element level
885  unsigned count = 0;
886 
887  if (parent_boundary_y_id == 1)
888  {
889  for (unsigned e = 0; e < n_pml_element; e++)
890  {
891  // If element is on the right boundary
892  if ((e % n_pml_x) == 0)
893  {
894  // Upcast from GeneralisedElement to bulk element
895  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(this->element_pt(e));
896 
897  // Loop over all nodes in element
898  unsigned n_node = el_pt->nnode();
899  for (unsigned inod = 0; inod < n_node; inod++)
900  {
901  // If it is one of the ones on the left boundary
902  if (e == 0)
903  {
904  if (inod == 0) el_pt->node_pt(inod) = special_corner_node_pt;
905  if ((inod % nnode_1d == 0) && (inod > 0))
906  {
907  // Get the pointer from the triangular mesh
908  el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
909  count++;
910 
911  // Node between two elements
912  if (inod == interior_node_nr_helper_1)
913  {
914  count--;
915  }
916  }
917  }
918  else
919  {
920  if ((inod % nnode_1d) == 0)
921  {
922  // Get the pointer from the triangular mesh
923  el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
924  count++;
925 
926  // Node between two elements
927  if (inod == interior_node_nr_helper_1)
928  {
929  count--;
930  }
931  }
932  }
933  }
934  }
935  }
936  }
937 
938  count = 0;
939 
940  if (parent_boundary_x_id == 2)
941  {
942  for (unsigned e = 0; e < n_pml_element; e++)
943  {
944  // If element is on the right boundary
945  if ((int)(e / n_pml_x) == 0)
946  {
947  // Upcast from GeneralisedElement to bulk element
948  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(this->element_pt(e));
949 
950  // Loop over all nodes in element
951  unsigned n_node = el_pt->nnode();
952  for (unsigned inod = 0; inod < n_node; inod++)
953  {
954  if (e == 0)
955  {
956  if (((int)(inod / nnode_1d) == 0) && (inod > 0))
957  {
958  // Get the pointer from the triangular mesh
959  el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
960  count++;
961 
962  // Node between two elements
963  if (inod == interior_node_nr_helper_2)
964  {
965  count--;
966  }
967  }
968  }
969  else
970  {
971  if ((int)(inod / nnode_1d) == 0)
972  {
973  // Get the pointer from the triangular mesh
974  el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
975  count++;
976 
977  // Node between two elements
978  if (inod == interior_node_nr_helper_2)
979  {
980  count--;
981  }
982  }
983  }
984  }
985  }
986  }
987  }
988  }
989 
990  // Set up bottom right corner element
991  //--------------------------------
992  if ((parent_boundary_x_id == 0) && (parent_boundary_y_id == 1))
993  {
994  // Get the number of nodes to be connected on the horizontal boundary
995  unsigned n_boundary_x_node =
996  PMLQuad_mesh_x_pt->nboundary_node(parent_boundary_x_id);
997 
998  // Create a vector of ordered boundary nodes
999  Vector<Node*> ordered_boundary_x_node_pt(n_boundary_x_node);
1000 
1001  // Fill the vector with the nodes on the respective boundary
1002  for (unsigned n = 0; n < n_boundary_x_node; n++)
1003  {
1004  ordered_boundary_x_node_pt[n] =
1005  PMLQuad_mesh_x_pt->boundary_node_pt(parent_boundary_x_id, n);
1006  }
1007 
1008  // Sort them from lowest to highest (in x coordinate)
1009  if (parent_boundary_x_id == 0)
1010  {
1011  std::sort(ordered_boundary_x_node_pt.begin(),
1012  ordered_boundary_x_node_pt.end(),
1014  }
1015 
1016  // Get the number of nodes to be connected on the vertical boundary
1017  unsigned n_boundary_y_node =
1018  PMLQuad_mesh_y_pt->nboundary_node(parent_boundary_y_id);
1019 
1020  // Create a vector of ordered boundary nodes
1021  Vector<Node*> ordered_boundary_y_node_pt(n_boundary_y_node);
1022 
1023  // Fill the vector with the nodes on the respective boundary
1024  for (unsigned n = 0; n < n_boundary_y_node; n++)
1025  {
1026  ordered_boundary_y_node_pt[n] =
1027  PMLQuad_mesh_y_pt->boundary_node_pt(parent_boundary_y_id, n);
1028  }
1029 
1030  // Sort them
1031  if (parent_boundary_y_id == 1)
1032  {
1033  std::sort(ordered_boundary_y_node_pt.begin(),
1034  ordered_boundary_y_node_pt.end(),
1036  }
1037 
1038  unsigned x_nnod = this->nboundary_node(current_boundary_x_id);
1039  for (unsigned j = 0; j < x_nnod; j++)
1040  {
1041  this->boundary_node_pt(current_boundary_x_id, j)->set_obsolete();
1042  }
1043 
1044  unsigned y_nnod = this->nboundary_node(current_boundary_y_id);
1045  for (unsigned j = 0; j < y_nnod; j++)
1046  {
1047  this->boundary_node_pt(current_boundary_y_id, j)->set_obsolete();
1048  }
1049 
1050  // Kill the obsolete nodes
1051  this->prune_dead_nodes();
1052 
1053  // Get the number of elements in the PML mesh
1054  unsigned n_pml_element = this->nelement();
1055 
1056  // Connect the elements in the pml mesh to the ones
1057  // in the triangular mesh at element level
1058  unsigned count = 0;
1059 
1060  if (parent_boundary_y_id == 1)
1061  {
1062  for (unsigned e = 0; e < n_pml_element; e++)
1063  {
1064  // If element is on the right boundary
1065  if ((e % n_pml_x) == 0)
1066  {
1067  // Upcast from GeneralisedElement to bulk element
1068  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(this->element_pt(e));
1069 
1070  // Loop over all nodes in element
1071  unsigned n_node = el_pt->nnode();
1072  for (unsigned inod = 0; inod < n_node; inod++)
1073  {
1074  if (e == ((n_pml_x) * (n_pml_y - 1)))
1075  {
1076  if (inod == interior_node_nr_helper_1)
1077  {
1078  el_pt->node_pt(inod) = special_corner_node_pt;
1079  }
1080  if ((inod % nnode_1d == 0) &&
1081  (inod < interior_node_nr_helper_1))
1082  {
1083  // Get the pointer from the triangular mesh
1084  el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
1085  count++;
1086 
1087  // Node between two elements
1088  if (inod == interior_node_nr_helper_1)
1089  {
1090  count--;
1091  }
1092  }
1093  }
1094  else
1095  {
1096  if ((inod % nnode_1d) == 0)
1097  {
1098  // Get the pointer from the triangular mesh
1099  el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
1100  count++;
1101 
1102  // Node between two elements
1103  if (inod == interior_node_nr_helper_1)
1104  {
1105  count--;
1106  }
1107  }
1108  }
1109  }
1110  }
1111  }
1112  }
1113 
1114  count = 0;
1115 
1116  if (parent_boundary_x_id == 0)
1117  {
1118  for (unsigned e = 0; e < n_pml_element; e++)
1119  {
1120  // If element is on the right boundary
1121  if (e >= ((n_pml_x - 0) * (n_pml_y - 1)))
1122  {
1123  // Upcast from GeneralisedElement to bulk element
1124  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(this->element_pt(e));
1125 
1126  // Loop over all nodes in element
1127  unsigned n_node = el_pt->nnode();
1128  for (unsigned inod = 0; inod < n_node; inod++)
1129  {
1130  if (e == ((n_pml_x) * (n_pml_y - 1)))
1131  {
1132  if (((unsigned)(inod / nnode_1d) ==
1133  interior_node_nr_helper_2) &&
1134  (inod > interior_node_nr_helper_1))
1135  {
1136  // Get the pointer from the triangular mesh
1137  el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
1138  count++;
1139 
1140  // Node between two elements
1141  if (inod == interior_node_nr_helper_3)
1142  {
1143  count--;
1144  }
1145  }
1146  }
1147  else
1148  {
1149  if ((unsigned)(inod / nnode_1d) == interior_node_nr_helper_2)
1150  {
1151  // Get the pointer from the triangular mesh
1152  el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
1153  count++;
1154 
1155  // Node between two elements
1156  if (inod == interior_node_nr_helper_3)
1157  {
1158  count--;
1159  }
1160  }
1161  }
1162  }
1163  }
1164  }
1165  }
1166  }
1167 
1168  // Set up top left corner element
1169  //--------------------------------
1170  if ((parent_boundary_x_id == 2) && (parent_boundary_y_id == 3))
1171  {
1172  // Get the number of nodes to be connected on the horizontal boundary
1173  unsigned n_boundary_x_node =
1174  PMLQuad_mesh_x_pt->nboundary_node(parent_boundary_x_id);
1175 
1176  // Create a vector of ordered boundary nodes
1177  Vector<Node*> ordered_boundary_x_node_pt(n_boundary_x_node);
1178 
1179  // Fill the vector with the nodes on the respective boundary
1180  for (unsigned n = 0; n < n_boundary_x_node; n++)
1181  {
1182  ordered_boundary_x_node_pt[n] =
1183  PMLQuad_mesh_x_pt->boundary_node_pt(parent_boundary_x_id, n);
1184  }
1185 
1186  // Sort them from lowest to highest (in x coordinate)
1187  if (parent_boundary_x_id == 2)
1188  {
1189  std::sort(ordered_boundary_x_node_pt.begin(),
1190  ordered_boundary_x_node_pt.end(),
1192  }
1193 
1194  // Get the number of nodes to be connected on the vertical boundary
1195  unsigned n_boundary_y_node =
1196  PMLQuad_mesh_y_pt->nboundary_node(parent_boundary_y_id);
1197 
1198  // Create a vector of ordered boundary nodes
1199  Vector<Node*> ordered_boundary_y_node_pt(n_boundary_y_node);
1200 
1201  // Fill the vector with the nodes on the respective boundary
1202  for (unsigned n = 0; n < n_boundary_y_node; n++)
1203  {
1204  ordered_boundary_y_node_pt[n] =
1205  PMLQuad_mesh_y_pt->boundary_node_pt(parent_boundary_y_id, n);
1206  }
1207 
1208  // Sort them from lowest to highest (in x coordinate)
1209  if (parent_boundary_y_id == 1)
1210  {
1211  std::sort(ordered_boundary_y_node_pt.begin(),
1212  ordered_boundary_y_node_pt.end(),
1214  }
1215 
1216  unsigned x_nnod = this->nboundary_node(current_boundary_x_id);
1217  for (unsigned j = 0; j < x_nnod; j++)
1218  {
1219  this->boundary_node_pt(current_boundary_x_id, j)->set_obsolete();
1220  }
1221 
1222  unsigned y_nnod = this->nboundary_node(current_boundary_y_id);
1223  for (unsigned j = 0; j < y_nnod; j++)
1224  {
1225  this->boundary_node_pt(current_boundary_y_id, j)->set_obsolete();
1226  }
1227 
1228  // Kill the obsolete nodes
1229  this->prune_dead_nodes();
1230 
1231  // Get the number of elements in the PML mesh
1232  unsigned n_pml_element = this->nelement();
1233 
1234  // Connect the elements in the pml mesh to the ones
1235  // in the triangular mesh at element level
1236  unsigned count = 0;
1237 
1238  if (parent_boundary_y_id == 3)
1239  {
1240  for (unsigned e = 0; e < n_pml_element; e++)
1241  {
1242  // If element is on the right boundary
1243  if ((e % n_pml_x) == (n_pml_x - 1))
1244  {
1245  // Upcast from GeneralisedElement to bulk element
1246  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(this->element_pt(e));
1247 
1248  // Loop over all nodes in element
1249  unsigned n_node = el_pt->nnode();
1250  for (unsigned inod = 0; inod < n_node; inod++)
1251  {
1252  if (e == (n_pml_x - 1))
1253  {
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)))
1258  {
1259  // Get the pointer from the triangular mesh
1260  el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
1261  count++;
1262 
1263  // Node between two elements
1264  if (inod == interior_node_nr_helper_3)
1265  {
1266  count--;
1267  }
1268  }
1269  }
1270  else
1271  {
1272  if ((inod % nnode_1d) == interior_node_nr_helper_2)
1273  {
1274  // Get the pointer from the triangular mesh
1275  el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
1276  count++;
1277 
1278  // Node between two elements
1279  if (inod == interior_node_nr_helper_3)
1280  {
1281  count--;
1282  }
1283  }
1284  }
1285  }
1286  }
1287  }
1288  }
1289 
1290  count = 0;
1291 
1292  if (parent_boundary_x_id == 2)
1293  {
1294  for (unsigned e = 0; e < n_pml_element; e++)
1295  {
1296  // If element is on the right boundary
1297  if ((int)(e / n_pml_x) == 0)
1298  {
1299  // Upcast from GeneralisedElement to bulk element
1300  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(this->element_pt(e));
1301 
1302  // Loop over all nodes in element
1303  unsigned n_node = el_pt->nnode();
1304  for (unsigned inod = 0; inod < n_node; inod++)
1305  {
1306  // If it is one of the ones on the left boundary
1307  if (e == (n_pml_x - 1))
1308  {
1309  if (((int)(inod / nnode_1d) == 0) &&
1310  (inod < interior_node_nr_helper_2))
1311  {
1312  // Get the pointer from the triangular mesh
1313  el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
1314  count++;
1315 
1316  // Node between two elements
1317  if (inod == (nnode_1d - 1))
1318  {
1319  count--;
1320  }
1321  }
1322  }
1323  else
1324  {
1325  if ((int)(inod / nnode_1d) == 0)
1326  {
1327  // Get the pointer from the triangular mesh
1328  el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
1329  count++;
1330 
1331  // Node between two elements
1332  if (inod == interior_node_nr_helper_2)
1333  {
1334  count--;
1335  }
1336  }
1337  }
1338  }
1339  }
1340  }
1341  }
1342  }
1343 
1344  // Set up bottom left corner element
1345  //--------------------------------
1346  if ((parent_boundary_x_id == 0) && (parent_boundary_y_id == 3))
1347  {
1348  // Get the number of nodes to be connected on the horizontal boundary
1349  unsigned n_boundary_x_node =
1350  PMLQuad_mesh_x_pt->nboundary_node(parent_boundary_x_id);
1351 
1352  // Create a vector of ordered boundary nodes
1353  Vector<Node*> ordered_boundary_x_node_pt(n_boundary_x_node);
1354 
1355  // Fill the vector with the nodes on the respective boundary
1356  for (unsigned n = 0; n < n_boundary_x_node; n++)
1357  {
1358  ordered_boundary_x_node_pt[n] =
1359  PMLQuad_mesh_x_pt->boundary_node_pt(parent_boundary_x_id, n);
1360  }
1361 
1362  // Sort them
1363  if (parent_boundary_x_id == 0)
1364  {
1365  std::sort(ordered_boundary_x_node_pt.begin(),
1366  ordered_boundary_x_node_pt.end(),
1368  }
1369 
1370  // Get the number of nodes to be connected on the vertical boundary
1371  unsigned n_boundary_y_node =
1372  PMLQuad_mesh_y_pt->nboundary_node(parent_boundary_y_id);
1373 
1374  // Create a vector of ordered boundary nodes
1375  Vector<Node*> ordered_boundary_y_node_pt(n_boundary_y_node);
1376 
1377  // Fill the vector with the nodes on the respective boundary
1378  for (unsigned n = 0; n < n_boundary_y_node; n++)
1379  {
1380  ordered_boundary_y_node_pt[n] =
1381  PMLQuad_mesh_y_pt->boundary_node_pt(parent_boundary_y_id, n);
1382  }
1383 
1384  // Sort them
1385  if (parent_boundary_y_id == 3)
1386  {
1387  std::sort(ordered_boundary_y_node_pt.begin(),
1388  ordered_boundary_y_node_pt.end(),
1390  }
1391 
1392  unsigned x_nnod = this->nboundary_node(current_boundary_x_id);
1393  for (unsigned j = 0; j < x_nnod; j++)
1394  {
1395  this->boundary_node_pt(current_boundary_x_id, j)->set_obsolete();
1396  }
1397 
1398  unsigned y_nnod = this->nboundary_node(current_boundary_y_id);
1399  for (unsigned j = 0; j < y_nnod; j++)
1400  {
1401  this->boundary_node_pt(current_boundary_y_id, j)->set_obsolete();
1402  }
1403 
1404  // Kill the obsolete nodes
1405  this->prune_dead_nodes();
1406 
1407  unsigned n_pml_element = this->nelement();
1408 
1409  // Connect the elements in the pml mesh to the ones
1410  // in the triangular mesh at element level
1411  unsigned count = 0;
1412 
1413  if (parent_boundary_y_id == 3)
1414  {
1415  for (unsigned e = 0; e < n_pml_element; e++)
1416  {
1417  // If element is on the right boundary
1418  if ((e % n_pml_x) == (n_pml_x - 1))
1419  {
1420  // Upcast from GeneralisedElement to bulk element
1421  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(this->element_pt(e));
1422 
1423  // Loop over all nodes in element
1424  unsigned n_node = el_pt->nnode();
1425  for (unsigned inod = 0; inod < n_node; inod++)
1426  {
1427  if (e == (n_pml_element - 1))
1428  {
1429  if (inod == interior_node_nr_helper_3)
1430  {
1431  el_pt->node_pt(inod) = special_corner_node_pt;
1432  }
1433  if ((inod % nnode_1d == interior_node_nr_helper_2) &&
1434  (inod < interior_node_nr_helper_3))
1435  {
1436  // Get the pointer from the triangular mesh
1437  el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
1438  count++;
1439 
1440  // Node between two elements
1441  if (inod == interior_node_nr_helper_3)
1442  {
1443  count--;
1444  }
1445  }
1446  }
1447  else
1448  {
1449  if ((inod % nnode_1d) == interior_node_nr_helper_2)
1450  {
1451  // Get the pointer from the triangular mesh
1452  el_pt->node_pt(inod) = ordered_boundary_y_node_pt[count];
1453  count++;
1454 
1455  // Node between two elements
1456  if (inod == interior_node_nr_helper_3)
1457  {
1458  count--;
1459  }
1460  }
1461  }
1462  }
1463  }
1464  }
1465  }
1466 
1467  count = 0;
1468 
1469  if (parent_boundary_x_id == 0)
1470  {
1471  for (unsigned e = 0; e < n_pml_element; e++)
1472  {
1473  // If element is on the right boundary
1474  if (e >= ((n_pml_x) * (n_pml_y - 1)))
1475  {
1476  // Upcast from GeneralisedElement to bulk element
1477  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(this->element_pt(e));
1478 
1479  // Loop over all nodes in element
1480  unsigned n_node = el_pt->nnode();
1481  for (unsigned inod = 0; inod < n_node; inod++)
1482  {
1483  if (e == (n_pml_element - 1))
1484  {
1485  if (((unsigned)(inod / nnode_1d) ==
1486  interior_node_nr_helper_2) &&
1487  (inod < interior_node_nr_helper_3))
1488  {
1489  // Get the pointer from the triangular mesh
1490  el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
1491  count++;
1492 
1493  // Node between two elements
1494  if (inod == interior_node_nr_helper_3)
1495  {
1496  count--;
1497  }
1498  }
1499  }
1500  else
1501  {
1502  if ((unsigned)(inod / nnode_1d) == interior_node_nr_helper_2)
1503  {
1504  // Get the pointer from the triangular mesh
1505  el_pt->node_pt(inod) = ordered_boundary_x_node_pt[count];
1506  count++;
1507 
1508  // Node between two elements
1509  if (inod == interior_node_nr_helper_3)
1510  {
1511  count--;
1512  }
1513  }
1514  }
1515  }
1516  }
1517  }
1518  }
1519  }
1520  }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
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
FiniteElement * finite_element_pt(const unsigned &e) const
Definition: mesh.h:473
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
void set_obsolete()
Mark node as obsolete.
Definition: nodes.h:1436
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
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 oomph::Mesh::boundary_node_pt(), e(), oomph::Mesh::element_pt(), oomph::Mesh::finite_element_pt(), j, n, oomph::Mesh::nboundary_node(), oomph::Mesh::nelement(), oomph::FiniteElement::nnode_1d(), oomph::Mesh::prune_dead_nodes(), oomph::Node::set_obsolete(), oomph::TwoDimensionalPMLHelper::sorter_right_boundary(), and oomph::TwoDimensionalPMLHelper::sorter_top_boundary().


The documentation for this class was generated from the following file: