oomph::Mesh Class Reference

#include <mesh.h>

+ Inheritance diagram for oomph::Mesh:

Public Types

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)
 

Public Member Functions

 Mesh ()
 Default constructor. More...
 
 Mesh (const Vector< Mesh * > &sub_mesh_pt)
 
void merge_meshes (const Vector< Mesh * > &sub_mesh_pt)
 
virtual void setup_boundary_element_info ()
 
virtual void setup_boundary_element_info (std::ostream &outfile)
 
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...
 

Static Public Attributes

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

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

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
 

Friends

class Problem
 Problem is a friend. More...
 

Detailed Description

A general mesh class.

The main components of a Mesh are:

  • pointers to its Nodes
  • pointers to its Elements
  • pointers to its boundary Nodes

Member Typedef Documentation

◆ SteadyExactSolutionFctPt

typedef void(FiniteElement::* oomph::Mesh::SteadyExactSolutionFctPt) (const Vector< double > &x, Vector< double > &soln)

Typedef for function pointer to function that computes steady exact solution

◆ UnsteadyExactSolutionFctPt

typedef void(FiniteElement::* oomph::Mesh::UnsteadyExactSolutionFctPt) (const double &time, const Vector< double > &x, Vector< double > &soln)

Typedef for function pointer to function that computes unsteady exact solution

Constructor & Destructor Documentation

◆ Mesh() [1/3]

oomph::Mesh::Mesh ( )
inline

Default constructor.

237  {
238  // Lookup scheme hasn't been setup yet
240 #ifdef OOMPH_HAS_MPI
241  // Set defaults for distributed meshes
242 
243  // Mesh hasn't been distributed: Null out pointer to communicator
244  Comm_pt = 0;
245  // Don't keep all objects as halos
246  Keep_all_elements_as_halos = false;
247  // Don't output halo elements
248  Output_halo_elements = false;
249  // Don't suppress automatic resizing of halo nodes
250  Resize_halo_nodes_not_required = false;
251 #endif
252  }
bool Lookup_for_elements_next_boundary_is_setup
Definition: mesh.h:87

References Lookup_for_elements_next_boundary_is_setup.

◆ Mesh() [2/3]

oomph::Mesh::Mesh ( const Vector< Mesh * > &  sub_mesh_pt)
inline

Constructor builds combined mesh from the meshes specified. Note: This simply merges the meshes' elements and nodes (ignoring duplicates; no boundary information etc. is created).

258  {
259 #ifdef OOMPH_HAS_MPI
260  // Mesh hasn't been distributed: Null out pointer to communicator
261  Comm_pt = 0;
262 #endif
263  // Now merge the meshes
264  merge_meshes(sub_mesh_pt);
265  }
void merge_meshes(const Vector< Mesh * > &sub_mesh_pt)
Definition: mesh.cc:65

References merge_meshes().

◆ Mesh() [3/3]

oomph::Mesh::Mesh ( const Mesh dummy)
delete

Broken copy constructor.

◆ ~Mesh()

oomph::Mesh::~Mesh ( )
virtual

Virtual Destructor to clean up all memory.

651  {
652  // Free the nodes first
653  // Loop over the nodes in reverse order
654  unsigned long Node_pt_range = Node_pt.size();
655  for (unsigned long i = Node_pt_range; i > 0; i--)
656  {
657  delete Node_pt[i - 1];
658  Node_pt[i - 1] = 0;
659  }
660 
661  // Free the elements
662  // Loop over the elements in reverse order
663  unsigned long Element_pt_range = Element_pt.size();
664  for (unsigned long i = Element_pt_range; i > 0; i--)
665  {
666  delete Element_pt[i - 1];
667  Element_pt[i - 1] = 0;
668  }
669 
670  // Wipe the storage for all externally-based elements and delete halos
672  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition: mesh.h:183
void delete_all_external_storage()
Wipe the storage for all externally-based elements.
Definition: mesh.cc:9190
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition: mesh.h:186

References delete_all_external_storage(), Element_pt, i, and Node_pt.

Member Function Documentation

◆ add_boundary_node()

void oomph::Mesh::add_boundary_node ( const unsigned b,
Node *const &  node_pt 
)

Add a (pointer to) a node to the b-th boundary.

Add the node node_pt to the b-th boundary of the mesh This function also sets the boundary information in the Node itself

244  {
245  // Tell the node that it's on boundary b.
246  // At this point, if the node is not a BoundaryNode, the function
247  // should throw an exception.
249 
250  // Get the size of the Boundary_node_pt vector
251  unsigned nbound_node = Boundary_node_pt[b].size();
252  bool node_already_on_this_boundary = false;
253  // Loop over the vector
254  for (unsigned n = 0; n < nbound_node; n++)
255  {
256  // is the current node here already?
257  if (node_pt == Boundary_node_pt[b][n])
258  {
259  node_already_on_this_boundary = true;
260  }
261  }
262 
263  // Add the base node pointer to the vector if it's not there already
264  if (!node_already_on_this_boundary)
265  {
266  Boundary_node_pt[b].push_back(node_pt);
267  }
268  }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Scalar * b
Definition: benchVecAdd.cpp:17
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Definition: mesh.h:436
Vector< Vector< Node * > > Boundary_node_pt
Definition: mesh.h:83
virtual void add_to_boundary(const unsigned &b)
Definition: nodes.cc:2336

References oomph::Node::add_to_boundary(), b, Boundary_node_pt, n, and node_pt().

Referenced by STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_mesh(), oomph::RefineableQElement< 3 >::build(), oomph::RefineableQElement< 2 >::build(), oomph::GmshTetMesh< ELEMENT >::build_from_scaffold(), CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::change_boundaries(), oomph::ChannelWithLeafletMesh< ELEMENT >::ChannelWithLeafletMesh(), oomph::CollapsibleChannelMesh< ELEMENT >::CollapsibleChannelMesh(), oomph::GmshTetScaffoldMesh::create_mesh_from_msh_file(), oomph::EighthSphereMesh< ELEMENT >::EighthSphereMesh(), ElasticTwoLayerMesh< ELEMENT >::ElasticTwoLayerMesh(), oomph::FSIDrivenCavityMesh< ELEMENT >::FSIDrivenCavityMesh(), oomph::FullCircleMesh< ELEMENT >::FullCircleMesh(), oomph::GeompackQuadScaffoldMesh::GeompackQuadScaffoldMesh(), oomph::PRefineableQElement< 2, INITIAL_NNODE_1D >::p_refine(), oomph::PRefineableQElement< 3, INITIAL_NNODE_1D >::p_refine(), oomph::QuarterCircleSectorMesh< ELEMENT >::QuarterCircleSectorMesh(), oomph::QuarterTubeMesh< ELEMENT >::QuarterTubeMesh(), oomph::PRefineableQElement< 2, INITIAL_NNODE_1D >::rebuild_from_sons(), oomph::PRefineableQElement< 3, INITIAL_NNODE_1D >::rebuild_from_sons(), oomph::RefineableQSpectralElement< 3 >::rebuild_from_sons(), oomph::RefineableQSpectralElement< 2 >::rebuild_from_sons(), oomph::RectangleWithHoleMesh< ELEMENT >::RectangleWithHoleMesh(), oomph::SimpleCubicScaffoldTetMesh::SimpleCubicScaffoldTetMesh(), oomph::SimpleRectangularTriMesh< ELEMENT >::SimpleRectangularTriMesh(), oomph::TetgenScaffoldMesh::TetgenScaffoldMesh(), oomph::ThinLayerBrickOnTetMesh< ELEMENT >::ThinLayerBrickOnTetMesh(), oomph::TriangleScaffoldMesh::TriangleScaffoldMesh(), and oomph::TubeMesh< ELEMENT >::TubeMesh().

◆ add_element_pt()

void oomph::Mesh::add_element_pt ( GeneralisedElement *const &  element_pt)
inline

Add a (pointer to) an element to the mesh.

618  {
619  Element_pt.push_back(element_pt);
620  }
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
Definition: mesh.h:460

References Element_pt, and element_pt().

Referenced by ABCProblem< ELEMENT, TIMESTEPPERT >::ABCProblem(), UnstructuredFvKProblem< ELEMENT >::actions_after_adapt(), FlowAroundCylinderProblem< ELEMENT >::add_eigenproblem(), AirwayReopeningProblem< ELEMENT >::AirwayReopeningProblem(), AxisymFreeSurfaceNozzleAdvDiffRobinProblem< ELEMENT >::AxisymFreeSurfaceNozzleAdvDiffRobinProblem(), oomph::BackupMeshForProjection< GEOMETRIC_ELEMENT >::BackupMeshForProjection(), build_face_mesh(), CapProblem< ELEMENT >::CapProblem(), ContactProblem< ELEMENT >::complete_problem_setup(), ContinuationProblem::ContinuationProblem(), ConvectionProblem< NST_ELEMENT, AD_ELEMENT >::ConvectionProblem(), ContactProblem< ELEMENT >::create_contact_elements(), ContactProblem< ELEMENT >::create_contact_heat_elements_on_boulder(), ContactProblem< ELEMENT >::create_displ_imposition_elements(), ScatteringProblem< ELEMENT >::create_flux_elements(), PMLProblem< ELEMENT >::create_flux_elements(), TwoMeshFluxAdvectionDiffusionProblem< ELEMENT >::create_flux_elements(), LinearWaveProblem< ELEMENT, TIMESTEPPER >::create_flux_elements(), RefineableUnsteadyHeatProblem< ELEMENT >::create_flux_elements(), RefineableTwoMeshFluxPoissonProblem< ELEMENT >::create_flux_elements(), AxisymFreeSurfaceNozzleAdvDiffRobinProblem< ELEMENT >::create_flux_elements(), FluxPoissonMGProblem< ELEMENT, MESH >::create_flux_elements(), TwoMeshFluxPoissonProblem< ELEMENT >::create_flux_elements(), TwoMeshFluxSteadyAxisymAdvectionDiffusionProblem< ELEMENT >::create_flux_elements(), RefineableRotatingCylinderProblem< ELEMENT >::create_free_surface_elements(), ContactProblem< ELEMENT >::create_imposed_heat_flux_elements_on_boulder(), HelmholtzPointSourceProblem< ELEMENT >::create_outer_bc_elements(), ScatteringProblem< ELEMENT >::create_outer_bc_elements(), TiltedCavityProblem< ELEMENT >::create_parall_outflow_lagrange_elements(), PMLProblem< ELEMENT >::create_power_elements(), CollapsibleChannelProblem< ELEMENT >::create_traction_elements(), RayleighTractionProblem< ELEMENT, TIMESTEPPER >::create_traction_elements(), FSICollapsibleChannelProblem< ELEMENT >::create_traction_elements(), SheetGlueProblem< ELEMENT >::create_traction_elements(), RefineableRotatingCylinderProblem< ELEMENT >::create_volume_constraint_elements(), FreeSurfaceRotationProblem< ELEMENT >::create_volume_constraint_elements(), OscRingNStProblem< ELEMENT >::doc_solution(), OscRingNStProblem< ELEMENT >::doc_solution_historic(), ElasticInterfaceProblem< ELEMENT, TIMESTEPPER >::ElasticInterfaceProblem(), FreeBoundaryPoissonProblem< ELEMENT >::FreeBoundaryPoissonProblem(), FSICollapsibleChannelProblem< ELEMENT >::FSICollapsibleChannelProblem(), GeomObjectAsGeneralisedElementProblem::GeomObjectAsGeneralisedElementProblem(), InterfaceProblem< ELEMENT, TIMESTEPPER >::InterfaceProblem(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::make_free_surface_elements(), ElasticRefineableQuarterCircleSectorMesh< ELEMENT >::make_traction_element_mesh(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::make_traction_elements(), MeltSpinningProblem< ELEMENT >::MeltSpinningProblem(), oomph::LinearElasticitySmoothMesh< LINEAR_ELASTICITY_ELEMENT >::operator()(), oomph::PoissonSmoothMesh< POISSON_ELEMENT >::operator()(), OscRingNStProblem< ELEMENT >::OscRingNStProblem(), PredPreyProblem< ELEMENT >::PredPreyProblem(), RefineableFishPoissonProblem< ELEMENT >::RefineableFishPoissonProblem(), RefineableYoungLaplaceProblem< ELEMENT >::RefineableYoungLaplaceProblem(), ElasticRefineableQuarterCircleSectorMesh< ELEMENT >::remake_traction_element_mesh(), run_navier_stokes_outflow(), MortaringHelpers::setup_constraint_elements_at_nodes(), ShellProblem< ELEMENT >::ShellProblem(), UnstructuredImmersedEllipseProblem< ELEMENT >::UnstructuredImmersedEllipseProblem(), oomph::WomersleyMesh< WOMERSLEY_ELEMENT >::WomersleyMesh(), and oomph::WomersleyProblem< ELEMENT, DIM >::WomersleyProblem().

◆ add_node_pt()

◆ assign_global_eqn_numbers()

unsigned long oomph::Mesh::assign_global_eqn_numbers ( Vector< double * > &  Dof_pt)
protected

Assign (global) equation numbers to the nodes.

Assign the global equation numbers in the Data stored at the nodes and also internal element Data. Also, build (via push_back) the Vector of pointers to the dofs (variables).

678  {
679  // Find out the current number of equations
680  unsigned long equation_number = Dof_pt.size();
681 
682  // Loop over the nodes and call their assigment functions
683  unsigned long nnod = Node_pt.size();
684 
685  for (unsigned long i = 0; i < nnod; i++)
686  {
687  Node_pt[i]->assign_eqn_numbers(equation_number, Dof_pt);
688  }
689 
690  // Loop over the elements and number their internals
691  unsigned long nel = Element_pt.size();
692  for (unsigned long i = 0; i < nel; i++)
693  {
694  Element_pt[i]->assign_internal_eqn_numbers(equation_number, Dof_pt);
695  }
696 
697  // Return the total number of equations
698  return (equation_number);
699  }

References Element_pt, i, and Node_pt.

Referenced by oomph::Problem::assign_eqn_numbers(), and oomph::PerturbedSpineMesh::assign_global_eqn_numbers().

◆ assign_initial_values_impulsive()

void oomph::Mesh::assign_initial_values_impulsive ( )

Assign initial values for an impulsive start.

Assign the initial values for an impulsive start, which is acheived by looping over all data in the mesh (internal element data and data stored at nodes) and setting the calling the assign_initial_values_impulsive() function for each data's timestepper

2289  {
2290  // Loop over the elements
2291  unsigned long Nelement = nelement();
2292  for (unsigned long e = 0; e < Nelement; e++)
2293  {
2294  // Find the number of internal dofs
2295  unsigned Ninternal = element_pt(e)->ninternal_data();
2296  // Loop over internal dofs and shift the time values
2297  // using the internals data's timestepper
2298  for (unsigned j = 0; j < Ninternal; j++)
2299  {
2300  element_pt(e)
2301  ->internal_data_pt(j)
2302  ->time_stepper_pt()
2303  ->assign_initial_values_impulsive(element_pt(e)->internal_data_pt(j));
2304  }
2305  }
2306 
2307  // Loop over the nodes
2308  unsigned long n_node = nnode();
2309  for (unsigned long n = 0; n < n_node; n++)
2310  {
2311  // Assign initial values using the Node's timestepper
2312  Node_pt[n]->time_stepper_pt()->assign_initial_values_impulsive(
2313  Node_pt[n]);
2314  // Assign initial positions using the Node's timestepper
2315  Node_pt[n]
2316  ->position_time_stepper_pt()
2317  ->assign_initial_positions_impulsive(Node_pt[n]);
2318  }
2319  }
Array< double, 1, 3 > e(1./3., 0.5, 2.)
unsigned long nnode() const
Return number of nodes in the mesh.
Definition: mesh.h:596
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References e(), element_pt(), j, n, nelement(), nnode(), and Node_pt.

Referenced by oomph::Problem::assign_initial_values_impulsive().

◆ assign_local_eqn_numbers()

void oomph::Mesh::assign_local_eqn_numbers ( const bool store_local_dof_pt)
protected

Assign local equation numbers in all elements.

Assign the local equation numbers in all elements If the boolean argument is true then also store pointers to dofs

766  {
767  // Now loop over the elements and assign local equation numbers
768  unsigned long Element_pt_range = Element_pt.size();
769  for (unsigned long i = 0; i < Element_pt_range; i++)
770  {
771  Element_pt[i]->assign_local_eqn_numbers(store_local_dof_pt);
772  }
773  }

References Element_pt, and i.

Referenced by oomph::Problem::assign_eqn_numbers().

◆ boundary_coordinate_exists()

bool oomph::Mesh::boundary_coordinate_exists ( const unsigned i) const
inline

Indicate whether the i-th boundary has an intrinsic coordinate.

566  {
567  if (Boundary_coordinate_exists.empty())
568  {
569  return false;
570  }
571  // ALH: This bounds-checking code needs to remain, because
572  // Boundary_coordinate_exists is
573  // an stl vector not our overloaded Vector class
574 #ifdef RANGE_CHECKING
575  if (i >= Boundary_coordinate_exists.size())
576  {
577  std::ostringstream error_message;
578  error_message << "Range Error: " << i << " is not in the range (0,"
579  << Boundary_coordinate_exists.size() - 1 << std::endl;
580 
581  throw OomphLibError(error_message.str(),
584  }
585 #endif
587  }
std::vector< bool > Boundary_coordinate_exists
Definition: mesh.h:190
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References Boundary_coordinate_exists, i, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

Referenced by oomph::RefineableQElement< 3 >::build(), oomph::RefineableQElement< 2 >::build(), ElasticTwoLayerMesh< ELEMENT >::ElasticTwoLayerMesh(), oomph::PRefineableQElement< 2, INITIAL_NNODE_1D >::p_refine(), oomph::PRefineableQElement< 3, INITIAL_NNODE_1D >::p_refine(), oomph::PRefineableQElement< 2, INITIAL_NNODE_1D >::rebuild_from_sons(), oomph::PRefineableQElement< 3, INITIAL_NNODE_1D >::rebuild_from_sons(), oomph::RefineableQSpectralElement< 3 >::rebuild_from_sons(), and oomph::RefineableQSpectralElement< 2 >::rebuild_from_sons().

◆ boundary_element_pt()

FiniteElement* oomph::Mesh::boundary_element_pt ( const unsigned b,
const unsigned e 
) const
inline

Return pointer to e-th finite element on boundary b.

842  {
843 #ifdef PARANOID
845  {
846  throw OomphLibError("Lookup scheme for elements next to boundary "
847  "hasn't been set up yet!\n",
850  }
851 #endif
852  return Boundary_element_pt[b][e];
853  }
Vector< Vector< FiniteElement * > > Boundary_element_pt
Definition: mesh.h:91

References b, Boundary_element_pt, e(), Lookup_for_elements_next_boundary_is_setup, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

Referenced by oomph::RefineableTetgenMesh< ELEMENT >::adapt(), oomph::RefineableGmshTetMesh< ELEMENT >::adapt(), oomph::TreeBasedRefineableMeshBase::adapt_mesh(), build_face_mesh(), CapProblem< ELEMENT >::CapProblem(), ContactProblem< ELEMENT >::create_contact_heat_elements_on_boulder(), ScatteringProblem< ELEMENT >::create_flux_elements(), PMLProblem< ELEMENT >::create_flux_elements(), TwoMeshFluxAdvectionDiffusionProblem< ELEMENT >::create_flux_elements(), LinearWaveProblem< ELEMENT, TIMESTEPPER >::create_flux_elements(), RefineableUnsteadyHeatProblem< ELEMENT >::create_flux_elements(), RefineableTwoMeshFluxPoissonProblem< ELEMENT >::create_flux_elements(), AxisymFreeSurfaceNozzleAdvDiffRobinProblem< ELEMENT >::create_flux_elements(), TwoMeshFluxPoissonProblem< ELEMENT >::create_flux_elements(), TwoMeshFluxSteadyAxisymAdvectionDiffusionProblem< ELEMENT >::create_flux_elements(), RefineableRotatingCylinderProblem< ELEMENT >::create_free_surface_elements(), ContactProblem< ELEMENT >::create_imposed_heat_flux_elements_on_boulder(), FSICollapsibleChannelProblem< ELEMENT >::create_lagrange_multiplier_elements(), CollapsibleChannelProblem< ELEMENT >::create_lagrange_multiplier_elements(), HelmholtzPointSourceProblem< ELEMENT >::create_outer_bc_elements(), ScatteringProblem< ELEMENT >::create_outer_bc_elements(), TiltedCavityProblem< ELEMENT >::create_parall_outflow_lagrange_elements(), PMLProblem< ELEMENT >::create_power_elements(), CollapsibleChannelProblem< ELEMENT >::create_traction_elements(), RayleighTractionProblem< ELEMENT, TIMESTEPPER >::create_traction_elements(), FSICollapsibleChannelProblem< ELEMENT >::create_traction_elements(), SheetGlueProblem< ELEMENT >::create_traction_elements(), RefineableRotatingCylinderProblem< ELEMENT >::create_volume_constraint_elements(), doc_boundary_coordinates(), oomph::ExtrudedCubeMeshFromQuadMesh< ELEMENT >::get_element_boundary_information(), oomph::NavierStokesSchurComplementPreconditioner::get_pressure_advection_diffusion_matrix(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::make_free_surface_elements(), oomph::jh_mesh< ELEMENT >::make_shear_elements(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::make_traction_elements(), oomph::jh_mesh< ELEMENT >::make_traction_elements(), oomph::streamfunction_mesh::make_traction_elements(), oomph::NonLinearElasticitySmoothMesh< ELEMENT >::operator()(), oomph::TreeBasedRefineableMeshBase::p_adapt_mesh(), oomph::PMLQuadMeshBase< ELEMENT >::pml_locate_zeta(), QFaceTestProblem< ELEMENT >::QFaceTestProblem(), run_navier_stokes_outflow(), oomph::TetMeshBase::setup_boundary_coordinates(), oomph::UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates(), oomph::RefineableTetgenMesh< ELEMENT >::snap_nodes_onto_boundary(), oomph::TetMeshBase::snap_to_quadratic_surface(), oomph::TetMeshBase::split_elements_in_corners(), TFaceTestProblem< ELEMENT >::TFaceTestProblem(), oomph::ThinLayerBrickOnTetMesh< ELEMENT >::ThinLayerBrickOnTetMesh(), TriangleFaceTestProblem< ELEMENT >::TriangleFaceTestProblem(), and oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::validate().

◆ boundary_node_pt() [1/2]

Node*& oomph::Mesh::boundary_node_pt ( const unsigned b,
const unsigned n 
)
inline

Return pointer to node n on boundary b.

494  {
495  return Boundary_node_pt[b][n];
496  }

References b, Boundary_node_pt, and n.

Referenced by FSICollapsibleChannelProblem< ELEMENT >::actions_after_adapt(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_implicit_timestep(), oomph::StreamfunctionProblem::actions_before_solve(), oomph::RefineableTetgenMesh< ELEMENT >::adapt(), oomph::RefineableGmshTetMesh< ELEMENT >::adapt(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_mesh(), oomph::SolidMesh::boundary_node_pt(), build_face_mesh(), oomph::ExtrudedCubeMeshFromQuadMesh< ELEMENT >::build_mesh(), RectangularWomersleyImpedanceTube< ELEMENT >::build_mesh_and_apply_boundary_conditions(), CombCanSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), CapProblem< ELEMENT >::CapProblem(), CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::change_boundaries(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::complete_build(), oomph::TwoDimensionalPMLHelper::create_bottom_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_bottom_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_bottom_right_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_right_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_right_pml_mesh(), MeltSpinningProblem< ELEMENT >::deform_free_surface(), AxisymFreeSurfaceNozzleAdvDiffRobinProblem< ELEMENT >::deform_free_surface(), InterfaceProblem< ELEMENT, TIMESTEPPER >::deform_free_surface(), FluxPoissonProblem< ELEMENT >::FluxPoissonProblem(), FSIRingProblem::FSIRingProblem(), merge_meshes(), OneDPoissonProblem< ELEMENT >::OneDPoissonProblem(), OrrSommerfeldProblem< ELEMENT >::OrrSommerfeldProblem(), oomph::PeriodicOrbitTemporalMesh< ELEMENT >::PeriodicOrbitTemporalMesh(), oomph::StreamfunctionProblem::pin_boundaries(), oomph::PMLCornerQuadMesh< ELEMENT >::PMLCornerQuadMesh(), oomph::PMLQuadMesh< ELEMENT >::PMLQuadMesh(), PseudoSolidCapProblem< ELEMENT >::PseudoSolidCapProblem(), QuarterCircleDrivenCavityProblem< ELEMENT >::QuarterCircleDrivenCavityProblem(), QuarterCircleDrivenCavityProblem2< ELEMENT >::QuarterCircleDrivenCavityProblem2(), oomph::QuarterPipeMesh< ELEMENT >::QuarterPipeMesh(), oomph::RefineableQuadMeshWithMovingCylinder< ELEMENT >::RefineableQuadMeshWithMovingCylinder(), remove_boundary_nodes(), run_navier_stokes_outflow(), run_prescribed_flux(), run_prescribed_pressure_gradient(), oomph::TetMeshBase::setup_boundary_coordinates(), oomph::RefineableTetgenMesh< ELEMENT >::snap_nodes_onto_boundary(), oomph::TetMeshBase::snap_nodes_onto_geometric_objects(), oomph::UnstructuredTwoDMeshGeometryBase::snap_nodes_onto_geometric_objects(), oomph::ThinLayerBrickOnTetMesh< ELEMENT >::ThinLayerBrickOnTetMesh(), and TurekProblem< FLUID_ELEMENT, SOLID_ELEMENT >::TurekProblem().

◆ boundary_node_pt() [2/2]

Node* oomph::Mesh::boundary_node_pt ( const unsigned b,
const unsigned n 
) const
inline

Return pointer to node n on boundary b.

500  {
501  return Boundary_node_pt[b][n];
502  }

References b, Boundary_node_pt, and n.

◆ build_face_mesh()

template<class BULK_ELEMENT , template< class > class FACE_ELEMENT>
void oomph::Mesh::build_face_mesh ( const unsigned b,
Mesh *const &  face_mesh_pt 
)
inline

Constuct a Mesh of FACE_ELEMENTs along the b-th boundary of the mesh (which contains elements of type BULK_ELEMENT)

654  {
655  // Find the number of nodes on the boundary
656  unsigned nbound_node = nboundary_node(b);
657  // Loop over the boundary nodes and add them to face mesh node pointer
658  for (unsigned n = 0; n < nbound_node; n++)
659  {
660  face_mesh_pt->add_node_pt(boundary_node_pt(b, n));
661  }
662 
663  // Find the number of elements next to the boundary
664  unsigned nbound_element = nboundary_element(b);
665  // Loop over the elements adjacent to boundary b
666  for (unsigned e = 0; e < nbound_element; e++)
667  {
668  // Create the FaceElement
669  FACE_ELEMENT<BULK_ELEMENT>* face_element_pt =
670  new FACE_ELEMENT<BULK_ELEMENT>(boundary_element_pt(b, e),
672 
673  // Add the face element to the face mesh
674  face_mesh_pt->add_element_pt(face_element_pt);
675  }
676 
677 #ifdef OOMPH_HAS_MPI
678  // If the bulk mesh has been distributed then the face mesh is too
679  if (this->is_mesh_distributed())
680  {
681  face_mesh_pt->set_communicator_pt(this->communicator_pt());
682  }
683 #endif
684  }
unsigned long nboundary_node(const unsigned &ibound) const
Return number of nodes on a particular boundary.
Definition: mesh.h:833
bool is_mesh_distributed() const
Boolean to indicate if Mesh has been distributed.
Definition: mesh.h:1588
OomphCommunicator * communicator_pt() const
Definition: mesh.h:1600
int face_index_at_boundary(const unsigned &b, const unsigned &e) const
Definition: mesh.h:896
unsigned nboundary_element(const unsigned &b) const
Return number of finite elements that are adjacent to boundary b.
Definition: mesh.h:878
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
Node *& boundary_node_pt(const unsigned &b, const unsigned &n)
Return pointer to node n on boundary b.
Definition: mesh.h:493

References add_element_pt(), add_node_pt(), b, boundary_element_pt(), boundary_node_pt(), communicator_pt(), e(), face_index_at_boundary(), is_mesh_distributed(), n, nboundary_element(), and nboundary_node().

◆ calculate_predictions()

void oomph::Mesh::calculate_predictions ( )

Calculate predictions for all Data and positions associated with the mesh, usually used in adaptive time-stepping.

Calculate predictions for all Data and positions associated with the mesh. This is usually only used for adaptive time-stepping when the comparison between a predicted value and the actual value is usually used to determine the change in step size. Again the loop is over all data in the mesh and individual timestepper functions for each data value are called.

2367  {
2368  // Loop over the elements which shift their internal data
2369  // via their own timesteppers
2370  const unsigned long Nelement = nelement();
2371  for (unsigned long e = 0; e < Nelement; e++)
2372  {
2373  // Find the number of internal dofs
2374  const unsigned Ninternal = element_pt(e)->ninternal_data();
2375  // Loop over internal dofs and calculate predicted positions
2376  // using the internals data's timestepper
2377  for (unsigned j = 0; j < Ninternal; j++)
2378  {
2379  element_pt(e)
2380  ->internal_data_pt(j)
2381  ->time_stepper_pt()
2382  ->calculate_predicted_values(element_pt(e)->internal_data_pt(j));
2383  }
2384  }
2385 
2386  // Loop over the nodes
2387  const unsigned long n_node = nnode();
2388  for (unsigned long n = 0; n < n_node; n++)
2389  {
2390  // Calculate the predicted values at the nodes
2391  Node_pt[n]->time_stepper_pt()->calculate_predicted_values(Node_pt[n]);
2392  // Calculate the predicted positions
2393  Node_pt[n]->position_time_stepper_pt()->calculate_predicted_positions(
2394  Node_pt[n]);
2395  }
2396  }

References e(), element_pt(), j, n, nelement(), nnode(), and Node_pt.

Referenced by oomph::Problem::calculate_predictions().

◆ check_for_repeated_nodes()

unsigned oomph::Mesh::check_for_repeated_nodes ( const double epsilon = 1.0e-12)
inline

Check for repeated nodes within a given spatial tolerance. Return (0/1) for (pass/fail).

753  {
754  oomph_info << "\n\nStarting check for repeated nodes...";
755  bool failed = false;
756  unsigned nnod = nnode();
757  for (unsigned j = 0; j < nnod; j++)
758  {
759  Node* nod1_pt = this->node_pt(j);
760  unsigned dim = nod1_pt->ndim();
761  for (unsigned k = j + 1; k < nnod; k++)
762  {
763  Node* nod2_pt = this->node_pt(k);
764  double dist = 0.0;
765  for (unsigned i = 0; i < dim; i++)
766  {
767  dist += pow((nod1_pt->x(i) - nod2_pt->x(i)), 2);
768  }
769  dist = sqrt(dist);
770  if (dist < epsilon)
771  {
772  oomph_info << "\n\nRepeated node!" << std::endl;
773  oomph_info << "Distance between nodes " << j << " and " << k
774  << std::endl;
775  oomph_info << "is " << dist << " which is less than the"
776  << std::endl;
777  oomph_info << "permitted distance of " << epsilon << std::endl
778  << std::endl;
779  oomph_info << "The offending nodes are located at: " << std::endl;
780  for (unsigned i = 0; i < dim; i++)
781  {
782  oomph_info << nod1_pt->x(i) << " ";
783  }
784  if (nod1_pt->is_a_copy() || nod2_pt->is_a_copy())
785  {
786  oomph_info << "\n\n[NOTE: message issued as diagonistic rather "
787  "than an error\n"
788  << " because at least one of the nodes is a copy; you "
789  "may still\n"
790  << " want to check this out. BACKGROUND: Copied nodes "
791  "share the same Data but\n"
792  << " will, in general, have different spatial "
793  "positions (e.g. when used\n"
794  << " as periodic nodes); however there are cases when "
795  "they are located\n"
796  << " at the same spatial position (e.g. in "
797  "oomph-lib's annular mesh which\n"
798  << " is a rolled-around version of the rectangular "
799  "quadmesh). In such cases,\n"
800  << " the nodes could have been deleted and completely "
801  "replaced by \n"
802  << " pointers to existing nodes, but may have been "
803  "left there for convenience\n"
804  << " or out of laziness...]\n";
805  }
806  else
807  {
808  failed = true;
809  }
810  oomph_info << std::endl << std::endl;
811  }
812  }
813  }
814  if (failed) return 1;
815 
816  // If we made it to here, we must have passed the test.
817  oomph_info << "...done: Test passed!" << std::endl << std::endl;
818  return 0;
819  }
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
char char char int int * k
Definition: level2_impl.h:374
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
double epsilon
Definition: osc_ring_sarah_asymptotics.h:43
OomphInfo oomph_info
Definition: oomph_definitions.cc:319

References oomph::SarahBL::epsilon, i, oomph::Data::is_a_copy(), j, k, oomph::Node::ndim(), nnode(), node_pt(), oomph::oomph_info, Eigen::bfloat16_impl::pow(), sqrt(), and oomph::Node::x().

Referenced by self_test().

◆ check_inverted_elements() [1/2]

void oomph::Mesh::check_inverted_elements ( bool mesh_has_inverted_elements)
inline

Check for inverted elements and report outcome in boolean variable. This visits all elements at their integration points and checks if the Jacobian of the mapping between local and global coordinates is positive – using the same test that would be carried out (but only in PARANOID mode) during the assembly of the elements' Jacobian matrices.

743  {
744  std::ofstream inverted_element_file;
745  check_inverted_elements(mesh_has_inverted_elements,
746  inverted_element_file);
747  }
void check_inverted_elements(bool &mesh_has_inverted_elements, std::ofstream &inverted_element_file)
Definition: mesh.cc:870

References check_inverted_elements().

◆ check_inverted_elements() [2/2]

void oomph::Mesh::check_inverted_elements ( bool mesh_has_inverted_elements,
std::ofstream &  inverted_element_file 
)

Check for inverted elements and report outcome in boolean variable. This visits all elements at their integration points and checks if the Jacobian of the mapping between local and global coordinates is positive – using the same test that would be carried out (but only in PARANOID mode) during the assembly of the elements' Jacobian matrices. Inverted elements are output in inverted_element_file (if the stream is open).

872  {
873  // Initialise flag
874  mesh_has_inverted_elements = false;
875 
876  // Suppress output while checking for inverted elements
877  bool backup =
880 
881  // Loop over all elements
882  unsigned nelem = nelement();
883  for (unsigned e = 0; e < nelem; e++)
884  {
885  FiniteElement* el_pt = finite_element_pt(e);
886 
887  // Only check for finite elements
888  if (el_pt != 0)
889  {
890  // Find out number of nodes and local coordinates in the element
891  unsigned n_node = el_pt->nnode();
892  unsigned n_dim = el_pt->dim();
893  unsigned ndim_node = el_pt->nodal_dimension();
894 
895  // Can't check Jacobian for elements in which nodal and elementa
896  // dimensions don't match
897  if (n_dim == ndim_node)
898  {
899  // Set up memory for the shape and test function and local coord
900  Shape psi(n_node);
901  DShape dpsidx(n_node, n_dim);
902  Vector<double> s(n_dim);
903 
904  // Initialise element-level test
905  bool is_inverted = false;
906 
907  unsigned n_intpt = el_pt->integral_pt()->nweight();
908  for (unsigned ipt = 0; ipt < n_intpt; ipt++)
909  {
910  // Local coordinates
911  for (unsigned i = 0; i < n_dim; i++)
912  {
913  s[i] = el_pt->integral_pt()->knot(ipt, i);
914  }
915 
916  double J = 0;
917  // Dummy assignment to keep gcc from complaining about
918  // "set but unused".
919  J += 0.0;
920  try
921  {
922  // Call the derivatives of the shape functions and Jacobian
923  J = el_pt->dshape_eulerian(s, psi, dpsidx);
924 
925  // If code is compiled without PARANOID setting, the
926  // above call will simply return the negative Jacobian
927  // without failing, so we need to check manually
928 #ifndef PARANOID
929  try
930  {
931  el_pt->check_jacobian(J);
932  }
933  catch (OomphLibQuietException& error)
934  {
935  is_inverted = true;
936  }
937 #endif
938  }
939  catch (OomphLibQuietException& error)
940  {
941  is_inverted = true;
942  }
943  }
944  if (is_inverted)
945  {
946  mesh_has_inverted_elements = true;
947  if (inverted_element_file.is_open())
948  {
949  el_pt->output(inverted_element_file);
950  }
951  }
952  }
953  }
954  }
955  // Reset
957  backup;
958  }
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
static bool Suppress_output_while_checking_for_inverted_elements
Definition: elements.h:1779
FiniteElement * finite_element_pt(const unsigned &e) const
Definition: mesh.h:473
RealScalar s
Definition: level1_cplx_impl.h:130
int error
Definition: calibrate.py:297

References oomph::FiniteElement::check_jacobian(), oomph::FiniteElement::dim(), oomph::FiniteElement::dshape_eulerian(), e(), calibrate::error, finite_element_pt(), i, oomph::FiniteElement::integral_pt(), J, oomph::Integral::knot(), nelement(), oomph::FiniteElement::nnode(), oomph::FiniteElement::nodal_dimension(), oomph::Integral::nweight(), oomph::FiniteElement::output(), s, and oomph::FiniteElement::Suppress_output_while_checking_for_inverted_elements.

Referenced by check_inverted_elements(), demo_smoothing_with_linear_elasticity(), demo_smoothing_with_nonlinear_elasticity(), demo_smoothing_with_poisson(), and oomph::NonLinearElasticitySmoothMesh< ELEMENT >::doc_solution().

◆ communicator_pt()

OomphCommunicator* oomph::Mesh::communicator_pt ( ) const
inline

Read-only access fct to communicator (Null if mesh is not distributed, i.e. if we don't have mpi).

1601  {
1602 #ifdef OOMPH_HAS_MPI
1603  return Comm_pt;
1604 #else
1605  return 0;
1606 #endif
1607  }

Referenced by build_face_mesh(), oomph::MeshAsGeomObject::build_it(), oomph::Z2ErrorEstimator::doc_flux(), oomph::Z2ErrorEstimator::get_element_errors(), and is_mesh_distributed().

◆ compute_error() [1/8]

virtual void oomph::Mesh::compute_error ( FiniteElement::SteadyExactSolutionFctPt  exact_soln_pt,
double error,
double norm 
)
inlinevirtual

Plot error when compared against a given time-dependent exact solution. Also returns the norm of the error and that of the exact solution

1235  {
1236  // Initialise norm and error
1237  norm = 0.0;
1238  error = 0.0;
1239 
1240  // Per-element norm and error
1241  double el_error, el_norm;
1242 
1243  // Loop over the elements
1244  unsigned long Element_pt_range = Element_pt.size();
1245  for (unsigned long e = 0; e < Element_pt_range; e++)
1246  {
1247  // Try to cast to FiniteElement
1248  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1249  if (el_pt == 0)
1250  {
1251  throw OomphLibError(
1252  "Can't execute compute_error(...) for non FiniteElements",
1255  }
1256 
1257  // Reset elemental errors and norms
1258  el_norm = 0.0;
1259  el_error = 0.0;
1260 
1261  // Calculate the elemental errors for each non-halo element
1262 #ifdef OOMPH_HAS_MPI
1263  if (!(el_pt->is_halo()))
1264 #endif
1265  {
1266  el_pt->compute_error(exact_soln_pt, el_error, el_norm);
1267  }
1268 
1269  // Add each elemental error to the global error
1270  norm += el_norm;
1271  error += el_error;
1272  }
1273  } // End of compute_error

References oomph::FiniteElement::compute_error(), e(), Element_pt, calibrate::error, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ compute_error() [2/8]

virtual void oomph::Mesh::compute_error ( FiniteElement::SteadyExactSolutionFctPt  exact_soln_pt,
Vector< double > &  error,
Vector< double > &  norm 
)
inlinevirtual

Plot error when compared against a given time-dependent exact solution. Also returns the norm of the error and that of the exact solution

1283  {
1284  // Initialise norm vector entries
1285  norm.initialise(0.0);
1286 
1287  // Initialise error vector entries
1288  error.initialise(0.0);
1289 
1290  // Norm vector size
1291  unsigned n_norm = norm.size();
1292 
1293  // Error vector size
1294  unsigned n_error = error.size();
1295 
1296  // Per-element norm and error
1297  Vector<double> el_norm(n_norm, 0.0);
1298 
1299  // Per-element norm and error
1300  Vector<double> el_error(n_error, 0.0);
1301 
1302  // How many elements are there?
1303  unsigned long element_pt_range = Element_pt.size();
1304 
1305  // Loop over the elements
1306  for (unsigned long e = 0; e < element_pt_range; e++)
1307  {
1308  // Try to cast to FiniteElement
1309  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1310  if (el_pt == 0)
1311  {
1312  throw OomphLibError(
1313  "Can't execute compute_error(...) for non FiniteElements",
1316  }
1317 
1318  // Re-initialise norm vector entries
1319  el_norm.initialise(0.0);
1320 
1321  // Re-initialise error vector entries
1322  el_error.initialise(0.0);
1323 
1324  // Calculate the elemental errors for each non-halo element
1325 #ifdef OOMPH_HAS_MPI
1326  if (!(el_pt->is_halo()))
1327 #endif
1328  {
1329  el_pt->compute_error(exact_soln_pt, el_error, el_norm);
1330  }
1331 
1332  // Add each elemental norm contribution to the global norm
1333  for (unsigned i = 0; i < n_norm; i++)
1334  {
1335  norm[i] += el_norm[i];
1336  }
1337 
1338  // Add each elemental error contribution to the global error
1339  for (unsigned i = 0; i < n_error; i++)
1340  {
1341  error[i] += el_error[i];
1342  }
1343  } // for (unsigned long e=0;e<element_pt_range;e++)
1344  } // End of compute_error
void initialise(const _Tp &__value)
Iterate over all values and set to the desired value.
Definition: oomph-lib/src/generic/Vector.h:167

References oomph::FiniteElement::compute_error(), e(), Element_pt, calibrate::error, i, oomph::Vector< _Tp >::initialise(), OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ compute_error() [3/8]

virtual void oomph::Mesh::compute_error ( FiniteElement::UnsteadyExactSolutionFctPt  exact_soln_pt,
const double time,
double error,
double norm 
)
inlinevirtual

Returns the norm of the error and that of the exact solution.

1484  {
1485  // Initialse the norm and error
1486  norm = 0.0;
1487  error = 0.0;
1488  // Per-element norm and error
1489  double el_error, el_norm;
1490 
1491  // Loop over the elements
1492  unsigned long Element_pt_range = Element_pt.size();
1493  for (unsigned long e = 0; e < Element_pt_range; e++)
1494  {
1495  // Try to cast to FiniteElement
1496  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1497  if (el_pt == 0)
1498  {
1499  throw OomphLibError(
1500  "Can't execute compute_error(...) for non FiniteElements",
1503  }
1504 
1505  // Reset elemental errors and norms
1506  el_norm = 0.0;
1507  el_error = 0.0;
1508 #ifdef OOMPH_HAS_MPI
1509  // Compute error for each non-halo element
1510  if (!(el_pt->is_halo()))
1511 #endif
1512  {
1513  el_pt->compute_error(exact_soln_pt, time, el_error, el_norm);
1514  }
1515  // Add each element error to the global errors
1516  norm += el_norm;
1517  error += el_error;
1518  }
1519  }

References oomph::FiniteElement::compute_error(), e(), Element_pt, calibrate::error, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ compute_error() [4/8]

virtual void oomph::Mesh::compute_error ( FiniteElement::UnsteadyExactSolutionFctPt  exact_soln_pt,
const double time,
Vector< double > &  error,
Vector< double > &  norm 
)
inlinevirtual

Returns the norm of the error and that of the exact solution. Version with vectors of norms and errors so that different variables' norms and errors can be returned individually

1530  {
1531  // Initialise norm and error
1532  unsigned n_error = error.size();
1533  unsigned n_norm = norm.size();
1534  for (unsigned i = 0; i < n_error; i++)
1535  {
1536  error[i] = 0.0;
1537  }
1538  for (unsigned i = 0; i < n_norm; i++)
1539  {
1540  norm[i] = 0.0;
1541  }
1542  // Per-element norm and error
1543  Vector<double> el_error(n_error), el_norm(n_norm);
1544 
1545  // Loop over the elements
1546  unsigned long Element_pt_range = Element_pt.size();
1547  for (unsigned long e = 0; e < Element_pt_range; e++)
1548  {
1549  // Try to cast to FiniteElement
1550  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1551  if (el_pt == 0)
1552  {
1553  throw OomphLibError(
1554  "Can't execute compute_error(...) for non FiniteElements",
1557  }
1558  // Reset elemental errors and norms
1559  for (unsigned i = 0; i < n_error; i++)
1560  {
1561  el_error[i] = 0.0;
1562  }
1563  for (unsigned i = 0; i < n_norm; i++)
1564  {
1565  el_norm[i] = 0.0;
1566  }
1567  // Calculate the elemental errors for each non-halo element
1568 #ifdef OOMPH_HAS_MPI
1569  if (!(el_pt->is_halo()))
1570 #endif
1571  {
1572  el_pt->compute_error(exact_soln_pt, time, el_error, el_norm);
1573  }
1574  // Add each elemental error to the global error
1575  for (unsigned i = 0; i < n_error; i++)
1576  {
1577  error[i] += el_error[i];
1578  }
1579  for (unsigned i = 0; i < n_norm; i++)
1580  {
1581  norm[i] += el_norm[i];
1582  }
1583  } // for (unsigned long e=0;e<Element_pt_range;e++)
1584  } // End of compute_error

References oomph::FiniteElement::compute_error(), e(), Element_pt, calibrate::error, i, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ compute_error() [5/8]

virtual void oomph::Mesh::compute_error ( std::ostream &  outfile,
FiniteElement::SteadyExactSolutionFctPt  exact_soln_pt,
double error,
double norm 
)
inlinevirtual

Plot error when compared against a given time-depdendent exact solution. Also returns the norm of the error and that of the exact solution

1191  {
1192  // Initialise norm and error
1193  norm = 0.0;
1194  error = 0.0;
1195  // Per-element norm and error
1196  double el_error, el_norm;
1197 
1198  // Loop over the elements
1199  unsigned long Element_pt_range = Element_pt.size();
1200  for (unsigned long e = 0; e < Element_pt_range; e++)
1201  {
1202  // Try to cast to FiniteElement
1203  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1204  if (el_pt == 0)
1205  {
1206  throw OomphLibError(
1207  "Can't execute compute_error(...) for non FiniteElements",
1210  }
1211  // Reset elemental errors and norms
1212  el_norm = 0.0;
1213  el_error = 0.0;
1214  // Calculate the elemental errors for each non-halo element
1215 #ifdef OOMPH_HAS_MPI
1216  if (!(el_pt->is_halo()))
1217 #endif
1218  {
1219  el_pt->compute_error(outfile, exact_soln_pt, el_error, el_norm);
1220  }
1221  // Add each elemental error to the global error
1222  norm += el_norm;
1223  error += el_error;
1224  }
1225  }

References oomph::FiniteElement::compute_error(), e(), Element_pt, calibrate::error, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ compute_error() [6/8]

virtual void oomph::Mesh::compute_error ( std::ostream &  outfile,
FiniteElement::SteadyExactSolutionFctPt  exact_soln_pt,
Vector< double > &  error,
Vector< double > &  norm 
)
inlinevirtual

Plot error when compared against a given time-depdendent exact solution. Also returns the norm of the error and that of the exact solution. Version with vectors of norms and errors so that different variables' norms and errors can be returned individually

1422  {
1423  // Initialise norm and error
1424  unsigned n_error = error.size();
1425  unsigned n_norm = norm.size();
1426  for (unsigned i = 0; i < n_error; i++)
1427  {
1428  error[i] = 0.0;
1429  }
1430  for (unsigned i = 0; i < n_norm; i++)
1431  {
1432  norm[i] = 0.0;
1433  }
1434  // Per-element norm and error
1435  Vector<double> el_error(n_error), el_norm(n_norm);
1436 
1437  // Loop over the elements
1438  unsigned long Element_pt_range = Element_pt.size();
1439  for (unsigned long e = 0; e < Element_pt_range; e++)
1440  {
1441  // Try to cast to FiniteElement
1442  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1443  if (el_pt == 0)
1444  {
1445  throw OomphLibError(
1446  "Can't execute compute_error(...) for non FiniteElements",
1449  }
1450  // Reset elemental errors and norms
1451  for (unsigned i = 0; i < n_error; i++)
1452  {
1453  el_error[i] = 0.0;
1454  }
1455  for (unsigned i = 0; i < n_norm; i++)
1456  {
1457  el_norm[i] = 0.0;
1458  }
1459  // Calculate the elemental errors for each non-halo element
1460 #ifdef OOMPH_HAS_MPI
1461  if (!(el_pt->is_halo()))
1462 #endif
1463  {
1464  el_pt->compute_error(outfile, exact_soln_pt, el_error, el_norm);
1465  }
1466  // Add each elemental error to the global error
1467  for (unsigned i = 0; i < n_error; i++)
1468  {
1469  error[i] += el_error[i];
1470  }
1471  for (unsigned i = 0; i < n_norm; i++)
1472  {
1473  norm[i] += el_norm[i];
1474  }
1475  }
1476  }

References oomph::FiniteElement::compute_error(), e(), Element_pt, calibrate::error, i, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ compute_error() [7/8]

virtual void oomph::Mesh::compute_error ( std::ostream &  outfile,
FiniteElement::UnsteadyExactSolutionFctPt  exact_soln_pt,
const double time,
double error,
double norm 
)
inlinevirtual

Plot error when compared against a given exact solution. Also returns the norm of the error and that of the exact solution

1146  {
1147  // Initialse the norm and error
1148  norm = 0.0;
1149  error = 0.0;
1150  // Per-element norm and error
1151  double el_error, el_norm;
1152 
1153  // Loop over the elements
1154  unsigned long Element_pt_range = Element_pt.size();
1155  for (unsigned long e = 0; e < Element_pt_range; e++)
1156  {
1157  // Try to cast to FiniteElement
1158  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1159  if (el_pt == 0)
1160  {
1161  throw OomphLibError(
1162  "Can't execute compute_error(...) for non FiniteElements",
1165  }
1166 
1167  // Reset elemental errors and norms
1168  el_norm = 0.0;
1169  el_error = 0.0;
1170 #ifdef OOMPH_HAS_MPI
1171  // Compute error for each non-halo element
1172  if (!(el_pt->is_halo()))
1173 #endif
1174  {
1175  el_pt->compute_error(outfile, exact_soln_pt, time, el_error, el_norm);
1176  }
1177  // Add each element error to the global errors
1178  norm += el_norm;
1179  error += el_error;
1180  }
1181  }

References oomph::FiniteElement::compute_error(), e(), Element_pt, calibrate::error, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ compute_error() [8/8]

virtual void oomph::Mesh::compute_error ( std::ostream &  outfile,
FiniteElement::UnsteadyExactSolutionFctPt  exact_soln_pt,
const double time,
Vector< double > &  error,
Vector< double > &  norm 
)
inlinevirtual

Plot error when compared against a given time-depdendent exact solution. Also returns the norm of the error and that of the exact solution. Version with vectors of norms and errors so that different variables' norms and errors can be returned individually

1357  {
1358  // Initialise norm and error
1359  unsigned n_error = error.size();
1360  unsigned n_norm = norm.size();
1361  for (unsigned i = 0; i < n_error; i++)
1362  {
1363  error[i] = 0.0;
1364  }
1365  for (unsigned i = 0; i < n_norm; i++)
1366  {
1367  norm[i] = 0.0;
1368  }
1369  // Per-element norm and error
1370  Vector<double> el_error(n_error), el_norm(n_norm);
1371 
1372  // Loop over the elements
1373  unsigned long Element_pt_range = Element_pt.size();
1374  for (unsigned long e = 0; e < Element_pt_range; e++)
1375  {
1376  // Try to cast to FiniteElement
1377  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
1378  if (el_pt == 0)
1379  {
1380  throw OomphLibError(
1381  "Can't execute compute_error(...) for non FiniteElements",
1384  }
1385  // Reset elemental errors and norms
1386  for (unsigned i = 0; i < n_error; i++)
1387  {
1388  el_error[i] = 0.0;
1389  }
1390  for (unsigned i = 0; i < n_norm; i++)
1391  {
1392  el_norm[i] = 0.0;
1393  }
1394  // Calculate the elemental errors for each non-halo element
1395 #ifdef OOMPH_HAS_MPI
1396  if (!(el_pt->is_halo()))
1397 #endif
1398  {
1399  el_pt->compute_error(outfile, exact_soln_pt, time, el_error, el_norm);
1400  }
1401  // Add each elemental error to the global error
1402  for (unsigned i = 0; i < n_error; i++)
1403  {
1404  error[i] += el_error[i];
1405  }
1406  for (unsigned i = 0; i < n_norm; i++)
1407  {
1408  norm[i] += el_norm[i];
1409  }
1410  }
1411  }

References oomph::FiniteElement::compute_error(), e(), Element_pt, calibrate::error, i, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ compute_norm() [1/2]

virtual void oomph::Mesh::compute_norm ( double norm)
inlinevirtual

Compute norm of solution by summing contributions of compute_norm(...) for all constituent elements in the mesh. What that norm means depends on what's defined in the element's function; may need to take the square root afterwards if the elements compute the square of the L2 norm, say.

Reimplemented in ElasticQuadFromTriangleMesh< ELEMENT >.

1069  {
1070  // Initialse the norm
1071  norm = 0.0;
1072 
1073  // Per-element norm
1074  double el_norm = 0;
1075 
1076  // Loop over the elements
1077  unsigned long n_element = Element_pt.size();
1078  for (unsigned long e = 0; e < n_element; e++)
1079  {
1080  GeneralisedElement* el_pt = Element_pt[e];
1081 
1082 #ifdef OOMPH_HAS_MPI
1083  // Compute error for each non-halo element
1084  if (!(el_pt->is_halo()))
1085 #endif
1086  {
1087  el_pt->compute_norm(el_norm);
1088  }
1089  norm += el_norm;
1090  }
1091  }

References oomph::GeneralisedElement::compute_norm(), e(), and Element_pt.

◆ compute_norm() [2/2]

virtual void oomph::Mesh::compute_norm ( Vector< double > &  norm)
inlinevirtual

Compute norm of solution by summing contributions of compute_norm(...) for all constituent elements in the mesh. What that norm means depends on what's defined in the element's function; may need to take the square root afterwards if the elements compute the square of the L2 norm, say.

1100  {
1101  // How many unknowns are there?
1102  unsigned n_entry = norm.size();
1103 
1104  // Initialse the norm
1105  norm.initialise(0.0);
1106 
1107  // Per-element norm
1108  Vector<double> el_norm(n_entry, 0.0);
1109 
1110  // How many elements are there?
1111  unsigned long n_element = Element_pt.size();
1112 
1113  // Loop over the elements
1114  for (unsigned long e = 0; e < n_element; e++)
1115  {
1116  // Get a pointer to the e-th generalised element
1117  GeneralisedElement* el_pt = Element_pt[e];
1118 
1119 #ifdef OOMPH_HAS_MPI
1120  // Compute error for each non-halo element
1121  if (!(el_pt->is_halo()))
1122 #endif
1123  {
1124  // Compute the elemental norm
1125  el_pt->compute_norm(el_norm);
1126  }
1127 
1128  // Loop over the norm vector entries
1129  for (unsigned i = 0; i < n_entry; i++)
1130  {
1131  // Update the norm of the i-th component
1132  norm[i] += el_norm[i];
1133  }
1134  } // for (unsigned long e=0;e<n_element;e++)
1135  } // End of compute_norm

References oomph::GeneralisedElement::compute_norm(), e(), Element_pt, i, and oomph::Vector< _Tp >::initialise().

◆ convert_to_boundary_node() [1/2]

void oomph::Mesh::convert_to_boundary_node ( Node *&  node_pt)
protected

A function that upgrades an ordinary node to a boundary node. All pointers to the node from the mesh's elements are found. and replaced by pointers to the new boundary node. If the node is present in the mesh's list of nodes, that pointer is also replaced. Finally, the pointer argument node_pt addresses the new node on return from the function. We shouldn't ever really use this, but it does make life that bit easier for the lazy mesh writer.

2565  {
2566  // Cache a list of FiniteElement pointers for use in this function.
2567  Vector<FiniteElement*> fe_pt(nelement(), 0);
2568  for (unsigned e = 0, ne = nelement(); e < ne; e++)
2569  {
2570  // Some elements may not have been build yet, just store a null pointer
2571  // for these cases.
2572  if (Element_pt[e] == 0) fe_pt[e] = 0;
2573  else
2574  fe_pt[e] = finite_element_pt(e);
2575  }
2576 
2577  // Now call the real function
2579  }
void convert_to_boundary_node(Node *&node_pt, const Vector< FiniteElement * > &finite_element_pt)
Definition: mesh.cc:2590

References convert_to_boundary_node(), e(), Element_pt, finite_element_pt(), nelement(), and node_pt().

◆ convert_to_boundary_node() [2/2]

void oomph::Mesh::convert_to_boundary_node ( Node *&  node_pt,
const Vector< FiniteElement * > &  finite_element_pt 
)
protected

A function that upgrades an ordinary node to a boundary node We shouldn't ever really use this, but it does make life that bit easier for the lazy mesh writer. The pointer to the node is replaced by a pointer to the new boundary node in all element look-up schemes and in the mesh's Node_pt vector. The new node is also addressed by node_pt on return from the function.

As convert_to_boundary_node but with a vector of pre-"dynamic cast"ed pointers passed in. If this function is being called often then creating this vector and passing it in explicitly each time can give a large speed up.

2592  {
2593  // If the node is already a boundary node, then return straight away,
2594  // we don't need to do anything
2595  if (dynamic_cast<BoundaryNodeBase*>(node_pt) != 0)
2596  {
2597  return;
2598  }
2599 
2600  // Loop over all the elements in the mesh and find all those in which
2601  // the present node is referenced and the corresponding local node number
2602  // in those elements.
2603 
2604  // Storage for elements and local node number
2605  std::list<std::pair<unsigned long, int>>
2606  list_of_elements_and_local_node_numbers;
2607 
2608  // Loop over all elements
2609  unsigned long n_element = this->nelement();
2610  for (unsigned long e = 0; e < n_element; e++)
2611  {
2612  // Buffer the case when we have not yet filled up the element array
2613  // Unfortunately, we should not assume that the array has been filled
2614  // in a linear order, so we can't break out early.
2615  if (Element_pt[e] != 0)
2616  {
2617  // Find the local node number of the passed node
2618  int node_number = finite_element_pt[e]->get_node_number(node_pt);
2619  // If the node is present in the element, add it to our list and
2620  // NULL out the local element entries
2621  if (node_number != -1)
2622  {
2623  list_of_elements_and_local_node_numbers.insert(
2624  list_of_elements_and_local_node_numbers.end(),
2625  std::make_pair(e, node_number));
2626  // Null it out
2627  finite_element_pt[e]->node_pt(node_number) = 0;
2628  }
2629  }
2630  } // End of loop over elements
2631 
2632  // If there are no entries in the list we are in real trouble
2633  if (list_of_elements_and_local_node_numbers.empty())
2634  {
2635  std::ostringstream error_stream;
2636  error_stream << "Node " << node_pt
2637  << " is not contained in any elements in the Mesh."
2638  << std::endl
2639  << "How was it created then?" << std::endl;
2640 
2641  throw OomphLibError(
2642  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2643  }
2644 
2645 
2646  // Create temporary storage for a pointer to the old node.
2647  // This is required because if we have passed a reference to the
2648  // first element that we find, constructing the new node
2649  // will over-write our pointer and we'll get segmentation faults.
2650  Node* old_node_pt = node_pt;
2651 
2652  // We now create the new node by using the first element in the list
2653  std::list<std::pair<unsigned long, int>>::iterator list_it =
2654  list_of_elements_and_local_node_numbers.begin();
2655 
2656  // Create a new boundary node, using the timestepper from the
2657  // original node
2658  Node* new_node_pt =
2659  finite_element_pt[list_it->first]->construct_boundary_node(
2660  list_it->second, node_pt->time_stepper_pt());
2661 
2662  // Now copy all the information accross from the old node
2663 
2664  // Can we cast the node to a solid node
2665  SolidNode* solid_node_pt = dynamic_cast<SolidNode*>(new_node_pt);
2666  // If it's a solid node, do the casting
2667  if (solid_node_pt != 0)
2668  {
2669  solid_node_pt->copy(dynamic_cast<SolidNode*>(old_node_pt));
2670  }
2671  else
2672  {
2673  new_node_pt->copy(old_node_pt);
2674  }
2675 
2676  // Loop over all other elements in the list and set their pointers
2677  // to the new node
2678  for (++list_it; // Increment the iterator
2679  list_it != list_of_elements_and_local_node_numbers.end();
2680  ++list_it)
2681  {
2682  finite_element_pt[list_it->first]->node_pt(list_it->second) = new_node_pt;
2683  }
2684 
2685  // Finally, find the position of the node in the global mesh
2686  Vector<Node*>::iterator it =
2687  std::find(Node_pt.begin(), Node_pt.end(), old_node_pt);
2688 
2689  // If it is in the mesh, update the pointer
2690  if (it != Node_pt.end())
2691  {
2692  *it = new_node_pt;
2693  }
2694 
2695  // Can now delete the old node
2696  delete old_node_pt;
2697 
2698  // Replace the passed pointer by a pointer to the new node
2699  // Note that in most cases, this will be wasted work because the node
2700  // pointer will either the pointer in the mesh's or an element's
2701  // node_pt vector. Still assignment is quicker than an if to check this.
2702  node_pt = new_node_pt;
2703  }
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
Definition: nodes.h:238
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
int get_node_number(Node *const &node_pt) const
Definition: elements.cc:3814
virtual Node * construct_boundary_node(const unsigned &n)
Definition: elements.h:2538
void copy(Node *orig_node_pt)
Copy all nodal data from specified Node object.
Definition: nodes.cc:1916

References oomph::FiniteElement::construct_boundary_node(), oomph::Node::copy(), oomph::SolidNode::copy(), e(), Element_pt, finite_element_pt(), oomph::FiniteElement::get_node_number(), nelement(), oomph::FiniteElement::node_pt(), Node_pt, node_pt(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and oomph::Data::time_stepper_pt().

Referenced by oomph::ChannelWithLeafletMesh< ELEMENT >::ChannelWithLeafletMesh(), convert_to_boundary_node(), ElasticTwoLayerMesh< ELEMENT >::ElasticTwoLayerMesh(), oomph::FullCircleMesh< ELEMENT >::FullCircleMesh(), oomph::QuarterTubeMesh< ELEMENT >::QuarterTubeMesh(), oomph::RectangleWithHoleMesh< ELEMENT >::RectangleWithHoleMesh(), oomph::SimpleRectangularTriMesh< ELEMENT >::SimpleRectangularTriMesh(), and oomph::TubeMesh< ELEMENT >::TubeMesh().

◆ copy_boundary_node_data_from_nodes()

void oomph::Mesh::copy_boundary_node_data_from_nodes ( )
inline

Replace existing boundary node lookup schemes with new schemes created using the boundary data stored in the nodes.

527  {
528  // Clear existing boundary data
529  Boundary_node_pt.clear();
530 
531  // Loop over nodes adding them to the appropriate boundary lookup schemes
532  // in the mesh.
533  const unsigned n_node = nnode();
534  for (unsigned nd = 0; nd < n_node; nd++)
535  {
536  Node* nd_pt = node_pt(nd);
537 
538  if (nd_pt->is_on_boundary())
539  {
540  // Get set of boundaries that the node is on
541  std::set<unsigned>* boundaries_pt;
542  nd_pt->get_boundaries_pt(boundaries_pt);
543 
544  // If needed then add more boundaries to this mesh
545  unsigned max_boundary_n =
546  1 + *std::max_element(boundaries_pt->begin(), boundaries_pt->end());
547  if (max_boundary_n > nboundary())
548  {
549  set_nboundary(max_boundary_n);
550  }
551 
552  // Add node pointer to the appropriate Boundary_node_pt vectors
553  std::set<unsigned>::const_iterator it;
554  for (it = boundaries_pt->begin(); it != boundaries_pt->end(); it++)
555  {
556  Boundary_node_pt[*it].push_back(nd_pt);
557  }
558  }
559  }
560  }
void set_nboundary(const unsigned &nbound)
Set the number of boundaries in the mesh.
Definition: mesh.h:505
unsigned nboundary() const
Return number of boundaries.
Definition: mesh.h:827

References Boundary_node_pt, oomph::Node::get_boundaries_pt(), oomph::Node::is_on_boundary(), nboundary(), nnode(), node_pt(), and set_nboundary().

◆ delete_all_external_storage()

void oomph::Mesh::delete_all_external_storage ( )

Wipe the storage for all externally-based elements.

Wipe the storage for all externally-based elements and delete halos.

9191  {
9192 #ifdef OOMPH_HAS_MPI
9193 
9194  // Only do for distributed meshes
9195  if (is_mesh_distributed())
9196  {
9197  // Some of the external halo/haloed nodes are masters of nodes
9198  // in this mesh. We must set to be non-hanging any nodes whose
9199  // masters we are about to delete, to remove any dependencies.
9200 
9201  // Loop over all the mesh nodes and check their masters
9202  for (unsigned i = 0; i < nnode(); i++)
9203  {
9204  // Get pointer to the node
9205  Node* nod_pt = node_pt(i);
9206 
9207  // Check if the node exists
9208  if (nod_pt != 0)
9209  {
9210  // Check if the node is hanging
9211  if (nod_pt->is_hanging())
9212  {
9213  // Get pointer to the hang info
9214  HangInfo* hang_pt = nod_pt->hanging_pt();
9215 
9216  // Check if any master is in the external halo storage
9217  // External haloed nodes don't get deleted, so we don't need to
9218  //(and shouldn't) un-hang their dependents
9219  bool found_a_master_in_external_halo_storage = false;
9220  for (unsigned m = 0; m < hang_pt->nmaster(); m++)
9221  {
9222  // Iterator for vector of nodes
9223  Vector<Node*>::iterator it;
9224 
9225  // Loop over external halo storage with all processors
9226  bool found_this_master_in_external_halo_storage = false;
9227  for (int d = 0; d < Comm_pt->nproc(); d++)
9228  {
9229  // Find master in map of external halo nodes
9230  it = std::find(External_halo_node_pt[d].begin(),
9231  External_halo_node_pt[d].end(),
9232  hang_pt->master_node_pt(m));
9233 
9234  // Check if it was found
9235  if (it != External_halo_node_pt[d].end())
9236  {
9237  // Mark as found
9238  found_this_master_in_external_halo_storage = true;
9239  // Don't need to search remaining processors
9240  break;
9241  }
9242  }
9243 
9244  // Check if any have been found
9245  if (found_this_master_in_external_halo_storage)
9246  {
9247  // Mark as found
9248  found_a_master_in_external_halo_storage = true;
9249  // Don't need to search remaining masters
9250  break;
9251  }
9252  }
9253 
9254  // If it was found...
9255  if (found_a_master_in_external_halo_storage)
9256  {
9257  // Master is in external halo storage and is about to be deleted,
9258  // so we'd better make this node non-hanging. In case the node
9259  // does not become hanging again, we must get all the required
9260  // information from its masters to make it a 'proper' node again.
9261 
9262  // Reconstruct the nodal values/position from the node's
9263  // hanging node representation
9264  unsigned nt = nod_pt->ntstorage();
9265  unsigned n_value = nod_pt->nvalue();
9266  Vector<double> values(n_value);
9267  unsigned n_dim = nod_pt->ndim();
9268  Vector<double> position(n_dim);
9269  // Loop over all history values
9270  for (unsigned t = 0; t < nt; t++)
9271  {
9272  nod_pt->value(t, values);
9273  for (unsigned i = 0; i < n_value; i++)
9274  {
9275  nod_pt->set_value(t, i, values[i]);
9276  }
9277  nod_pt->position(t, position);
9278  for (unsigned i = 0; i < n_dim; i++)
9279  {
9280  nod_pt->x(t, i) = position[i];
9281  }
9282  }
9283 
9284  // If it's an algebraic node: Update its previous nodal positions
9285  // too
9286  AlgebraicNode* alg_node_pt = dynamic_cast<AlgebraicNode*>(nod_pt);
9287  if (alg_node_pt != 0)
9288  {
9289  bool update_all_time_levels = true;
9290  alg_node_pt->node_update(update_all_time_levels);
9291  }
9292 
9293 
9294  // If it's a Solid node, update Lagrangian coordinates
9295  // from its hanging node representation
9296  SolidNode* solid_node_pt = dynamic_cast<SolidNode*>(nod_pt);
9297  if (solid_node_pt != 0)
9298  {
9299  unsigned n_lagrangian = solid_node_pt->nlagrangian();
9300  for (unsigned i = 0; i < n_lagrangian; i++)
9301  {
9302  solid_node_pt->xi(i) = solid_node_pt->lagrangian_position(i);
9303  }
9304  }
9305 
9306  // No need to worry about geometrically hanging nodes
9307  // on boundaries (as in (p_)adapt_mesh())
9311  // if((mesh_dim > 2) && (nod_pt->is_hanging()))
9312  // {
9313  // //If the node is on a boundary then add a pointer to the node
9314  // //to our lookup scheme
9315  // if(nod_pt->is_on_boundary())
9316  // {
9317  // //Storage for the boundaries on which the Node is located
9318  // std::set<unsigned>* boundaries_pt;
9319  // nod_pt->get_boundaries_pt(boundaries_pt);
9320  // if(boundaries_pt!=0)
9321  // {
9322  // //Loop over the boundaries and add a pointer to the node
9323  // //to the appropriate storage scheme
9324  // for(std::set<unsigned>::iterator
9325  // it=boundaries_pt->begin();
9326  // it!=boundaries_pt->end();++it)
9327  // {
9328  // hanging_nodes_on_boundary_pt[*it].insert(nod_pt);
9329  // }
9330  // }
9331  // }
9332  // }
9333 
9334  // Finally set nonhanging
9335  nod_pt->set_nonhanging();
9336  }
9337  }
9338  }
9339  else
9340  {
9341  // Node doesn't exist!
9342  }
9343  }
9344  }
9345 
9346  // Careful: some of the external halo nodes are also in boundary
9347  // node storage and should be removed from this first
9348  for (std::map<unsigned, Vector<Node*>>::iterator it =
9349  External_halo_node_pt.begin();
9350  it != External_halo_node_pt.end();
9351  it++)
9352  {
9353  // Processor ID
9354  int d = (*it).first;
9355 
9356  // How many external haloes with this process?
9357  unsigned n_ext_halo_nod = nexternal_halo_node(d);
9358  for (unsigned j = 0; j < n_ext_halo_nod; j++)
9359  {
9360  Node* ext_halo_nod_pt = external_halo_node_pt(d, j);
9361  unsigned n_bnd = nboundary();
9362  for (unsigned i_bnd = 0; i_bnd < n_bnd; i_bnd++)
9363  {
9364  // Call this for all boundaries; it will do nothing
9365  // if the node is not on the current boundary
9366  remove_boundary_node(i_bnd, ext_halo_nod_pt);
9367  }
9368  }
9369  }
9370 
9371  // A loop to delete external halo nodes
9372  for (std::map<unsigned, Vector<Node*>>::iterator it =
9373  External_halo_node_pt.begin();
9374  it != External_halo_node_pt.end();
9375  it++)
9376  {
9377  // Processor ID
9378  int d = (*it).first;
9379 
9380  unsigned n_ext_halo_nod = nexternal_halo_node(d);
9381  for (unsigned j = 0; j < n_ext_halo_nod; j++)
9382  {
9383  // Only delete if it's not a node stored in the current mesh
9384  bool is_a_mesh_node = false;
9385  unsigned n_node = nnode();
9386  for (unsigned jj = 0; jj < n_node; jj++)
9387  {
9388  if (Node_pt[jj] == External_halo_node_pt[d][j])
9389  {
9390  is_a_mesh_node = true;
9391  }
9392  }
9393 
9394  // There will also be duplications between multiple processors,
9395  // so make sure that we don't try to delete these twice
9396  if (!is_a_mesh_node)
9397  {
9398  // Loop over all other higher-numbered processors and check
9399  // for duplicated external halo nodes
9400  // (The highest numbered processor should delete all its ext halos)
9401  for (std::map<unsigned, Vector<Node*>>::iterator itt =
9402  External_halo_node_pt.begin();
9403  itt != External_halo_node_pt.end();
9404  itt++)
9405  {
9406  // Processor ID
9407  int dd = (*itt).first;
9408 
9409  if (dd > d)
9410  {
9411  unsigned n_ext_halo = nexternal_halo_node(dd);
9412  for (unsigned jjj = 0; jjj < n_ext_halo; jjj++)
9413  {
9414  if (External_halo_node_pt[dd][jjj] ==
9415  External_halo_node_pt[d][j])
9416  {
9417  is_a_mesh_node = true;
9418  }
9419  }
9420  }
9421  }
9422  }
9423 
9424  // Only now if no duplicates exist can the node be safely deleted
9425  if (!is_a_mesh_node)
9426  {
9427  delete External_halo_node_pt[d][j];
9428  }
9429  }
9430  }
9431 
9432  // Another loop to delete external halo elements (which are distinct)
9433  for (std::map<unsigned, Vector<GeneralisedElement*>>::iterator it =
9434  External_halo_element_pt.begin();
9435  it != External_halo_element_pt.end();
9436  it++)
9437  {
9438  // Processor ID
9439  int d = (*it).first;
9440 
9441  unsigned n_ext_halo_el = nexternal_halo_element(d);
9442  for (unsigned e = 0; e < n_ext_halo_el; e++)
9443  {
9444  delete External_halo_element_pt[d][e];
9445  }
9446  }
9447 
9448  // Now we are okay to clear the external halo node storage
9449  External_halo_node_pt.clear();
9450  External_halo_element_pt.clear();
9451 
9452  // External haloed nodes and elements are actual members
9453  // of the external mesh and should not be deleted
9454  External_haloed_node_pt.clear();
9455  External_haloed_element_pt.clear();
9456 #endif
9457  }
void remove_boundary_node(const unsigned &b, Node *const &node_pt)
Remove a node from the boundary b.
Definition: mesh.cc:221
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
int * m
Definition: level2_cplx_impl.h:294
t
Definition: plotPSD.py:36

References e(), Eigen::placeholders::end, oomph::Node::hanging_pt(), i, oomph::Node::is_hanging(), is_mesh_distributed(), j, oomph::SolidNode::lagrangian_position(), m, oomph::HangInfo::master_node_pt(), nboundary(), oomph::Node::ndim(), oomph::SolidNode::nlagrangian(), oomph::HangInfo::nmaster(), nnode(), Node_pt, node_pt(), oomph::AlgebraicNode::node_update(), oomph::Data::ntstorage(), oomph::Data::nvalue(), oomph::Node::position(), remove_boundary_node(), oomph::Node::set_nonhanging(), oomph::Data::set_value(), plotPSD::t, oomph::Node::value(), oomph::Node::x(), and oomph::SolidNode::xi().

Referenced by oomph::TreeBasedRefineableMeshBase::adapt(), oomph::TreeBasedRefineableMeshBase::adapt_mesh(), oomph::Problem::delete_all_external_storage(), oomph::TreeBasedRefineableMeshBase::p_adapt(), oomph::TreeBasedRefineableMeshBase::p_adapt_mesh(), oomph::Multi_domain_functions::setup_multi_domain_interactions(), and ~Mesh().

◆ describe_dofs()

void oomph::Mesh::describe_dofs ( std::ostream &  out,
const std::string &  current_string 
) const
protected

Function to describe the dofs of the Mesh. The ostream specifies the output stream to which the description is written; the string stores the currently assembled output that is ultimately written to the output stream by Data::describe_dofs(...); it is typically built up incrementally as we descend through the call hierarchy of this function when called from Problem::describe_dofs(...)

713  {
714  // Loop over the nodes and call their classification functions
715  unsigned long nnod = Node_pt.size();
716  for (unsigned long i = 0; i < nnod; i++)
717  {
718  std::stringstream conversion;
719  conversion << " of Node " << i << current_string;
720  std::string in(conversion.str());
721  Node_pt[i]->describe_dofs(out, in);
722  }
723 
724  // Loop over the elements and classify.
725  unsigned long nel = Element_pt.size();
726  for (unsigned long i = 0; i < nel; i++)
727  {
728  std::stringstream conversion;
729  conversion << " in Element " << i << " [" << typeid(*Element_pt[i]).name()
730  << "] " << current_string;
731  std::string in(conversion.str());
732  Element_pt[i]->describe_dofs(out, in);
733  }
734  }
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
string name
Definition: plotDoE.py:33
std::ofstream out("Result.txt")

References Element_pt, i, plotDoE::name, Node_pt, out(), and oomph::Global_string_for_annotation::string().

Referenced by oomph::Problem::describe_dofs().

◆ describe_local_dofs()

void oomph::Mesh::describe_local_dofs ( std::ostream &  out,
const std::string &  current_string 
) const
protected

Function to describe the local dofs of the elements. The ostream specifies the output stream to which the description is written; the string stores the currently assembled output that is ultimately written to the output stream by Data::describe_dofs(...); it is typically built up incrementally as we descend through the call hierarchy of this function when called from Problem::describe_dofs(...)

748  {
749  // Now loop over the elements and describe local dofs
750  unsigned long nel = Element_pt.size();
751  for (unsigned long i = 0; i < nel; i++)
752  {
753  std::stringstream conversion;
754  conversion << " in Element" << i << " [" << typeid(*Element_pt[i]).name()
755  << "] " << current_string;
756  std::string in(conversion.str());
757  Element_pt[i]->describe_local_dofs(out, in);
758  }
759  }

References Element_pt, i, plotDoE::name, out(), and oomph::Global_string_for_annotation::string().

Referenced by oomph::Problem::describe_dofs().

◆ doc_boundary_coordinates()

template<class BULK_ELEMENT >
void oomph::Mesh::doc_boundary_coordinates ( const unsigned b,
std::ofstream &  the_file 
)
inline

Output boundary coordinates on boundary b – template argument specifies the bulk element type (needed to create FaceElement of appropriate type on mesh boundary).

304  {
305  if (nelement() == 0) return;
307  {
308  oomph_info << "No boundary coordinates were set up for boundary " << b
309  << std::endl;
310  return;
311  }
312 
313  // Get spatial dimension
314  unsigned dim = finite_element_pt(0)->node_pt(0)->ndim();
315 
316  // Loop over all elements on boundaries
317  unsigned nel = this->nboundary_element(b);
318 
319  // Loop over the bulk elements adjacent to boundary b
320  for (unsigned e = 0; e < nel; e++)
321  {
322  // Get pointer to the bulk element that is adjacent to boundary b
323  FiniteElement* bulk_elem_pt = this->boundary_element_pt(b, e);
324 
325  // Find the index of the face of element e along boundary b
326  int face_index = this->face_index_at_boundary(b, e);
327 
328  // Create new face element
329  DummyFaceElement<BULK_ELEMENT>* el_pt =
330  new DummyFaceElement<BULK_ELEMENT>(bulk_elem_pt, face_index);
331 
332  // Specify boundary id in bulk mesh (needed to extract
333  // boundary coordinate)
334  el_pt->set_boundary_number_in_bulk_mesh(b);
335 
336  // Doc boundary coordinate
337  Vector<double> s(dim - 1);
338  Vector<double> zeta(dim - 1);
339  Vector<double> x(dim);
340  unsigned n_plot = 5;
341  the_file << el_pt->tecplot_zone_string(n_plot);
342 
343  // Loop over plot points
344  unsigned num_plot_points = el_pt->nplot_points(n_plot);
345  for (unsigned iplot = 0; iplot < num_plot_points; iplot++)
346  {
347  // Get local coordinates of plot point
348  el_pt->get_s_plot(iplot, n_plot, s);
349  el_pt->interpolated_zeta(s, zeta);
350  el_pt->interpolated_x(s, x);
351  for (unsigned i = 0; i < dim; i++)
352  {
353  the_file << x[i] << " ";
354  }
355  for (unsigned i = 0; i < (dim - 1); i++)
356  {
357  the_file << zeta[i] << " ";
358  }
359 
360  the_file << std::endl;
361  }
362  el_pt->write_tecplot_zone_footer(the_file, n_plot);
363 
364  // Cleanup
365  delete el_pt;
366  }
367  }
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition: nodes.h:1054
EIGEN_STRONG_INLINE const Eigen::CwiseBinaryOp< Eigen::internal::scalar_zeta_op< typename DerivedX::Scalar >, const DerivedX, const DerivedQ > zeta(const Eigen::ArrayBase< DerivedX > &x, const Eigen::ArrayBase< DerivedQ > &q)
Definition: SpecialFunctionsArrayAPI.h:152
list x
Definition: plotDoE.py:28

References b, Boundary_coordinate_exists, boundary_element_pt(), e(), face_index_at_boundary(), finite_element_pt(), oomph::FiniteElement::get_s_plot(), i, oomph::FaceElement::interpolated_x(), oomph::FiniteElement::interpolated_zeta(), nboundary_element(), oomph::Node::ndim(), nelement(), oomph::FiniteElement::node_pt(), oomph::FiniteElement::nplot_points(), oomph::oomph_info, s, oomph::FaceElement::set_boundary_number_in_bulk_mesh(), oomph::FiniteElement::tecplot_zone_string(), oomph::FiniteElement::write_tecplot_zone_footer(), plotDoE::x, and Eigen::zeta().

◆ does_pointer_correspond_to_mesh_data()

bool oomph::Mesh::does_pointer_correspond_to_mesh_data ( double *const &  parameter_pt)

Does the double pointer correspond to any mesh data.

Return true if the pointer corresponds to any data stored in the mesh and false if not

2472  {
2473  // Loop over the nodes
2474  const unsigned long n_node = this->nnode();
2475  for (unsigned long n = 0; n < n_node; n++)
2476  {
2477  // Check the values and positional data associated with each node
2478  if ((this->Node_pt[n]->does_pointer_correspond_to_value(parameter_pt)) ||
2479  (this->Node_pt[n]->does_pointer_correspond_to_position_data(
2480  parameter_pt)))
2481  {
2482  return true;
2483  }
2484  }
2485 
2486  // Loop over the elements
2487  const unsigned long n_element = this->nelement();
2488  for (unsigned long e = 0; e < n_element; e++)
2489  {
2490  // Cache pointer to the elemnet
2491  GeneralisedElement* const elem_pt = this->element_pt(e);
2492 
2493  // Find the number of internal dofs
2494  const unsigned n_internal = elem_pt->ninternal_data();
2495 
2496  // Loop over internal dofs and test the data
2497  for (unsigned j = 0; j < n_internal; j++)
2498  {
2499  if (elem_pt->internal_data_pt(j)->does_pointer_correspond_to_value(
2500  parameter_pt))
2501  {
2502  return true;
2503  }
2504  }
2505  }
2506 
2507  // If we get here we haven't found the data, so return false
2508  return false;
2509  }

References oomph::Data::does_pointer_correspond_to_value(), e(), element_pt(), oomph::GeneralisedElement::internal_data_pt(), j, n, nelement(), oomph::GeneralisedElement::ninternal_data(), nnode(), and Node_pt.

Referenced by oomph::Problem::does_pointer_correspond_to_problem_data().

◆ dump() [1/2]

void oomph::Mesh::dump ( const std::string &  dump_file_name,
const bool use_old_ordering = true 
) const
inline

Dump the data in the mesh into a file for restart.

917  {
918  std::ofstream dump_stream(dump_file_name.c_str());
919 #ifdef PARANOID
920  if (!dump_stream.is_open())
921  {
922  std::string err = "Couldn't open file " + dump_file_name;
923  throw OomphLibError(
925  }
926 #endif
927  dump(dump_stream, use_old_ordering);
928  }
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.
Definition: mesh.cc:1088

References dump(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and oomph::Global_string_for_annotation::string().

◆ dump() [2/2]

void oomph::Mesh::dump ( std::ofstream &  dump_file,
const bool use_old_ordering = true 
) const
virtual

Dump the data in the mesh into a file for restart.

Dump function for the mesh class. Loop over all nodes and elements and dump them

Reimplemented in oomph::PerturbedSpineMesh.

1089  {
1090  // Get a reordering of the nodes so that the dump file is in a standard
1091  // ordering regardless of the sequence of mesh refinements etc.
1092  Vector<Node*> reordering;
1093  this->get_node_reordering(reordering, use_old_ordering);
1094 
1095  // Find number of nodes
1096  unsigned long Node_pt_range = this->nnode();
1097 
1098  // Doc # of nodes
1099  dump_file << Node_pt_range << " # number of nodes " << std::endl;
1100 
1101  // Loop over all the nodes and dump their data
1102  for (unsigned nd = 0; nd < Node_pt_range; nd++)
1103  {
1104  reordering[nd]->dump(dump_file);
1105  }
1106 
1107  // Loop over elements and deal with internal data
1108  unsigned n_element = this->nelement();
1109  for (unsigned e = 0; e < n_element; e++)
1110  {
1111  GeneralisedElement* el_pt = this->element_pt(e);
1112  unsigned n_internal = el_pt->ninternal_data();
1113  if (n_internal > 0)
1114  {
1115  dump_file << n_internal
1116  << " # number of internal Data items in element " << e
1117  << std::endl;
1118  for (unsigned i = 0; i < n_internal; i++)
1119  {
1120  el_pt->internal_data_pt(i)->dump(dump_file);
1121  }
1122  }
1123  }
1124  }
virtual void get_node_reordering(Vector< Node * > &reordering, const bool &use_old_ordering=true) const
Definition: mesh.cc:532

References oomph::Data::dump(), e(), element_pt(), get_node_reordering(), i, oomph::GeneralisedElement::internal_data_pt(), nelement(), oomph::GeneralisedElement::ninternal_data(), and nnode().

Referenced by dump(), oomph::Problem::dump(), oomph::SpineMesh::dump(), and oomph::PerturbedSpineMesh::dump().

◆ element_pt() [1/4]

Vector<GeneralisedElement*>& oomph::Mesh::element_pt ( )
inline

Return reference to the Vector of elements.

467  {
468  return Element_pt;
469  }

References Element_pt.

◆ element_pt() [2/4]

const Vector<GeneralisedElement*>& oomph::Mesh::element_pt ( ) const
inline

Return reference to the Vector of elements.

461  {
462  return Element_pt;
463  }

References Element_pt.

Referenced by oomph::TreeBasedRefineableMeshBase::adapt(), add_element_pt(), oomph::PeriodicOrbitTemporalMesh< ELEMENT >::assemble_residuals(), oomph::PeriodicOrbitTemporalMesh< ELEMENT >::assemble_residuals_and_jacobian(), assign_initial_values_impulsive(), calculate_predictions(), does_pointer_correspond_to_mesh_data(), dump(), oomph::ElasticRefineableQuarterPipeMesh< ELEMENT >::ElasticRefineableQuarterPipeMesh(), get_node_reordering(), oomph::TreeBasedRefineableMeshBase::get_refinement_levels(), oomph::DGMesh::limit_slopes(), oomph::MacroElementNodeUpdateChannelWithLeafletMesh< ELEMENT >::MacroElementNodeUpdateChannelWithLeafletMesh(), oomph::MacroElementNodeUpdateCollapsibleChannelMesh< ELEMENT >::MacroElementNodeUpdateCollapsibleChannelMesh(), oomph::MacroElementNodeUpdateRefineableFishMesh< ELEMENT >::MacroElementNodeUpdateRefineableFishMesh(), ndof_types(), node_update(), oomph::PeriodicOrbitTemporalMesh< ELEMENT >::orbit_output(), output_fct_paraview(), output_paraview(), oomph::TreeBasedRefineableMeshBase::p_adapt(), oomph::TreeBasedRefineableMeshBase::p_adapt_mesh(), oomph::TreeBasedRefineableMeshBase::p_refine_selected_elements(), oomph::TreeBasedRefineableMeshBase::p_refine_uniformly(), oomph::TreeBasedRefineableMeshBase::p_unrefine_uniformly(), oomph::PMLQuadMeshBase< ELEMENT >::pml_locate_zeta(), oomph::PMLCornerQuadMesh< ELEMENT >::PMLCornerQuadMesh(), oomph::PMLQuadMesh< ELEMENT >::PMLQuadMesh(), oomph::QuarterCircleSectorMesh< ELEMENT >::QuarterCircleSectorMesh(), oomph::QuarterPipeMesh< ELEMENT >::QuarterPipeMesh(), read(), oomph::TreeBasedRefineableMeshBase::refine_base_mesh(), oomph::TreeBasedRefineableMeshBase::refine_selected_elements(), oomph::TreeBasedRefineableMeshBase::refine_uniformly(), oomph::RefineableEighthSphereMesh< ELEMENT >::RefineableEighthSphereMesh(), oomph::RefineableFullCircleMesh< ELEMENT >::RefineableFullCircleMesh(), oomph::RefineableQuarterTubeMesh< ELEMENT >::RefineableQuarterTubeMesh(), oomph::RefineableRectangleWithHoleAndAnnularRegionMesh< ELEMENT >::RefineableRectangleWithHoleAndAnnularRegionMesh(), oomph::RefineableRectangleWithHoleMesh< ELEMENT >::RefineableRectangleWithHoleMesh(), oomph::RefineableTubeMesh< ELEMENT >::RefineableTubeMesh(), oomph::RefineableTwoDAnnularMesh< ELEMENT >::RefineableTwoDAnnularMesh(), set_consistent_pinned_values_for_continuation(), set_elemental_internal_time_stepper(), oomph::AlgebraicFishMesh< ELEMENT >::setup_algebraic_node_update(), oomph::AlgebraicRefineableQuarterCircleSectorMesh< ELEMENT >::setup_algebraic_node_update(), oomph::AlgebraicRefineableQuarterTubeMesh< ELEMENT >::setup_algebraic_node_update(), oomph::RefineableLineMesh< ELEMENT >::setup_binary_tree_forest(), oomph::DGMesh::setup_face_neighbour_info(), oomph::MacroElementNodeUpdateRefineableQuarterCircleSectorMesh< ELEMENT >::setup_macro_element_node_update(), oomph::MacroElementNodeUpdateRefineableQuarterTubeMesh< ELEMENT >::setup_macro_element_node_update(), oomph::RefineableBrickMesh< ELEMENT >::setup_octree_forest(), oomph::RefineableQuadMesh< ELEMENT >::setup_quadtree_forest(), and shift_time_values().

◆ element_pt() [3/4]

GeneralisedElement*& oomph::Mesh::element_pt ( const unsigned long &  e)
inline

Return pointer to element e.

449  {
450  return Element_pt[e];
451  }

References e(), and Element_pt.

Referenced by oomph::IMRByBDF::actions_after_timestep(), oomph::RefineableTetgenMesh< ELEMENT >::adapt(), oomph::RefineableGmshTetMesh< ELEMENT >::adapt(), oomph::PeriodicOrbitAssemblyHandler< NNODE_1D >::adapt_temporal_mesh(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_mesh(), CombCanSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_outlet_bulk_elements(), oomph::NavierStokesSchurComplementPreconditioner::assemble_inv_press_and_veloc_mass_matrix_diagonal(), oomph::PressureBasedSolidLSCPreconditioner::assemble_mass_matrix_diagonal(), oomph::Problem::assign_eqn_numbers(), oomph::Multi_domain_functions::aux_setup_multi_domain_interaction(), AxisymFreeSurfaceNozzleAdvDiffRobinProblem< ELEMENT >::AxisymFreeSurfaceNozzleAdvDiffRobinProblem(), oomph::SolidICProblem::backup_original_state(), oomph::BackupMeshForProjection< GEOMETRIC_ELEMENT >::BackupMeshForProjection(), oomph::MeshAsGeomObject::build_it(), CombCanSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), CapProblem< ELEMENT >::CapProblem(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::complete_build(), ContactProblem< ELEMENT >::complete_problem_setup(), AdvectionProblem::compute_error(), TwoDDGProblem< ELEMENT >::compute_error(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::compute_integrated_concentrations(), InterfaceProblem< ELEMENT, TIMESTEPPER >::compute_total_mass(), AirwayReopeningProblem< ELEMENT >::connect_walls(), ConvectionProblem< NST_ELEMENT, AD_ELEMENT >::ConvectionProblem(), oomph::Problem::copy(), oomph::TwoDimensionalPMLHelper::create_bottom_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_bottom_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_bottom_right_pml_mesh(), RefineableRotatingCylinderProblem< ELEMENT >::create_free_surface_elements(), oomph::TwoDimensionalPMLHelper::create_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_right_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_right_pml_mesh(), SheetGlueProblem< ELEMENT >::create_traction_elements(), ContactProblem< ELEMENT >::delete_contact_elements(), ContactProblem< ELEMENT >::delete_displ_imposition_elements(), FourierDecomposedHelmholtzProblem< ELEMENT >::delete_face_elements(), HelmholtzPointSourceProblem< ELEMENT >::delete_face_elements(), ScatteringProblem< ELEMENT >::delete_face_elements(), CoatedDiskProblem< ELASTICITY_ELEMENT, HELMHOLTZ_ELEMENT >::delete_face_elements(), CoatedSphereProblem< ELASTICITY_ELEMENT, HELMHOLTZ_ELEMENT >::delete_face_elements(), PMLFourierDecomposedHelmholtzProblem< ELEMENT >::delete_face_elements(), TwoMeshFluxAdvectionDiffusionProblem< ELEMENT >::delete_flux_elements(), RefineableUnsteadyHeatProblem< ELEMENT >::delete_flux_elements(), RefineableTwoMeshFluxPoissonProblem< ELEMENT >::delete_flux_elements(), AxisymFreeSurfaceNozzleAdvDiffRobinProblem< ELEMENT >::delete_flux_elements(), FluxPoissonMGProblem< ELEMENT, MESH >::delete_flux_elements(), TwoMeshFluxSteadyAxisymAdvectionDiffusionProblem< ELEMENT >::delete_flux_elements(), RefineableRotatingCylinderProblem< ELEMENT >::delete_free_surface_elements(), CollapsibleChannelProblem< ELEMENT >::delete_traction_elements(), FSICollapsibleChannelProblem< ELEMENT >::delete_traction_elements(), RefineableRotatingCylinderProblem< ELEMENT >::delete_volume_constraint_elements(), oomph::Problem::disable_mass_matrix_reuse(), oomph::SolidHelpers::doc_2D_principal_stress(), oomph::Z2ErrorEstimator::doc_flux(), oomph::FSI_functions::doc_fsi(), OscRingNStProblem< ELEMENT >::doc_solution(), OscRingNStProblem< ELEMENT >::doc_solution_historic(), ProblemParameters::edge_sign_setup(), TestProblem::edge_sign_setup(), Global_Physical_Variables::edge_sign_setup(), ElasticInterfaceProblem< ELEMENT, TIMESTEPPER >::ElasticInterfaceProblem(), ElasticRefineableQuarterCircleSectorMesh< ELEMENT >::ElasticRefineableQuarterCircleSectorMesh(), PseudoElasticCollapsibleChannelProblem< FLUID_ELEMENT, SOLID_ELEMENT >::empty_mesh(), oomph::Problem::enable_mass_matrix_reuse(), oomph::NetFluxControlElement< ELEMENT >::fill_in_contribution_to_residuals(), oomph::NetFluxControlElement< ELEMENT >::fill_in_generic_residual_contribution_flux_control(), FluxPoissonProblem< ELEMENT >::FluxPoissonProblem(), oomph::FoldHandler::FoldHandler(), FSIChannelWithLeafletProblem< ELEMENT >::FSIChannelWithLeafletProblem(), FSIRingProblem::FSIRingProblem(), oomph::Multi_domain_functions::get_dim_helper(), oomph::Problem::get_dofs(), oomph::Z2ErrorEstimator::get_element_errors(), oomph::ImmersedRigidBodyElement::get_force_and_torque(), oomph::Problem::get_hessian_vector_products(), oomph::Problem::get_inverse_mass_matrix_times_residuals(), oomph::Problem::get_jacobian(), oomph::NavierStokesSchurComplementPreconditioner::get_pressure_advection_diffusion_matrix(), oomph::Problem::get_residuals(), SolidProblem< ELEMENT_TYPE >::getMassMomentumEnergy(), oomph::ODEProblem::global_temporal_error_norm(), oomph::HopfHandler::HopfHandler(), oomph::ImposeFluxForWomersleyElement< DIM >::ImposeFluxForWomersleyElement(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::interface_min_max(), InterfaceProblem< ELEMENT, TIMESTEPPER >::InterfaceProblem(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::l2_norm_of_height(), oomph::HelmholtzMGPreconditioner< DIM >::maximum_edge_width(), MeltSpinningProblem< ELEMENT >::MeltSpinningProblem(), oomph::ODEProblem::my_set_initial_condition(), oomph::NetFluxControlElement< ELEMENT >::NetFluxControlElement(), oomph::ImmersedRigidBodyElement::node_update_adjacent_fluid_elements(), OneDPoissonProblem< ELEMENT >::OneDPoissonProblem(), oomph::NonLinearElasticitySmoothMesh< ELEMENT >::operator()(), oomph::PeriodicOrbitAssemblyHandler< NNODE_1D >::orbit_output(), OrrSommerfeldProblem< ELEMENT >::OrrSommerfeldProblem(), oomph::METIS::partition_mesh(), PerturbedStateProblem< BASE_ELEMENT, PERTURBED_ELEMENT >::PerturbedStateProblem(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::pin_all(), oomph::NavierStokesSchurComplementPreconditioner::pin_all_non_pressure_dofs(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::pin_dofs_of_field(), oomph::PitchForkHandler::PitchForkHandler(), oomph::WomersleyImpedanceTubeBase< ELEMENT, DIM >::precompute_aux_integrals(), print_elemental_jacobian(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::project(), PseudoSolidCapProblem< ELEMENT >::PseudoSolidCapProblem(), QuarterCircleDrivenCavityProblem< ELEMENT >::QuarterCircleDrivenCavityProblem(), QuarterCircleDrivenCavityProblem2< ELEMENT >::QuarterCircleDrivenCavityProblem2(), oomph::Problem::read(), oomph::VorticitySmoother< ELEMENT >::recover_vorticity(), RefineableUnsteadyHeatProblem< ELEMENT >::RefineableUnsteadyHeatProblem(), oomph::HSL_MA42::reorder_elements(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::reposition_spines(), oomph::SolidICProblem::reset_original_state(), oomph::NavierStokesSchurComplementPreconditioner::reset_pin_status(), oomph::AugmentedBlockFoldLinearSolver::resolve(), oomph::AugmentedBlockPitchForkLinearSolver::resolve(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::restore_positions(), HeatedCircularPenetratorElement::resulting_force(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::set_coordinate_for_projection(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::set_current_field_for_projection(), oomph::Problem::set_dofs(), oomph::ImmersedRigidBodyElement::set_drag_mesh(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::set_lagrangian_coordinate_for_projection(), oomph::SolidICProblem::set_newmark_initial_condition_consistently(), oomph::Problem::set_pinned_values_to_zero(), oomph::BiharmonicProblem< DIM >::set_source_function(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::set_time_level_for_projection(), oomph::Problem::setup_element_count_per_dof(), oomph::VorticitySmoother< ELEMENT >::setup_patches(), oomph::Z2ErrorEstimator::setup_patches(), oomph::SolidICProblem::setup_problem(), oomph::RefineableTetgenMesh< ELEMENT >::snap_nodes_onto_boundary(), oomph::ODEProblem::solution(), oomph::AugmentedBlockFoldLinearSolver::solve(), oomph::AugmentedBlockPitchForkLinearSolver::solve(), oomph::BlockHopfLinearSolver::solve(), oomph::HSL_MA42::solve(), oomph::HSL_MA42::solve_for_one_dof(), oomph::BlockHopfLinearSolver::solve_for_two_rhs(), oomph::Problem::sparse_assemble_row_or_column_compressed_with_lists(), oomph::Problem::sparse_assemble_row_or_column_compressed_with_maps(), oomph::Problem::sparse_assemble_row_or_column_compressed_with_two_arrays(), oomph::Problem::sparse_assemble_row_or_column_compressed_with_two_vectors(), oomph::Problem::sparse_assemble_row_or_column_compressed_with_vectors_of_pairs(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::store_positions(), oomph::StreamfunctionProblem::StreamfunctionProblem(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem(), ContactProblem< ELEMENT >::switch_to_force_control(), oomph::ThinLayerBrickOnTetMesh< ELEMENT >::ThinLayerBrickOnTetMesh(), oomph::ImposeFluxForWomersleyElement< DIM >::total_volume_flux(), oomph::NavierStokesImpedanceTractionElement< BULK_NAVIER_STOKES_ELEMENT, WOMERSLEY_ELEMENT, DIM >::total_volume_flux_into_downstream_tube(), oomph::WomersleyImpedanceTubeBase< ELEMENT, DIM >::total_volume_flux_into_impedance_tube(), TurekProblem< FLUID_ELEMENT, SOLID_ELEMENT >::TurekProblem(), TwoDDGProblem< ELEMENT >::TwoDDGProblem(), TwoMeshFluxAdvectionDiffusionProblem< ELEMENT >::TwoMeshFluxAdvectionDiffusionProblem(), TwoMeshFluxPoissonProblem< ELEMENT >::TwoMeshFluxPoissonProblem(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::unpin_all(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::unpin_dofs_of_field(), oomph::RefineableTetgenMesh< ELEMENT >::update_faceted_surface_using_face_mesh(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::validate(), oomph::WomersleyImpedanceTubeBase< ELEMENT, DIM >::WomersleyImpedanceTubeBase(), and oomph::WomersleyProblem< ELEMENT, DIM >::WomersleyProblem().

◆ element_pt() [4/4]

GeneralisedElement* oomph::Mesh::element_pt ( const unsigned long &  e) const
inline

Return pointer to element e (const version)

455  {
456  return Element_pt[e];
457  }

References e(), and Element_pt.

◆ elemental_dimension()

unsigned oomph::Mesh::elemental_dimension ( ) const

Return number of elemental dimension in mesh.

Get the number of elemental dimension in the mesh from the first element of the mesh. If MPI is on then also do some consistency checks between processors. Careful: Involves MPI Broadcasts and must therefore be called on all processors!

8918  {
8919  // Remains -1 if we don't have any elements on this processor.
8920  int int_dim = -1;
8921  if (nelement() > 0)
8922  {
8923  int_dim = finite_element_pt(0)->dim();
8924 #ifdef PARANOID
8925  // Check that every element in this mesh has the same number of
8926  // types of elemental dimension.
8927  for (unsigned i = 1; i < nelement(); i++)
8928  {
8929  if (int_dim != int(finite_element_pt(i)->dim()))
8930  {
8931  std::ostringstream error_message;
8932  error_message
8933  << "Every element in the mesh must have the same number of "
8934  << "elemental dimension for elemental_dimension() to work.\n"
8935  << "Element 0 has elemental dimension " << int_dim << "\n"
8936  << "Element " << i << " has elemental dimension "
8937  << finite_element_pt(i)->dim() << ".";
8938  throw OomphLibError(error_message.str(),
8941  }
8942  }
8943 #endif
8944  }
8945 
8946 #ifdef OOMPH_HAS_MPI
8947 
8948  // If mesh is distributed
8949  if (Comm_pt != 0)
8950  {
8951  // if more than one processor then
8952  // + ensure dimension number is consistent on each processor (PARANOID)
8953  // + ensure processors with no elements in this mesh have the
8954  // correct dimension number.
8955  if (Comm_pt->nproc() > 1)
8956  {
8957  unsigned nproc = Comm_pt->nproc();
8958  unsigned my_rank = Comm_pt->my_rank();
8959 
8960  // Collect on root the dimension number determined independently
8961  // on all processors (-1 indicates that the processor didn't have
8962  // any elements and therefore doesn't know!)
8963  int* dim_recv = 0;
8964  if (my_rank == 0)
8965  {
8966  dim_recv = new int[nproc];
8967  }
8968 
8969  MPI_Gather(
8970  &int_dim, 1, MPI_INT, dim_recv, 1, MPI_INT, 0, Comm_pt->mpi_comm());
8971 
8972  // Root: Update own dimension, check consistency amongst
8973  // all processors (in paranoid mode) and send out the actual
8974  // dimension number to those processors who couldn't figure this
8975  // out themselves
8976  if (my_rank == 0)
8977  {
8978  // Check number of types of all non-root processors
8979  for (unsigned p = 1; p < nproc; p++)
8980  {
8981  if (dim_recv[p] != -1)
8982  {
8983  // Processor p was able to figure out the elemental
8984  // dimension, so I root can update
8985  // its own (if required)
8986  if (int_dim == -1)
8987  {
8988  int_dim = dim_recv[p];
8989  }
8990 #ifdef PARANOID
8991  // Check consistency
8992  else if (int_dim != dim_recv[p])
8993  {
8994  std::ostringstream error_message;
8995  error_message
8996  << "The elements in this mesh must have the same elemental "
8997  << "dimension number on each processor";
8998  for (unsigned p = 0; p < nproc; p++)
8999  {
9000  if (dim_recv[p] != -1)
9001  {
9002  error_message << "Processor " << p << " : " << dim_recv[p]
9003  << "\n";
9004  }
9005  else
9006  {
9007  error_message << "Processor " << p << " : (no elements)\n";
9008  }
9009  }
9010  throw OomphLibError(error_message.str(),
9013  }
9014 #endif
9015  }
9016  }
9017 
9018  // Now send the elemental dimension to non-root processors that
9019  // don't have it
9020  for (unsigned p = 1; p < nproc; p++)
9021  {
9022  if (dim_recv[p] == -1)
9023  {
9024  MPI_Send(&int_dim, 1, MPI_INT, p, 0, Comm_pt->mpi_comm());
9025  }
9026  }
9027  // clean up
9028  delete[] dim_recv;
9029  }
9030  // "else if": "else" for non-root; "if" for checking if current
9031  // (non-root) processor does not know elemental dimension and is
9032  // therefore about to receive it from root.
9033  else if (int_dim == -1)
9034  {
9035  MPI_Recv(
9036  &int_dim, 1, MPI_INT, 0, 0, Comm_pt->mpi_comm(), MPI_STATUS_IGNORE);
9037  }
9038  }
9039  }
9040 #endif
9041 
9042  // If int_dim if still -1 then no elements were found for this mesh, so it
9043  // has no elemental dimension.
9044  if (int_dim == -1) int_dim = 0;
9045 
9046  return unsigned(int_dim);
9047  }
float * p
Definition: Tutorial_Map_using.cpp:9
unsigned dim() const
Definition: elements.h:2611

References oomph::FiniteElement::dim(), finite_element_pt(), i, nelement(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and p.

Referenced by oomph::LagrangeEnforcedFlowPreconditioner::set_meshes().

◆ face_index_at_boundary()

int oomph::Mesh::face_index_at_boundary ( const unsigned b,
const unsigned e 
) const
inline

For the e-th finite element on boundary b, return int to indicate the face_index of the face adjacent to the boundary. This is consistent with input required during the generation of FaceElements.

897  {
898 #ifdef PARANOID
900  {
901  throw OomphLibError("Lookup scheme for elements next to boundary "
902  "hasn't been set up yet!\n",
905  }
906 #endif
907  return Face_index_at_boundary[b][e];
908  }
Vector< Vector< int > > Face_index_at_boundary
Definition: mesh.h:95

References b, e(), Face_index_at_boundary, Lookup_for_elements_next_boundary_is_setup, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

Referenced by oomph::RefineableTetgenMesh< ELEMENT >::adapt(), oomph::RefineableGmshTetMesh< ELEMENT >::adapt(), build_face_mesh(), CapProblem< ELEMENT >::CapProblem(), ContactProblem< ELEMENT >::create_contact_heat_elements_on_boulder(), ScatteringProblem< ELEMENT >::create_flux_elements(), PMLProblem< ELEMENT >::create_flux_elements(), TwoMeshFluxAdvectionDiffusionProblem< ELEMENT >::create_flux_elements(), LinearWaveProblem< ELEMENT, TIMESTEPPER >::create_flux_elements(), RefineableUnsteadyHeatProblem< ELEMENT >::create_flux_elements(), RefineableTwoMeshFluxPoissonProblem< ELEMENT >::create_flux_elements(), AxisymFreeSurfaceNozzleAdvDiffRobinProblem< ELEMENT >::create_flux_elements(), TwoMeshFluxPoissonProblem< ELEMENT >::create_flux_elements(), TwoMeshFluxSteadyAxisymAdvectionDiffusionProblem< ELEMENT >::create_flux_elements(), RefineableRotatingCylinderProblem< ELEMENT >::create_free_surface_elements(), ContactProblem< ELEMENT >::create_imposed_heat_flux_elements_on_boulder(), FSICollapsibleChannelProblem< ELEMENT >::create_lagrange_multiplier_elements(), CollapsibleChannelProblem< ELEMENT >::create_lagrange_multiplier_elements(), HelmholtzPointSourceProblem< ELEMENT >::create_outer_bc_elements(), ScatteringProblem< ELEMENT >::create_outer_bc_elements(), TiltedCavityProblem< ELEMENT >::create_parall_outflow_lagrange_elements(), PMLProblem< ELEMENT >::create_power_elements(), CollapsibleChannelProblem< ELEMENT >::create_traction_elements(), RayleighTractionProblem< ELEMENT, TIMESTEPPER >::create_traction_elements(), FSICollapsibleChannelProblem< ELEMENT >::create_traction_elements(), SheetGlueProblem< ELEMENT >::create_traction_elements(), RefineableRotatingCylinderProblem< ELEMENT >::create_volume_constraint_elements(), doc_boundary_coordinates(), oomph::ExtrudedCubeMeshFromQuadMesh< ELEMENT >::get_element_boundary_information(), oomph::NavierStokesSchurComplementPreconditioner::get_pressure_advection_diffusion_matrix(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::make_free_surface_elements(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::make_traction_elements(), oomph::NonLinearElasticitySmoothMesh< ELEMENT >::operator()(), QFaceTestProblem< ELEMENT >::QFaceTestProblem(), run_navier_stokes_outflow(), oomph::TetMeshBase::setup_boundary_coordinates(), oomph::UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates(), oomph::TetMeshBase::split_elements_in_corners(), TFaceTestProblem< ELEMENT >::TFaceTestProblem(), oomph::ThinLayerBrickOnTetMesh< ELEMENT >::ThinLayerBrickOnTetMesh(), TriangleFaceTestProblem< ELEMENT >::TriangleFaceTestProblem(), and oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::validate().

◆ finite_element_pt()

FiniteElement* oomph::Mesh::finite_element_pt ( const unsigned e) const
inline

Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).

474  {
475 #ifdef PARANOID
476  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
477  if (el_pt == 0)
478  {
479  // Error
480  throw OomphLibError("Failed cast to FiniteElement* ",
483  // Dummy return to keep intel compiler happy
484  return el_pt;
485  }
486  return el_pt;
487 #else
488  return dynamic_cast<FiniteElement*>(Element_pt[e]);
489 #endif
490  }

References e(), Element_pt, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

Referenced by oomph::RefineableTetgenMesh< ELEMENT >::adapt(), oomph::TreeBasedRefineableMeshBase::adapt_mesh(), oomph::TetMeshBase::assess_mesh_quality(), oomph::Multi_domain_functions::aux_setup_multi_domain_interaction(), oomph::BackupMeshForProjection< GEOMETRIC_ELEMENT >::BackupMeshForProjection(), oomph::GmshTetMesh< ELEMENT >::build_from_scaffold(), oomph::QuadFromTriangleMesh< ELEMENT >::build_from_scaffold(), oomph::MeshAsGeomObject::build_it(), oomph::ExtrudedCubeMeshFromQuadMesh< ELEMENT >::build_mesh(), oomph::ChannelWithLeafletMesh< ELEMENT >::ChannelWithLeafletMesh(), check_inverted_elements(), oomph::TriangleScaffoldMesh::check_mesh_integrity(), oomph::CollapsibleChannelMesh< ELEMENT >::CollapsibleChannelMesh(), oomph::RefineableTetMeshBase::compute_volume_target(), convert_to_boundary_node(), oomph::GmshTetScaffoldMesh::create_mesh_from_msh_file(), doc_boundary_coordinates(), oomph::Z2ErrorEstimator::doc_flux(), oomph::FSI_functions::doc_fsi(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::doc_solution(), oomph::DummyErrorEstimator::DummyErrorEstimator(), oomph::EighthSphereMesh< ELEMENT >::EighthSphereMesh(), oomph::ElasticRefineableQuarterPipeMesh< ELEMENT >::ElasticRefineableQuarterPipeMesh(), ElasticTwoLayerMesh< ELEMENT >::ElasticTwoLayerMesh(), elemental_dimension(), GlobalParameters::find_node_on_centerline(), FlatPlateMesh< ELEMENT >::FlatPlateMesh(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::FpPressureAdvectionDiffusionProblem(), oomph::FSIDrivenCavityMesh< ELEMENT >::FSIDrivenCavityMesh(), FSIRingProblem::FSIRingProblem(), oomph::FullCircleMesh< ELEMENT >::FullCircleMesh(), oomph::GeompackQuadScaffoldMesh::GeompackQuadScaffoldMesh(), oomph::DummyErrorEstimator::get_element_errors(), NodeReordering::get_node_reordering(), oomph::NavierStokesSchurComplementPreconditioner::get_pressure_advection_diffusion_matrix(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::interface_min_max(), max_and_min_element_size(), oomph::MyProblem::min_element_size(), oomph::MyProblem::my_set_initial_condition(), oomph::NetFluxControlElement< ELEMENT >::NetFluxControlElement(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::nfree_surface_spines(), nodal_dimension(), oomph::LinearElasticitySmoothMesh< LINEAR_ELASTICITY_ELEMENT >::operator()(), oomph::PoissonSmoothMesh< POISSON_ELEMENT >::operator()(), oomph::MyProblem::output_exact_solution(), oomph::MyProblem::output_solution(), oomph::TreeBasedRefineableMeshBase::p_adapt_mesh(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::pin_all(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::pin_all_non_pressure_dofs(), oomph::MGSolver< DIM >::plot(), oomph::PMLQuadMeshBase< ELEMENT >::pml_locate_zeta(), oomph::PMLCornerQuadMesh< ELEMENT >::PMLCornerQuadMesh(), oomph::PMLQuadMesh< ELEMENT >::PMLQuadMesh(), print_connectivity_matrix(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::project(), oomph::QuarterCircleSectorMesh< ELEMENT >::QuarterCircleSectorMesh(), oomph::QuarterTubeMesh< ELEMENT >::QuarterTubeMesh(), oomph::RectangleWithHoleMesh< ELEMENT >::RectangleWithHoleMesh(), oomph::TreeBasedRefineableMeshBase::refine_as_in_reference_mesh(), oomph::RefineableEighthSphereMesh< ELEMENT >::RefineableEighthSphereMesh(), oomph::RefineableFullCircleMesh< ELEMENT >::RefineableFullCircleMesh(), oomph::RefineableQuarterPipeMesh< ELEMENT >::RefineableQuarterPipeMesh(), oomph::RefineableQuarterTubeMesh< ELEMENT >::RefineableQuarterTubeMesh(), oomph::RefineableTubeMesh< ELEMENT >::RefineableTubeMesh(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::reset_pin_status(), HeatedCircularPenetratorElement::set_contact_element_mesh_pt(), oomph::NavierStokesImpedanceTractionElement< BULK_NAVIER_STOKES_ELEMENT, WOMERSLEY_ELEMENT, DIM >::set_external_data_from_navier_stokes_outflow_mesh(), oomph::MGSolver< DIM >::set_self_test_vector(), oomph::MyProblem::set_up_impulsive_initial_condition(), oomph::AlgebraicFishMesh< ELEMENT >::setup_algebraic_node_update(), oomph::AlgebraicRefineableQuarterCircleSectorMesh< ELEMENT >::setup_algebraic_node_update(), oomph::AlgebraicRefineableQuarterTubeMesh< ELEMENT >::setup_algebraic_node_update(), oomph::BrickMeshBase::setup_boundary_element_info(), oomph::LineMeshBase::setup_boundary_element_info(), oomph::QuadMeshBase::setup_boundary_element_info(), oomph::TetMeshBase::setup_boundary_element_info(), oomph::TriangleMeshBase::setup_boundary_element_info(), oomph::MGSolver< DIM >::setup_interpolation_matrices(), oomph::HelmholtzMGPreconditioner< DIM >::setup_interpolation_matrices(), ShellMesh< ELEMENT >::ShellMesh(), oomph::SimpleRectangularTriMesh< ELEMENT >::SimpleRectangularTriMesh(), SimpleSpineMesh< ELEMENT >::SimpleSpineMesh(), oomph::TetMeshBase::snap_nodes_onto_geometric_objects(), oomph::TetMeshBase::split_elements_in_corners(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem(), oomph::TetgenScaffoldMesh::TetgenScaffoldMesh(), oomph::ThinLayerBrickOnTetMesh< ELEMENT >::ThinLayerBrickOnTetMesh(), total_size(), TriangleFaceTestProblem< ELEMENT >::TriangleFaceTestProblem(), oomph::TriangleScaffoldMesh::TriangleScaffoldMesh(), oomph::TubeMesh< ELEMENT >::TubeMesh(), TurekProblem< FLUID_ELEMENT, SOLID_ELEMENT >::TurekProblem(), oomph::RefineableTetgenMesh< ELEMENT >::update_faceted_surface_using_face_mesh(), and oomph::WomersleyMesh< WOMERSLEY_ELEMENT >::WomersleyMesh().

◆ flush_element_and_node_storage()

void oomph::Mesh::flush_element_and_node_storage ( )
inline

Flush storage for elements and nodes by emptying the vectors that store the pointers to them. This is useful if a particular mesh is only built to generate a small part of a bigger mesh. Once the elements and nodes have been created, they are typically copied into the new mesh and the auxiliary mesh can be deleted. However, if we simply call the destructor of the auxiliary mesh, it will also wipe out the nodes and elements, because it still "thinks" it's in charge of these...

408  {
411  }
void flush_element_storage()
Definition: mesh.h:423
void flush_node_storage()
Definition: mesh.h:430

References flush_element_storage(), and flush_node_storage().

Referenced by ContactProblem< ELEMENT >::actions_before_adapt(), oomph::RefineableTetgenMesh< ELEMENT >::adapt(), oomph::RefineableGmshTetMesh< ELEMENT >::adapt(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), ContactProblem< ELEMENT >::delete_contact_elements(), ContactProblem< ELEMENT >::delete_displ_imposition_elements(), FourierDecomposedHelmholtzProblem< ELEMENT >::delete_face_elements(), HelmholtzPointSourceProblem< ELEMENT >::delete_face_elements(), ScatteringProblem< ELEMENT >::delete_face_elements(), CoatedDiskProblem< ELASTICITY_ELEMENT, HELMHOLTZ_ELEMENT >::delete_face_elements(), CoatedSphereProblem< ELASTICITY_ELEMENT, HELMHOLTZ_ELEMENT >::delete_face_elements(), PMLFourierDecomposedHelmholtzProblem< ELEMENT >::delete_face_elements(), TwoMeshFluxAdvectionDiffusionProblem< ELEMENT >::delete_flux_elements(), RefineableUnsteadyHeatProblem< ELEMENT >::delete_flux_elements(), RefineableTwoMeshFluxPoissonProblem< ELEMENT >::delete_flux_elements(), AxisymFreeSurfaceNozzleAdvDiffRobinProblem< ELEMENT >::delete_flux_elements(), FluxPoissonMGProblem< ELEMENT, MESH >::delete_flux_elements(), TwoMeshFluxSteadyAxisymAdvectionDiffusionProblem< ELEMENT >::delete_flux_elements(), RefineableRotatingCylinderProblem< ELEMENT >::delete_free_surface_elements(), CollapsibleChannelProblem< ELEMENT >::delete_traction_elements(), FSICollapsibleChannelProblem< ELEMENT >::delete_traction_elements(), RefineableRotatingCylinderProblem< ELEMENT >::delete_volume_constraint_elements(), PseudoElasticCollapsibleChannelProblem< FLUID_ELEMENT, SOLID_ELEMENT >::empty_mesh(), ElasticRefineableQuarterCircleSectorMesh< ELEMENT >::remake_traction_element_mesh(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::reposition_spines(), oomph::RefineableTetgenMesh< ELEMENT >::snap_nodes_onto_boundary(), and oomph::Problem::~Problem().

◆ flush_element_storage()

void oomph::Mesh::flush_element_storage ( )
inline

Flush storage for elements (only) by emptying the vectors that store the pointers to them. This is useful if a particular mesh is only built to generate a small part of a bigger mesh. Once the elements and nodes have been created, they are typically copied into the new mesh and the auxiliary mesh can be deleted. However, if we simply call the destructor of the auxiliary mesh, it will also wipe out the nodes and elements, because it still "thinks" it's in charge of these...

424  {
425  Element_pt.clear();
426  }

References Element_pt.

Referenced by flush_element_and_node_storage().

◆ flush_node_storage()

void oomph::Mesh::flush_node_storage ( )
inline

Flush storage for nodes (only) by emptying the vectors that store the pointers to them.

431  {
432  Node_pt.clear();
433  }

References Node_pt.

Referenced by flush_element_and_node_storage(), and InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::~InclinedPlaneProblem().

◆ get_node_reordering()

void oomph::Mesh::get_node_reordering ( Vector< Node * > &  reordering,
const bool use_old_ordering = true 
) const
virtual

Get a reordering of the nodes in the order in which they appear in elements – can be overloaded for more efficient re-ordering

Get a vector of the nodes in the order in which they are encountered when stepping through the elements (similar to reorder_nodes() but without changing the mesh's node vector).

534  {
535  // If the user wants to use the original order
536  if (use_old_ordering)
537  {
538  // Setup map to check if nodes have been done yet
539  std::map<Node*, bool> done;
540 
541  // Loop over all nodes
542  unsigned nnod = nnode();
543 
544  // Initialise the vector
545  reordering.assign(nnod, 0);
546 
547  // Return immediately if there are no nodes: Note assumption:
548  // Either all the elements' nodes stored here or none. If only a subset
549  // is stored in the Node_pt vector we'll get a range checking error below
550  // (only if run with range checking, of course).
551  if (nnod == 0)
552  {
553  // Return immediately
554  return;
555  }
556 
557  // Loop over the nodes in the mesh
558  for (unsigned j = 0; j < nnod; j++)
559  {
560  // Indicate whether or not the node has been swapped
561  done[node_pt(j)] = false;
562  }
563 
564  // Initialise counter for number of nodes
565  unsigned long count = 0;
566 
567  // Get the number of elements in the mesh
568  unsigned nel = nelement();
569 
570  // Loop over all elements
571  for (unsigned e = 0; e < nel; e++)
572  {
573  // Make sure the e-th element is a FiniteElement (or derived) class
574  // object
575  FiniteElement* el_pt =
576  checked_dynamic_cast<FiniteElement*>(element_pt(e));
577 
578  // Get the number of nodes in this element
579  unsigned nnod = el_pt->nnode();
580 
581  // Loop over nodes in element
582  for (unsigned j = 0; j < nnod; j++)
583  {
584  // Get a pointer to the j-th node in the element
585  Node* nod_pt = el_pt->node_pt(j);
586 
587  // Has node been done yet?
588  if (!done[nod_pt])
589  {
590  // Insert into node vector. NOTE: If you get a seg fault/range
591  // checking error here then you probably haven't added all the
592  // elements' nodes to the Node_pt vector -- this is most likely to
593  // arise in the case of meshes of face elements (though they usually
594  // don't store the nodes at all so if you have any problems here
595  // there's something unusual/not quite right in any case... For this
596  // reason we don't range check here by default (not even under
597  // paranoia) but force you turn on proper (costly) range checking to
598  // track this down...
599  reordering[count] = nod_pt;
600 
601  // Indicate that the node has been done
602  done[nod_pt] = true;
603 
604  // Increase counter
605  count++;
606  }
607  } // for (unsigned j=0;j<nnod;j++)
608  } // for (unsigned e=0;e<nel;e++)
609 
610  // Sanity check
611  if (count != nnod)
612  {
613  // Create an error message
614  std::string error_message = "Trouble: Number of nodes hasn't stayed ";
615 
616  // Finish off the message
617  error_message += "constant during reordering!\n";
618 
619  // Throw an error
620  throw OomphLibError(
622  }
623  }
624  else
625  {
626  // Copy node vector out
627  unsigned n_node = nnode();
628 
629  // Resize the node ordering vector
630  reordering.resize(n_node);
631 
632  // Loop over the nodes
633  for (unsigned i = 0; i < n_node; i++)
634  {
635  // Assign the i-th node pointer entry
636  reordering[i] = node_pt(i);
637  }
638 
639  // Now sort the nodes lexicographically
640  std::sort(reordering.begin(),
641  reordering.end(),
643  } // if (use_old_ordering)
644  } // End of get_node_reordering
bool node_global_position_comparison(Node *nd1_pt, Node *nd2_pt)
Definition: mesh.h:2918

References e(), element_pt(), i, j, nelement(), oomph::FiniteElement::nnode(), nnode(), oomph::NodeOrdering::node_global_position_comparison(), oomph::FiniteElement::node_pt(), node_pt(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and oomph::Global_string_for_annotation::string().

Referenced by dump(), and reorder_nodes().

◆ get_some_non_boundary_node()

Node* oomph::Mesh::get_some_non_boundary_node ( ) const
inline

Find a node not on any boundary in mesh_pt (useful for pinning a single node in a purely Neumann problem so that it is fully determined).

860  {
861  for (unsigned nd = 0, nnd = nnode(); nd < nnd; nd++)
862  {
863  if (!(node_pt(nd)->is_on_boundary()))
864  {
865  return node_pt(nd);
866  }
867  }
868 
869  std::ostringstream error_msg;
870  error_msg << "No non-boundary nodes in the mesh.";
871  throw OomphLibError(
873  // Never get here!
874  return 0;
875  }

References nnode(), node_pt(), OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ is_mesh_distributed()

◆ max_and_min_element_size()

void oomph::Mesh::max_and_min_element_size ( double max_size,
double min_size 
)
inline

Determine max and min area for all FiniteElements in the mesh (non-FiniteElements are ignored)

693  {
694  max_size = 0.0;
695  min_size = DBL_MAX;
696  unsigned nel = nelement();
697  for (unsigned e = 0; e < nel; e++)
698  {
699  max_size = std::max(max_size, finite_element_pt(e)->size());
700  min_size = std::min(min_size, finite_element_pt(e)->size());
701  }
702  }
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
#define min(a, b)
Definition: datatypes.h:22
#define max(a, b)
Definition: datatypes.h:23

References e(), finite_element_pt(), max, min, nelement(), and size.

◆ merge_meshes()

void oomph::Mesh::merge_meshes ( const Vector< Mesh * > &  sub_mesh_pt)

Merge meshes. Note: This simply merges the meshes' elements and nodes (ignoring duplicates; no boundary information etc. is created).

66  {
67  // No boundary lookup scheme is set up for the combined mesh
69 
70  // Number of submeshes
71  unsigned nsub_mesh = sub_mesh_pt.size();
72 
73  // Initialise element, node and boundary counters for global mesh
74  unsigned long n_element = 0;
75  unsigned long n_node = 0;
76  unsigned n_bound = 0;
77 
78  // Loop over submeshes and get total number of elements, nodes and
79  // boundaries
80  for (unsigned imesh = 0; imesh < nsub_mesh; imesh++)
81  {
82  n_element += sub_mesh_pt[imesh]->nelement();
83  n_node += sub_mesh_pt[imesh]->nnode();
84  n_bound += sub_mesh_pt[imesh]->nboundary();
85  }
86 
87  // Reserve storage for element and node pointers
88  Element_pt.clear();
89  Element_pt.reserve(n_element);
90  Node_pt.clear();
91  Node_pt.reserve(n_node);
92 
93  // Resize vector of vectors of nodes
94  Boundary_node_pt.clear();
95  Boundary_node_pt.resize(n_bound);
96 
97  // Sets of pointers to elements and nodes (to exlude duplicates -- they
98  // shouldn't occur anyway but if they do, they must only be added
99  // once in the global mesh to avoid trouble in the timestepping)
100  std::set<GeneralisedElement*> element_set_pt;
101  std::set<Node*> node_set_pt;
102 
103  // Counter for total number of boundaries in all the submeshes
104  unsigned ibound_global = 0;
105  // Loop over the number of submeshes
106  for (unsigned imesh = 0; imesh < nsub_mesh; imesh++)
107  {
108  // Loop over the elements of the submesh and add to vector
109  // duplicates are ignored
110  unsigned nel_before = 0;
111  unsigned long n_element = sub_mesh_pt[imesh]->nelement();
112  for (unsigned long e = 0; e < n_element; e++)
113  {
114  GeneralisedElement* el_pt = sub_mesh_pt[imesh]->element_pt(e);
115  element_set_pt.insert(el_pt);
116  // Was it a duplicate?
117  unsigned nel_now = element_set_pt.size();
118  if (nel_now == nel_before)
119  {
120  std::ostringstream warning_stream;
121  warning_stream << "WARNING: " << std::endl
122  << "Element " << e << " in submesh " << imesh
123  << " is a duplicate \n and was ignored when assembling"
124  << " combined mesh." << std::endl;
125  OomphLibWarning(warning_stream.str(),
126  "Mesh::Mesh(const Vector<Mesh*>&)",
128  }
129  else
130  {
131  Element_pt.push_back(el_pt);
132  }
133  nel_before = nel_now;
134  }
135 
136  // Loop over the nodes of the submesh and add to vector
137  // duplicates are ignored
138  unsigned nnod_before = 0;
139  unsigned long n_node = sub_mesh_pt[imesh]->nnode();
140  for (unsigned long n = 0; n < n_node; n++)
141  {
142  Node* nod_pt = sub_mesh_pt[imesh]->node_pt(n);
143  node_set_pt.insert(nod_pt);
144  // Was it a duplicate?
145  unsigned nnod_now = node_set_pt.size();
146  if (nnod_now == nnod_before)
147  {
148  std::ostringstream warning_stream;
149  warning_stream
150  << "WARNING: " << std::endl
151  << "Node " << n << " in submesh " << imesh
152  << " is a duplicate \n and was ignored when assembling "
153  << "combined mesh." << std::endl;
154  OomphLibWarning(warning_stream.str(),
155  "Mesh::Mesh(const Vector<Mesh*>&)",
157  }
158  else
159  {
160  Node_pt.push_back(nod_pt);
161  }
162  nnod_before = nnod_now;
163  }
164 
165  // Loop over the boundaries of the submesh
166  unsigned n_bound = sub_mesh_pt[imesh]->nboundary();
167  for (unsigned ibound = 0; ibound < n_bound; ibound++)
168  {
169  // Loop over the number of nodes on the boundary and add to the
170  // global vector
171  unsigned long n_bound_node = sub_mesh_pt[imesh]->nboundary_node(ibound);
172  for (unsigned long n = 0; n < n_bound_node; n++)
173  {
174  Boundary_node_pt[ibound_global].push_back(
175  sub_mesh_pt[imesh]->boundary_node_pt(ibound, n));
176  }
177  // Increase the number of the global boundary counter
178  ibound_global++;
179  }
180  } // End of loop over submeshes
181  }

References Boundary_node_pt, boundary_node_pt(), e(), Element_pt, Lookup_for_elements_next_boundary_is_setup, n, Node_pt, and OOMPH_EXCEPTION_LOCATION.

Referenced by Mesh(), oomph::Problem::rebuild_global_mesh(), and oomph::SolidMesh::SolidMesh().

◆ nboundary()

unsigned oomph::Mesh::nboundary ( ) const
inline

Return number of boundaries.

828  {
829  return Boundary_node_pt.size();
830  }

References Boundary_node_pt.

Referenced by oomph::StreamfunctionProblem::actions_before_solve(), oomph::RefineableTetgenMesh< ELEMENT >::adapt(), oomph::RefineableGmshTetMesh< ELEMENT >::adapt(), oomph::TreeBasedRefineableMeshBase::adapt_mesh(), FlowAroundCylinderProblem< ELEMENT >::add_eigenproblem(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_mesh(), oomph::GmshTetMesh< ELEMENT >::build_from_scaffold(), oomph::QuadFromTriangleMesh< ELEMENT >::build_from_scaffold(), oomph::GmshTetMesh< ELEMENT >::build_it(), RefineableDrivenCavityProblem< ELEMENT >::build_mesh(), oomph::ExtrudedCubeMeshFromQuadMesh< ELEMENT >::build_mesh(), RectangularWomersleyImpedanceTube< ELEMENT >::build_mesh_and_apply_boundary_conditions(), CombCanSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), CapProblem< ELEMENT >::CapProblem(), oomph::CollapsibleChannelMesh< ELEMENT >::CollapsibleChannelMesh(), copy_boundary_node_data_from_nodes(), oomph::TwoDimensionalPMLHelper::create_bottom_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_bottom_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_bottom_right_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_right_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_right_pml_mesh(), delete_all_external_storage(), FishPoissonProblem< ELEMENT >::FishPoissonProblem(), FluxPoissonProblem< ELEMENT >::FluxPoissonProblem(), oomph::FSIDrivenCavityMesh< ELEMENT >::FSIDrivenCavityMesh(), oomph::ExtrudedCubeMeshFromQuadMesh< ELEMENT >::get_element_boundary_information(), oomph::NavierStokesSchurComplementPreconditioner::get_pressure_advection_diffusion_matrix(), oomph::NonLinearElasticitySmoothMesh< ELEMENT >::operator()(), output_boundaries(), oomph::TreeBasedRefineableMeshBase::p_adapt_mesh(), oomph::StreamfunctionProblem::pin_boundaries(), prune_dead_nodes(), PseudoSolidCapProblem< ELEMENT >::PseudoSolidCapProblem(), oomph::QuadFromTriangleMesh< ELEMENT >::QuadFromTriangleMesh(), QuarterCircleDrivenCavityProblem< ELEMENT >::QuarterCircleDrivenCavityProblem(), QuarterCircleDrivenCavityProblem2< ELEMENT >::QuarterCircleDrivenCavityProblem2(), oomph::RefineableTetgenMesh< ELEMENT >::RefineableTetgenMesh(), run_navier_stokes_outflow(), run_prescribed_flux(), run_prescribed_pressure_gradient(), oomph::BrickMeshBase::setup_boundary_element_info(), oomph::LineMeshBase::setup_boundary_element_info(), oomph::QuadMeshBase::setup_boundary_element_info(), oomph::TetMeshBase::setup_boundary_element_info(), oomph::TriangleMeshBase::setup_boundary_element_info(), oomph::TetMeshBase::snap_nodes_onto_geometric_objects(), oomph::UnstructuredTwoDMeshGeometryBase::snap_nodes_onto_geometric_objects(), oomph::SolidTetgenMesh< ELEMENT >::SolidTetgenMesh(), oomph::TetMeshBase::split_elements_in_corners(), oomph::TetgenMesh< ELEMENT >::TetgenMesh(), oomph::TriangleMesh< ELEMENT >::TriangleMesh(), TurekProblem< FLUID_ELEMENT, SOLID_ELEMENT >::TurekProblem(), and oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::validate().

◆ nboundary_element()

unsigned oomph::Mesh::nboundary_element ( const unsigned b) const
inline

Return number of finite elements that are adjacent to boundary b.

879  {
880 #ifdef PARANOID
882  {
883  throw OomphLibError("Lookup scheme for elements next to boundary "
884  "hasn't been set up yet!\n",
887  }
888 #endif
889  return Boundary_element_pt[b].size();
890  }

References b, Boundary_element_pt, Lookup_for_elements_next_boundary_is_setup, OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

Referenced by oomph::RefineableTetgenMesh< ELEMENT >::adapt(), oomph::RefineableGmshTetMesh< ELEMENT >::adapt(), oomph::TreeBasedRefineableMeshBase::adapt_mesh(), build_face_mesh(), CapProblem< ELEMENT >::CapProblem(), oomph::TwoDimensionalPMLHelper::create_bottom_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_bottom_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_bottom_right_pml_mesh(), ContactProblem< ELEMENT >::create_contact_heat_elements_on_boulder(), ScatteringProblem< ELEMENT >::create_flux_elements(), PMLProblem< ELEMENT >::create_flux_elements(), TwoMeshFluxAdvectionDiffusionProblem< ELEMENT >::create_flux_elements(), LinearWaveProblem< ELEMENT, TIMESTEPPER >::create_flux_elements(), RefineableUnsteadyHeatProblem< ELEMENT >::create_flux_elements(), RefineableTwoMeshFluxPoissonProblem< ELEMENT >::create_flux_elements(), AxisymFreeSurfaceNozzleAdvDiffRobinProblem< ELEMENT >::create_flux_elements(), TwoMeshFluxPoissonProblem< ELEMENT >::create_flux_elements(), TwoMeshFluxSteadyAxisymAdvectionDiffusionProblem< ELEMENT >::create_flux_elements(), RefineableRotatingCylinderProblem< ELEMENT >::create_free_surface_elements(), ContactProblem< ELEMENT >::create_imposed_heat_flux_elements_on_boulder(), FSICollapsibleChannelProblem< ELEMENT >::create_lagrange_multiplier_elements(), CollapsibleChannelProblem< ELEMENT >::create_lagrange_multiplier_elements(), oomph::TwoDimensionalPMLHelper::create_left_pml_mesh(), HelmholtzPointSourceProblem< ELEMENT >::create_outer_bc_elements(), ScatteringProblem< ELEMENT >::create_outer_bc_elements(), TiltedCavityProblem< ELEMENT >::create_parall_outflow_lagrange_elements(), PMLProblem< ELEMENT >::create_power_elements(), oomph::TwoDimensionalPMLHelper::create_right_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_right_pml_mesh(), CollapsibleChannelProblem< ELEMENT >::create_traction_elements(), RayleighTractionProblem< ELEMENT, TIMESTEPPER >::create_traction_elements(), FSICollapsibleChannelProblem< ELEMENT >::create_traction_elements(), SheetGlueProblem< ELEMENT >::create_traction_elements(), PseudoSolidCapProblem< ELEMENT >::create_volume_constraint_elements(), RefineableRotatingCylinderProblem< ELEMENT >::create_volume_constraint_elements(), SolidFreeSurfaceRotationProblem< ELEMENT >::create_volume_constraint_elements(), doc_boundary_coordinates(), oomph::ExtrudedCubeMeshFromQuadMesh< ELEMENT >::get_element_boundary_information(), oomph::NavierStokesSchurComplementPreconditioner::get_pressure_advection_diffusion_matrix(), InterfaceProblem< ELEMENT, TIMESTEPPER >::InterfaceProblem(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::make_free_surface_elements(), oomph::jh_mesh< ELEMENT >::make_shear_elements(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::make_traction_elements(), oomph::jh_mesh< ELEMENT >::make_traction_elements(), oomph::streamfunction_mesh::make_traction_elements(), oomph::NonLinearElasticitySmoothMesh< ELEMENT >::operator()(), oomph::TreeBasedRefineableMeshBase::p_adapt_mesh(), QFaceTestProblem< ELEMENT >::QFaceTestProblem(), run_navier_stokes_outflow(), oomph::TetMeshBase::setup_boundary_coordinates(), oomph::UnstructuredTwoDMeshGeometryBase::setup_boundary_coordinates(), oomph::RefineableTetgenMesh< ELEMENT >::snap_nodes_onto_boundary(), oomph::TetMeshBase::snap_to_quadratic_surface(), oomph::TetMeshBase::split_elements_in_corners(), TFaceTestProblem< ELEMENT >::TFaceTestProblem(), oomph::ThinLayerBrickOnTetMesh< ELEMENT >::ThinLayerBrickOnTetMesh(), TriangleFaceTestProblem< ELEMENT >::TriangleFaceTestProblem(), and oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::validate().

◆ nboundary_node()

unsigned long oomph::Mesh::nboundary_node ( const unsigned ibound) const
inline

Return number of nodes on a particular boundary.

834  {
835  return Boundary_node_pt[ibound].size();
836  }

References Boundary_node_pt.

Referenced by FSICollapsibleChannelProblem< ELEMENT >::actions_after_adapt(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_implicit_timestep(), oomph::StreamfunctionProblem::actions_before_solve(), oomph::RefineableTetgenMesh< ELEMENT >::adapt(), oomph::RefineableGmshTetMesh< ELEMENT >::adapt(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_mesh(), build_face_mesh(), oomph::ExtrudedCubeMeshFromQuadMesh< ELEMENT >::build_mesh(), RectangularWomersleyImpedanceTube< ELEMENT >::build_mesh_and_apply_boundary_conditions(), CombCanSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), CapProblem< ELEMENT >::CapProblem(), CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::change_boundaries(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::complete_build(), oomph::TwoDimensionalPMLHelper::create_bottom_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_bottom_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_bottom_right_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_right_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_right_pml_mesh(), demo_smoothing_with_linear_elasticity(), demo_smoothing_with_poisson(), oomph::ElasticRefineableRectangularQuadMesh< ELEMENT >::ElasticRefineableRectangularQuadMesh(), ElasticTwoLayerMesh< ELEMENT >::ElasticTwoLayerMesh(), FluxPoissonProblem< ELEMENT >::FluxPoissonProblem(), FSIRingProblem::FSIRingProblem(), oomph::StreamfunctionProblem::pin_boundaries(), oomph::PMLCornerQuadMesh< ELEMENT >::PMLCornerQuadMesh(), oomph::PMLQuadMesh< ELEMENT >::PMLQuadMesh(), PseudoSolidCapProblem< ELEMENT >::PseudoSolidCapProblem(), QuarterCircleDrivenCavityProblem< ELEMENT >::QuarterCircleDrivenCavityProblem(), QuarterCircleDrivenCavityProblem2< ELEMENT >::QuarterCircleDrivenCavityProblem2(), oomph::QuarterPipeMesh< ELEMENT >::QuarterPipeMesh(), oomph::RefineableQuadMeshWithMovingCylinder< ELEMENT >::RefineableQuadMeshWithMovingCylinder(), oomph::RefineableSolidCubicMesh< ELEMENT >::RefineableSolidCubicMesh(), run_navier_stokes_outflow(), run_prescribed_flux(), run_prescribed_pressure_gradient(), oomph::TetMeshBase::setup_boundary_coordinates(), oomph::RefineableTetgenMesh< ELEMENT >::snap_nodes_onto_boundary(), oomph::TetMeshBase::snap_nodes_onto_geometric_objects(), oomph::UnstructuredTwoDMeshGeometryBase::snap_nodes_onto_geometric_objects(), oomph::ThinLayerBrickOnTetMesh< ELEMENT >::ThinLayerBrickOnTetMesh(), and TurekProblem< FLUID_ELEMENT, SOLID_ELEMENT >::TurekProblem().

◆ ndof_types()

unsigned oomph::Mesh::ndof_types ( ) const

Return number of dof types in mesh.

Get the number of dof types in the mesh from the first element of the mesh. If MPI is on then also do some consistency checks between processors. Careful: Involves MPI Broadcasts and must therefore be called on all processors!

8765  {
8766  // Remains -1 if we don't have any elements on this processor.
8767  int int_ndof_types = -1;
8768  unsigned nel = nelement();
8769  if (nel > 0)
8770  {
8771  int_ndof_types = element_pt(0)->ndof_types();
8772 #ifdef PARANOID
8773  // Check that every element in this mesh has the same number of
8774  // types of DOF.
8775  for (unsigned i = 1; i < nel; i++)
8776  {
8777  if (int_ndof_types != int(element_pt(i)->ndof_types()))
8778  {
8779  std::ostringstream error_message;
8780  error_message
8781  << "Every element in the mesh must have the same number of "
8782  << "types of DOF for ndof_types() to work\n"
8783  << "Element 0 has " << int_ndof_types << " DOF types\n"
8784  << "Element " << i << " [out of a total of " << nel << " ] has "
8785  << element_pt(i)->ndof_types() << " DOF types"
8786  << "Element types are: Element 0:" << typeid(*element_pt(0)).name()
8787  << "\n"
8788  << " Current Element :" << typeid(*element_pt(i)).name()
8789  << "\n";
8790  throw OomphLibError(error_message.str(),
8793  }
8794  }
8795 #endif
8796  }
8797 
8798 #ifdef OOMPH_HAS_MPI
8799 
8800  // If mesh is distributed
8801  if (is_mesh_distributed())
8802  {
8803  // if more than one processor then
8804  // + ensure number of DOFs is consistent on each processor (PARANOID)
8805  // + ensure processors with no elements in this mesh have the
8806  // correct number of DOF types
8807  if (Comm_pt->nproc() > 1)
8808  {
8809  unsigned nproc = Comm_pt->nproc();
8810  unsigned my_rank = Comm_pt->my_rank();
8811 
8812  // Collect on root the number of dofs types determined independently
8813  // on all processors (-1 indicates that the processor didn't have
8814  // any elements and therefore doesn't know!)
8815  int* ndof_types_recv = 0;
8816  if (my_rank == 0)
8817  {
8818  ndof_types_recv = new int[nproc];
8819  }
8820 
8821  MPI_Gather(&int_ndof_types,
8822  1,
8823  MPI_INT,
8824  ndof_types_recv,
8825  1,
8826  MPI_INT,
8827  0,
8828  Comm_pt->mpi_comm());
8829 
8830  // Root: Update own number of dof types, check consistency amongst
8831  // all processors (in paranoid mode) and send out the actual
8832  // number of dof types to those processors who couldn't figure this
8833  // out themselves
8834  if (my_rank == 0)
8835  {
8836  // Check number of types of all non-root processors
8837  for (unsigned p = 1; p < nproc; p++)
8838  {
8839  if (ndof_types_recv[p] != -1)
8840  {
8841  // Processor p was able to figure out how many
8842  // dof types there are, so I root can update
8843  // its own (if required)
8844  if (int_ndof_types == -1)
8845  {
8846  int_ndof_types = ndof_types_recv[p];
8847  }
8848 #ifdef PARANOID
8849  // Check consistency
8850  else if (int_ndof_types != ndof_types_recv[p])
8851  {
8852  std::ostringstream error_message;
8853  error_message
8854  << "The elements in this mesh must have the same number "
8855  << "of types of DOF on each processor";
8856  for (unsigned p = 0; p < nproc; p++)
8857  {
8858  if (ndof_types_recv[p] != -1)
8859  {
8860  error_message << "Processor " << p << " : "
8861  << ndof_types_recv[p] << "\n";
8862  }
8863  else
8864  {
8865  error_message << "Processor " << p << " : (no elements)\n";
8866  }
8867  }
8868  throw OomphLibError(error_message.str(),
8871  }
8872 #endif
8873  }
8874  }
8875 
8876  // Now send ndof types to non-root processors that don't have it
8877  for (unsigned p = 1; p < nproc; p++)
8878  {
8879  if (ndof_types_recv[p] == -1)
8880  {
8881  MPI_Send(&int_ndof_types, 1, MPI_INT, p, 0, Comm_pt->mpi_comm());
8882  }
8883  }
8884  // clean up
8885  delete[] ndof_types_recv;
8886  }
8887  // "else if": "else" for non-root; "if" for checking if current
8888  // (non-root) processor does not know ndof type and is therefore
8889  // about to receive it from root.
8890  else if (int_ndof_types == -1)
8891  {
8892  MPI_Recv(&int_ndof_types,
8893  1,
8894  MPI_INT,
8895  0,
8896  0,
8897  Comm_pt->mpi_comm(),
8898  MPI_STATUS_IGNORE);
8899  }
8900  }
8901  }
8902 #endif
8903 
8904  // If int_ndof_types if still -1 then no elements were found for this mesh,
8905  // so it has no dofs.
8906  if (int_ndof_types == -1) int_ndof_types = 0;
8907 
8908  return unsigned(int_ndof_types);
8909  }
unsigned ndof_types() const
Return number of dof types in mesh.
Definition: mesh.cc:8764

References element_pt(), i, is_mesh_distributed(), plotDoE::name, nelement(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and p.

Referenced by oomph::BlockPreconditioner< MATRIX >::ndof_types_in_mesh().

◆ nelement()

unsigned long oomph::Mesh::nelement ( ) const
inline

Return number of elements in the mesh.

591  {
592  return Element_pt.size();
593  }

References Element_pt.

Referenced by oomph::IMRByBDF::actions_after_timestep(), oomph::RefineableTetgenMesh< ELEMENT >::adapt(), oomph::RefineableGmshTetMesh< ELEMENT >::adapt(), oomph::TreeBasedRefineableMeshBase::adapt(), oomph::TreeBasedRefineableMeshBase::adapt_mesh(), oomph::PeriodicOrbitAssemblyHandler< NNODE_1D >::adapt_temporal_mesh(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_mesh(), oomph::NavierStokesSchurComplementPreconditioner::assemble_inv_press_and_veloc_mass_matrix_diagonal(), oomph::PressureBasedSolidLSCPreconditioner::assemble_mass_matrix_diagonal(), oomph::PeriodicOrbitTemporalMesh< ELEMENT >::assemble_residuals(), oomph::PeriodicOrbitTemporalMesh< ELEMENT >::assemble_residuals_and_jacobian(), oomph::TetMeshBase::assess_mesh_quality(), oomph::Problem::assign_eqn_numbers(), assign_initial_values_impulsive(), oomph::Multi_domain_functions::aux_setup_multi_domain_interaction(), AxisymFreeSurfaceNozzleAdvDiffRobinProblem< ELEMENT >::AxisymFreeSurfaceNozzleAdvDiffRobinProblem(), oomph::SolidICProblem::backup_original_state(), oomph::BackupMeshForProjection< GEOMETRIC_ELEMENT >::BackupMeshForProjection(), oomph::GmshTetMesh< ELEMENT >::build_from_scaffold(), oomph::QuadFromTriangleMesh< ELEMENT >::build_from_scaffold(), oomph::MeshAsGeomObject::build_it(), oomph::ExtrudedCubeMeshFromQuadMesh< ELEMENT >::build_mesh(), CombCanSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), calculate_predictions(), CapProblem< ELEMENT >::CapProblem(), check_inverted_elements(), oomph::TriangleScaffoldMesh::check_mesh_integrity(), oomph::CollapsibleChannelMesh< ELEMENT >::CollapsibleChannelMesh(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::complete_build(), ContactProblem< ELEMENT >::complete_problem_setup(), AdvectionProblem::compute_error(), TwoDDGProblem< ELEMENT >::compute_error(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::compute_integrated_concentrations(), InterfaceProblem< ELEMENT, TIMESTEPPER >::compute_total_mass(), oomph::RefineableTetMeshBase::compute_volume_target(), AirwayReopeningProblem< ELEMENT >::connect_walls(), ConvectionProblem< NST_ELEMENT, AD_ELEMENT >::ConvectionProblem(), convert_to_boundary_node(), oomph::Problem::copy(), oomph::TwoDimensionalPMLHelper::create_bottom_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_bottom_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_bottom_right_pml_mesh(), PseudoSolidCapProblem< ELEMENT >::create_contact_angle_element(), MovingBlockProblem< ELEMENT >::create_extruded_mesh(), RefineableRotatingCylinderProblem< ELEMENT >::create_free_surface_elements(), oomph::TwoDimensionalPMLHelper::create_left_pml_mesh(), oomph::GmshTetScaffoldMesh::create_mesh_from_msh_file(), oomph::TwoDimensionalPMLHelper::create_right_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_left_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_pml_mesh(), oomph::TwoDimensionalPMLHelper::create_top_right_pml_mesh(), SheetGlueProblem< ELEMENT >::create_traction_elements(), ContactProblem< ELEMENT >::delete_contact_elements(), ContactProblem< ELEMENT >::delete_displ_imposition_elements(), FourierDecomposedHelmholtzProblem< ELEMENT >::delete_face_elements(), HelmholtzPointSourceProblem< ELEMENT >::delete_face_elements(), ScatteringProblem< ELEMENT >::delete_face_elements(), CoatedDiskProblem< ELASTICITY_ELEMENT, HELMHOLTZ_ELEMENT >::delete_face_elements(), CoatedSphereProblem< ELASTICITY_ELEMENT, HELMHOLTZ_ELEMENT >::delete_face_elements(), PMLFourierDecomposedHelmholtzProblem< ELEMENT >::delete_face_elements(), TwoMeshFluxAdvectionDiffusionProblem< ELEMENT >::delete_flux_elements(), RefineableUnsteadyHeatProblem< ELEMENT >::delete_flux_elements(), RefineableTwoMeshFluxPoissonProblem< ELEMENT >::delete_flux_elements(), AxisymFreeSurfaceNozzleAdvDiffRobinProblem< ELEMENT >::delete_flux_elements(), FluxPoissonMGProblem< ELEMENT, MESH >::delete_flux_elements(), TwoMeshFluxSteadyAxisymAdvectionDiffusionProblem< ELEMENT >::delete_flux_elements(), RefineableRotatingCylinderProblem< ELEMENT >::delete_free_surface_elements(), CollapsibleChannelProblem< ELEMENT >::delete_traction_elements(), FSICollapsibleChannelProblem< ELEMENT >::delete_traction_elements(), RefineableRotatingCylinderProblem< ELEMENT >::delete_volume_constraint_elements(), oomph::Problem::disable_mass_matrix_reuse(), oomph::SolidHelpers::doc_2D_principal_stress(), doc_boundary_coordinates(), oomph::Z2ErrorEstimator::doc_flux(), oomph::FSI_functions::doc_fsi(), OscRingNStProblem< ELEMENT >::doc_solution(), OscRingNStProblem< ELEMENT >::doc_solution_historic(), does_pointer_correspond_to_mesh_data(), oomph::DummyErrorEstimator::DummyErrorEstimator(), dump(), ProblemParameters::edge_sign_setup(), TestProblem::edge_sign_setup(), Global_Physical_Variables::edge_sign_setup(), ElasticInterfaceProblem< ELEMENT, TIMESTEPPER >::ElasticInterfaceProblem(), oomph::ElasticRefineableQuarterPipeMesh< ELEMENT >::ElasticRefineableQuarterPipeMesh(), elemental_dimension(), PseudoElasticCollapsibleChannelProblem< FLUID_ELEMENT, SOLID_ELEMENT >::empty_mesh(), oomph::Problem::enable_mass_matrix_reuse(), oomph::NetFluxControlElement< ELEMENT >::fill_in_contribution_to_residuals(), oomph::NetFluxControlElement< ELEMENT >::fill_in_generic_residual_contribution_flux_control(), GlobalParameters::find_node_on_centerline(), FluxPoissonProblem< ELEMENT >::FluxPoissonProblem(), oomph::FoldHandler::FoldHandler(), FSIChannelWithLeafletProblem< ELEMENT >::FSIChannelWithLeafletProblem(), oomph::FSIDrivenCavityMesh< ELEMENT >::FSIDrivenCavityMesh(), FSIRingProblem::FSIRingProblem(), oomph::Multi_domain_functions::get_dim_helper(), oomph::Z2ErrorEstimator::get_element_errors(), oomph::DummyErrorEstimator::get_element_errors(), oomph::ImmersedRigidBodyElement::get_force_and_torque(), oomph::Problem::get_hessian_vector_products(), oomph::Problem::get_inverse_mass_matrix_times_residuals(), oomph::Problem::get_jacobian(), NodeReordering::get_node_reordering(), get_node_reordering(), oomph::NavierStokesSchurComplementPreconditioner::get_pressure_advection_diffusion_matrix(), oomph::TreeBasedRefineableMeshBase::get_refinement_levels(), oomph::Problem::get_residuals(), oomph::FoldHandler::get_residuals(), oomph::HopfHandler::get_residuals(), oomph::HopfHandler::HopfHandler(), oomph::ImposeFluxForWomersleyElement< DIM >::ImposeFluxForWomersleyElement(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::interface_min_max(), InterfaceProblem< ELEMENT, TIMESTEPPER >::InterfaceProblem(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::l2_norm_of_height(), oomph::DGMesh::limit_slopes(), oomph::MacroElementNodeUpdateChannelWithLeafletMesh< ELEMENT >::MacroElementNodeUpdateChannelWithLeafletMesh(), oomph::MacroElementNodeUpdateCollapsibleChannelMesh< ELEMENT >::MacroElementNodeUpdateCollapsibleChannelMesh(), oomph::MacroElementNodeUpdateRefineableFishMesh< ELEMENT >::MacroElementNodeUpdateRefineableFishMesh(), main(), max_and_min_element_size(), oomph::HelmholtzMGPreconditioner< DIM >::maximum_edge_width(), MeltSpinningProblem< ELEMENT >::MeltSpinningProblem(), oomph::MyProblem::min_element_size(), oomph::MyProblem::my_set_initial_condition(), ndof_types(), oomph::NetFluxControlElement< ELEMENT >::NetFluxControlElement(), nodal_dimension(), node_update(), oomph::ImmersedRigidBodyElement::node_update_adjacent_fluid_elements(), oomph::NonLinearElasticitySmoothMesh< ELEMENT >::operator()(), oomph::LinearElasticitySmoothMesh< LINEAR_ELASTICITY_ELEMENT >::operator()(), oomph::PoissonSmoothMesh< POISSON_ELEMENT >::operator()(), oomph::PeriodicOrbitTemporalMesh< ELEMENT >::orbit_output(), oomph::PeriodicOrbitAssemblyHandler< NNODE_1D >::orbit_output(), oomph::MyProblem::output_exact_solution(), oomph::MyProblem::output_solution(), oomph::TreeBasedRefineableMeshBase::p_adapt(), oomph::TreeBasedRefineableMeshBase::p_adapt_mesh(), oomph::TreeBasedRefineableMeshBase::p_refine_uniformly(), oomph::TreeBasedRefineableMeshBase::p_unrefine_uniformly(), oomph::METIS::partition_mesh(), PerturbedStateProblem< BASE_ELEMENT, PERTURBED_ELEMENT >::PerturbedStateProblem(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::pin_all(), oomph::NavierStokesSchurComplementPreconditioner::pin_all_non_pressure_dofs(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::pin_all_non_pressure_dofs(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::pin_dofs_of_field(), oomph::PitchForkHandler::PitchForkHandler(), oomph::MGSolver< DIM >::plot(), oomph::PMLCornerQuadMesh< ELEMENT >::PMLCornerQuadMesh(), oomph::PMLQuadMesh< ELEMENT >::PMLQuadMesh(), oomph::WomersleyImpedanceTubeBase< ELEMENT, DIM >::precompute_aux_integrals(), print_connectivity_matrix(), print_elemental_jacobian(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::project(), PseudoSolidCapProblem< ELEMENT >::PseudoSolidCapProblem(), QuarterCircleDrivenCavityProblem< ELEMENT >::QuarterCircleDrivenCavityProblem(), QuarterCircleDrivenCavityProblem2< ELEMENT >::QuarterCircleDrivenCavityProblem2(), oomph::QuarterCircleSectorMesh< ELEMENT >::QuarterCircleSectorMesh(), oomph::QuarterPipeMesh< ELEMENT >::QuarterPipeMesh(), read(), oomph::Problem::read(), oomph::TreeBasedRefineableMeshBase::refine_as_in_reference_mesh(), oomph::TreeBasedRefineableMeshBase::refine_uniformly(), oomph::RefineableEighthSphereMesh< ELEMENT >::RefineableEighthSphereMesh(), oomph::RefineableTwoDAnnularMesh< ELEMENT >::RefineableTwoDAnnularMesh(), RefineableUnsteadyHeatProblem< ELEMENT >::RefineableUnsteadyHeatProblem(), oomph::HSL_MA42::reorder_elements(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::reposition_spines(), oomph::SolidICProblem::reset_original_state(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::reset_pin_status(), oomph::NavierStokesSchurComplementPreconditioner::reset_pin_status(), oomph::AugmentedBlockFoldLinearSolver::resolve(), oomph::AugmentedBlockPitchForkLinearSolver::resolve(), HeatedCircularPenetratorElement::resulting_force(), set_consistent_pinned_values_for_continuation(), HeatedCircularPenetratorElement::set_contact_element_mesh_pt(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::set_coordinate_for_projection(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::set_current_field_for_projection(), oomph::ImmersedRigidBodyElement::set_drag_mesh(), set_elemental_internal_time_stepper(), oomph::NavierStokesImpedanceTractionElement< BULK_NAVIER_STOKES_ELEMENT, WOMERSLEY_ELEMENT, DIM >::set_external_data_from_navier_stokes_outflow_mesh(), AdvectionProblem::set_initial_conditions(), EulerProblem::set_initial_conditions(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::set_lagrangian_coordinate_for_projection(), oomph::SolidICProblem::set_newmark_initial_condition_consistently(), oomph::Problem::set_pinned_values_to_zero(), oomph::MGSolver< DIM >::set_self_test_vector(), oomph::BiharmonicProblem< DIM >::set_source_function(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::set_time_level_for_projection(), oomph::MyProblem::set_up_impulsive_initial_condition(), oomph::AlgebraicRefineableQuarterTubeMesh< ELEMENT >::setup_algebraic_node_update(), oomph::RefineableLineMesh< ELEMENT >::setup_binary_tree_forest(), oomph::BrickMeshBase::setup_boundary_element_info(), oomph::LineMeshBase::setup_boundary_element_info(), oomph::QuadMeshBase::setup_boundary_element_info(), oomph::TetMeshBase::setup_boundary_element_info(), oomph::TriangleMeshBase::setup_boundary_element_info(), oomph::Problem::setup_element_count_per_dof(), oomph::DGMesh::setup_face_neighbour_info(), oomph::MGSolver< DIM >::setup_interpolation_matrices(), oomph::HelmholtzMGPreconditioner< DIM >::setup_interpolation_matrices(), oomph::MacroElementNodeUpdateRefineableQuarterCircleSectorMesh< ELEMENT >::setup_macro_element_node_update(), oomph::MacroElementNodeUpdateRefineableQuarterTubeMesh< ELEMENT >::setup_macro_element_node_update(), oomph::RefineableBrickMesh< ELEMENT >::setup_octree_forest(), oomph::VorticitySmoother< ELEMENT >::setup_patches(), oomph::Z2ErrorEstimator::setup_patches(), oomph::SolidICProblem::setup_problem(), oomph::RefineableQuadMesh< ELEMENT >::setup_quadtree_forest(), shift_time_values(), oomph::RefineableTetgenMesh< ELEMENT >::snap_nodes_onto_boundary(), oomph::TetMeshBase::snap_nodes_onto_geometric_objects(), oomph::AugmentedBlockFoldLinearSolver::solve(), oomph::AugmentedBlockPitchForkLinearSolver::solve(), oomph::BlockHopfLinearSolver::solve(), oomph::HSL_MA42::solve(), oomph::HSL_MA42::solve_for_one_dof(), oomph::BlockHopfLinearSolver::solve_for_two_rhs(), oomph::Problem::sparse_assemble_row_or_column_compressed_with_lists(), oomph::Problem::sparse_assemble_row_or_column_compressed_with_maps(), oomph::Problem::sparse_assemble_row_or_column_compressed_with_two_arrays(), oomph::Problem::sparse_assemble_row_or_column_compressed_with_two_vectors(), oomph::Problem::sparse_assemble_row_or_column_compressed_with_vectors_of_pairs(), oomph::TetMeshBase::split_elements_in_corners(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem(), ContactProblem< ELEMENT >::switch_to_force_control(), total_size(), oomph::ImposeFluxForWomersleyElement< DIM >::total_volume_flux(), oomph::NavierStokesImpedanceTractionElement< BULK_NAVIER_STOKES_ELEMENT, WOMERSLEY_ELEMENT, DIM >::total_volume_flux_into_downstream_tube(), oomph::WomersleyImpedanceTubeBase< ELEMENT, DIM >::total_volume_flux_into_impedance_tube(), TriangleFaceTestProblem< ELEMENT >::TriangleFaceTestProblem(), TurekProblem< FLUID_ELEMENT, SOLID_ELEMENT >::TurekProblem(), TwoDDGProblem< ELEMENT >::TwoDDGProblem(), TwoMeshFluxAdvectionDiffusionProblem< ELEMENT >::TwoMeshFluxAdvectionDiffusionProblem(), TwoMeshFluxPoissonProblem< ELEMENT >::TwoMeshFluxPoissonProblem(), oomph::METIS::uniform_partition_mesh(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::unpin_all(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::unpin_dofs_of_field(), oomph::TreeBasedRefineableMeshBase::unrefine_uniformly(), oomph::RefineableTetgenMesh< ELEMENT >::update_faceted_surface_using_face_mesh(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::validate(), oomph::WomersleyImpedanceTubeBase< ELEMENT, DIM >::WomersleyImpedanceTubeBase(), oomph::WomersleyMesh< WOMERSLEY_ELEMENT >::WomersleyMesh(), and oomph::WomersleyProblem< ELEMENT, DIM >::WomersleyProblem().

◆ nnode()

unsigned long oomph::Mesh::nnode ( ) const
inline

Return number of nodes in the mesh.

597  {
598  return Node_pt.size();
599  }

References Node_pt.

Referenced by oomph::IMRByBDF::actions_after_timestep(), oomph::NonLinearElasticitySmoothMesh< ELEMENT >::actions_before_newton_solve(), SolidBag::actionsBeforeOomphTimeStep(), oomph::RefineableTetgenMesh< ELEMENT >::adapt(), oomph::RefineableGmshTetMesh< ELEMENT >::adapt(), oomph::TreeBasedRefineableMeshBase::adapt_mesh(), oomph::PeriodicOrbitAssemblyHandler< NNODE_1D >::adapt_temporal_mesh(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_mesh(), assign_initial_values_impulsive(), oomph::StreamfunctionProblem::assign_velocities(), oomph::Multi_domain_functions::aux_setup_multi_domain_interaction(), oomph::NonLinearElasticitySmoothMesh< ELEMENT >::backup(), oomph::SolidICProblem::backup_original_state(), oomph::BackupMeshForProjection< GEOMETRIC_ELEMENT >::BackupMeshForProjection(), SolidBag::bendBag(), oomph::GmshTetMesh< ELEMENT >::build_from_scaffold(), oomph::MeshAsGeomObject::build_it(), oomph::ExtrudedCubeMeshFromQuadMesh< ELEMENT >::build_mesh(), CombCanSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::build_single_layer_mesh(), calculate_predictions(), check_for_repeated_nodes(), oomph::TriangleScaffoldMesh::check_mesh_integrity(), oomph::MyProblem::check_not_segregated(), oomph::CollapsibleChannelMesh< ELEMENT >::CollapsibleChannelMesh(), oomph::TreeBasedRefineableMeshBase::complete_hanging_nodes(), oomph::AddedMainNumberingLookup::construct_added_to_main_mapping(), oomph::Problem::copy(), copy_boundary_node_data_from_nodes(), MovingBlockProblem< ELEMENT >::create_extruded_mesh(), InterfaceProblem< ELEMENT, TIMESTEPPER >::deform_free_surface(), MeshDeformation::deform_mesh(), delete_all_external_storage(), demo_smoothing_with_nonlinear_elasticity(), oomph::FSI_functions::doc_fsi(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::doc_solution(), doc_sparse_node_update(), does_pointer_correspond_to_mesh_data(), dump(), FlatPlateMesh< ELEMENT >::FlatPlateMesh(), oomph::FSIDrivenCavityMesh< ELEMENT >::FSIDrivenCavityMesh(), oomph::Z2ErrorEstimator::get_element_errors(), NodeReordering::get_node_reordering(), get_node_reordering(), get_some_non_boundary_node(), main(), oomph::MyProblem::my_set_initial_condition(), oomph::AlgebraicMesh::node_update(), oomph::MacroElementNodeUpdateMesh::node_update(), node_update(), oomph::NonLinearElasticitySmoothMesh< ELEMENT >::operator()(), oomph::LinearElasticitySmoothMesh< LINEAR_ELASTICITY_ELEMENT >::operator()(), oomph::PoissonSmoothMesh< POISSON_ELEMENT >::operator()(), PolarNSProblem< ELEMENT >::output_streamfunction(), oomph::TreeBasedRefineableMeshBase::p_adapt_mesh(), PerturbedStateProblem< BASE_ELEMENT, PERTURBED_ELEMENT >::PerturbedStateProblem(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::pin_all(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::pin_dofs_of_coordinate(), oomph::StreamfunctionProblem::pin_velocities(), oomph::PMLQuadMeshBase< ELEMENT >::pml_locate_zeta(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::project(), prune_dead_nodes(), PseudoSolidCapProblem< ELEMENT >::PseudoSolidCapProblem(), read(), oomph::VorticitySmoother< ELEMENT >::recover_vorticity(), reorder_nodes(), NodeReordering::reorder_nodes(), oomph::NonLinearElasticitySmoothMesh< ELEMENT >::reset(), oomph::SolidICProblem::reset_original_state(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::reset_pin_status(), oomph::NavierStokesSchurComplementPreconditioner::reset_pin_status(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::restore_positions(), CombCanSpineMesh< ELEMENT, INTERFACE_ELEMENT >::rotate_90(), CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::rotate_90_zeq1_xeq0(), CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::rotate_90_zeq1_yeq0(), run_navier_stokes_outflow(), scale_mesh(), oomph::MyProblem::segregated_pin_indices(), oomph::AlgebraicMesh::self_test(), set_consistent_pinned_values_for_continuation(), oomph::SolidMesh::set_lagrangian_nodal_coordinates(), oomph::SolidICProblem::set_newmark_initial_condition_consistently(), oomph::SolidICProblem::set_newmark_initial_condition_directly(), set_nodal_time_stepper(), oomph::Problem::set_pinned_values_to_zero(), oomph::MyProblem::set_up_impulsive_initial_condition(), oomph::MGSolver< DIM >::setup_interpolation_matrices_unstructured(), oomph::HelmholtzMGPreconditioner< DIM >::setup_interpolation_matrices_unstructured(), oomph::SolidICProblem::setup_problem(), ShellMesh< ELEMENT >::ShellMesh(), shift_time_values(), oomph::TetMeshBase::snap_nodes_onto_geometric_objects(), ABCProblem< ELEMENT, TIMESTEPPERT >::solve(), oomph::TetMeshBase::split_elements_in_corners(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::store_positions(), oomph::Refineable_r_mesh< ELEMENT >::stretch_mesh(), oomph::TriangleScaffoldMesh::TriangleScaffoldMesh(), oomph::MyProblem::undo_segregated_pinning(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::unpin_all(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::unpin_dofs_of_coordinate(), and oomph::WomersleyMesh< WOMERSLEY_ELEMENT >::WomersleyMesh().

◆ nodal_dimension()

unsigned oomph::Mesh::nodal_dimension ( ) const

Return number of nodal dimension in mesh.

Get the number of nodal dimension in the mesh from the first element of the mesh. If MPI is on then also do some consistency checks between processors. Careful: Involves MPI Broadcasts and must therefore be called on all processors!

9056  {
9057  // Remains -1 if we don't have any elements on this processor.
9058  int int_dim = -1;
9059  if (nelement() > 0)
9060  {
9061  int_dim = finite_element_pt(0)->nodal_dimension();
9062 #ifdef PARANOID
9063  // Check that every element in this mesh has the same number of
9064  // types of nodal dimension.
9065  for (unsigned i = 1; i < nelement(); i++)
9066  {
9067  if (int_dim != int(finite_element_pt(i)->nodal_dimension()))
9068  {
9069  std::ostringstream error_message;
9070  error_message
9071  << "Every element in the mesh must have the same number of "
9072  << "nodal dimension for nodal_dimension() to work.\n"
9073  << "Element 0 has nodal dimension " << int_dim << "\n"
9074  << "Element " << i << " has nodal dimension "
9075  << finite_element_pt(i)->nodal_dimension() << ".";
9076  throw OomphLibError(error_message.str(),
9079  }
9080  }
9081 #endif
9082  }
9083 
9084 #ifdef OOMPH_HAS_MPI
9085 
9086  // If mesh is distributed
9087  if (Comm_pt != 0)
9088  {
9089  // if more than one processor then
9090  // + ensure dimension number is consistent on each processor (PARANOID)
9091  // + ensure processors with no elements in this mesh have the
9092  // correct dimension number.
9093  if (Comm_pt->nproc() > 1)
9094  {
9095  unsigned nproc = Comm_pt->nproc();
9096  unsigned my_rank = Comm_pt->my_rank();
9097 
9098  // Collect on root the dimension number determined independently
9099  // on all processors (-1 indicates that the processor didn't have
9100  // any elements and therefore doesn't know!)
9101  int* dim_recv = 0;
9102  if (my_rank == 0)
9103  {
9104  dim_recv = new int[nproc];
9105  }
9106 
9107  MPI_Gather(
9108  &int_dim, 1, MPI_INT, dim_recv, 1, MPI_INT, 0, Comm_pt->mpi_comm());
9109 
9110  // Root: Update own dimension, check consistency amongst
9111  // all processors (in paranoid mode) and send out the actual
9112  // dimension number to those processors who couldn't figure this
9113  // out themselves
9114  if (my_rank == 0)
9115  {
9116  // Check number of types of all non-root processors
9117  for (unsigned p = 1; p < nproc; p++)
9118  {
9119  if (dim_recv[p] != -1)
9120  {
9121  // Processor p was able to figure out the nodal
9122  // dimension, so I root can update
9123  // its own (if required)
9124  if (int_dim == -1)
9125  {
9126  int_dim = dim_recv[p];
9127  }
9128 #ifdef PARANOID
9129  // Check consistency
9130  else if (int_dim != dim_recv[p])
9131  {
9132  std::ostringstream error_message;
9133  error_message
9134  << "The elements in this mesh must have the same nodal "
9135  << "dimension number on each processor";
9136  for (unsigned p = 0; p < nproc; p++)
9137  {
9138  if (dim_recv[p] != -1)
9139  {
9140  error_message << "Processor " << p << " : " << dim_recv[p]
9141  << "\n";
9142  }
9143  else
9144  {
9145  error_message << "Processor " << p << " : (no elements)\n";
9146  }
9147  }
9148  throw OomphLibError(error_message.str(),
9151  }
9152 #endif
9153  }
9154  }
9155 
9156  // Now send the nodal dimension to non-root processors that
9157  // don't have it
9158  for (unsigned p = 1; p < nproc; p++)
9159  {
9160  if (dim_recv[p] == -1)
9161  {
9162  MPI_Send(&int_dim, 1, MPI_INT, p, 0, Comm_pt->mpi_comm());
9163  }
9164  }
9165  // clean up
9166  delete[] dim_recv;
9167  }
9168  // "else if": "else" for non-root; "if" for checking if current
9169  // (non-root) processor does not know nodal dimension and is therefore
9170  // about to receive it from root.
9171  else if (int_dim == -1)
9172  {
9173  MPI_Recv(
9174  &int_dim, 1, MPI_INT, 0, 0, Comm_pt->mpi_comm(), MPI_STATUS_IGNORE);
9175  }
9176  }
9177  }
9178 #endif
9179 
9180  // If int_dim if still -1 then no elements were found for this mesh, so it
9181  // has no nodal dimension.
9182  if (int_dim == -1) int_dim = 0;
9183 
9184  return unsigned(int_dim);
9185  }
unsigned nodal_dimension() const
Return the required Eulerian dimension of the nodes in this element.
Definition: elements.h:2484
unsigned nodal_dimension() const
Return number of nodal dimension in mesh.
Definition: mesh.cc:9055

References finite_element_pt(), i, nelement(), oomph::FiniteElement::nodal_dimension(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and p.

Referenced by oomph::LagrangeEnforcedFlowPreconditioner::set_meshes().

◆ node_pt() [1/2]

Node*& oomph::Mesh::node_pt ( const unsigned long &  n)
inline

Return pointer to global node n.

437  {
438  return Node_pt[n];
439  }

References n, and Node_pt.

Referenced by oomph::IMRByBDF::actions_after_timestep(), oomph::RefineableTetgenMesh< ELEMENT >::adapt(), oomph::RefineableGmshTetMesh< ELEMENT >::adapt(), oomph::TreeBasedRefineableMeshBase::adapt_mesh(), oomph::PeriodicOrbitAssemblyHandler< NNODE_1D >::adapt_temporal_mesh(), add_boundary_node(), STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_mesh(), add_node_pt(), oomph::StreamfunctionProblem::assign_velocities(), oomph::SolidICProblem::backup_original_state(), oomph::MeshAsGeomObject::build_it(), oomph::ExtrudedCubeMeshFromQuadMesh< ELEMENT >::build_mesh(), check_for_repeated_nodes(), oomph::TriangleScaffoldMesh::check_mesh_integrity(), oomph::MyProblem::check_not_segregated(), oomph::CollapsibleChannelMesh< ELEMENT >::CollapsibleChannelMesh(), InclinedPlaneProblem< ELEMENT, INTERFACE_ELEMENT >::complete_build(), oomph::TreeBasedRefineableMeshBase::complete_hanging_nodes(), oomph::AddedMainNumberingLookup::construct_added_to_main_mapping(), convert_to_boundary_node(), oomph::Problem::copy(), copy_boundary_node_data_from_nodes(), MeshDeformation::deform_mesh(), delete_all_external_storage(), oomph::FSI_functions::doc_fsi(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::doc_solution(), oomph::EighthSphereMesh< ELEMENT >::EighthSphereMesh(), oomph::FSIDrivenCavityMesh< ELEMENT >::FSIDrivenCavityMesh(), oomph::FullCircleMesh< ELEMENT >::FullCircleMesh(), oomph::Problem::get_dofs(), oomph::Z2ErrorEstimator::get_element_errors(), NodeReordering::get_node_reordering(), get_node_reordering(), get_some_non_boundary_node(), main(), oomph::MyProblem::my_set_initial_condition(), oomph::MacroElementNodeUpdateMesh::node_update(), node_update(), PolarNSProblem< ELEMENT >::output_streamfunction(), oomph::TreeBasedRefineableMeshBase::p_adapt_mesh(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::pin_all(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::pin_dofs_of_coordinate(), oomph::StreamfunctionProblem::pin_velocities(), oomph::MGSolver< DIM >::plot(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::project(), PseudoSolidCapProblem< ELEMENT >::PseudoSolidCapProblem(), oomph::QuarterTubeMesh< ELEMENT >::QuarterTubeMesh(), read(), oomph::VorticitySmoother< ELEMENT >::recover_vorticity(), oomph::TreeBasedRefineableMeshBase::refine_as_in_reference_mesh(), remove_boundary_node(), reorder_nodes(), NodeReordering::reorder_nodes(), oomph::SolidICProblem::reset_original_state(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::reset_pin_status(), oomph::NavierStokesSchurComplementPreconditioner::reset_pin_status(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::restore_positions(), run_navier_stokes_outflow(), scale_mesh(), oomph::MyProblem::segregated_pin_indices(), oomph::Problem::set_dofs(), oomph::SolidICProblem::set_newmark_initial_condition_consistently(), oomph::Problem::set_pinned_values_to_zero(), oomph::MGSolver< DIM >::set_self_test_vector(), oomph::MyProblem::set_up_impulsive_initial_condition(), oomph::MGSolver< DIM >::setup_interpolation_matrices_unstructured(), oomph::HelmholtzMGPreconditioner< DIM >::setup_interpolation_matrices_unstructured(), oomph::SolidICProblem::setup_problem(), oomph::SimpleCubicScaffoldTetMesh::SimpleCubicScaffoldTetMesh(), oomph::TetMeshBase::snap_nodes_onto_geometric_objects(), ABCProblem< ELEMENT, TIMESTEPPERT >::solve(), oomph::MGSolver< DIM >::solve(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::store_positions(), oomph::TubeMesh< ELEMENT >::TubeMesh(), oomph::MyProblem::undo_segregated_pinning(), oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::unpin_all(), and oomph::ProjectionProblem< PROJECTABLE_ELEMENT >::unpin_dofs_of_coordinate().

◆ node_pt() [2/2]

Node* oomph::Mesh::node_pt ( const unsigned long &  n) const
inline

Return pointer to global node n (const version)

443  {
444  return Node_pt[n];
445  }

References n, and Node_pt.

◆ node_update()

void oomph::Mesh::node_update ( const bool update_all_solid_nodes = false)
virtual

Update nodal positions in response to changes in the domain shape. Uses the FiniteElement::get_x(...) function for FiniteElements and doesn't do anything for other element types. If a MacroElement pointer has been set for a FiniteElement, the MacroElement representation is used to update the nodal positions; if not get_x(...) uses the FE interpolation and thus leaves the nodal positions unchanged. Virtual, so it can be overloaded by specific meshes, such as AlgebraicMeshes or SpineMeshes. Generally, this function updates the position of all nodes in response to changes in the boundary position. However, we ignore all SolidNodes since their position is computed as part of the solution – unless the bool flag is set to true. Such calls are typically made when the initial mesh is created and/or after a mesh has been refined repeatedly before the start of the computation.

Update nodal positions in response to changes in the domain shape. Uses the FiniteElement::get_x(...) function for FiniteElements and doesn't do anything for other element types. If a MacroElement pointer has been set for a FiniteElement, the MacroElement representation is used to update the nodal positions; if not get_x(...) uses the FE interpolation and thus leaves the nodal positions unchanged. Virtual, so it can be overloaded by specific meshes, such as AlgebraicMeshes or SpineMeshes. Generally, this function updates the position of all nodes in response to changes in the boundary position. For SolidNodes it only applies the update to those SolidNodes whose position is determined by the boundary position, unless the bool flag is set to true.

Local and global (Eulerian) coordinate

Reimplemented in oomph::AlgebraicRefineableQuarterTubeMesh< ELEMENT >, oomph::MacroElementNodeUpdateRefineableQuarterTubeMesh< ELEMENT >, oomph::AlgebraicRefineableQuarterCircleSectorMesh< ELEMENT >, oomph::AlgebraicRefineableQuarterCircleSectorMesh< FLUID_ELEMENT >, oomph::MacroElementNodeUpdateRefineableQuarterCircleSectorMesh< ELEMENT >, oomph::AlgebraicRefineableFishMesh< ELEMENT >, oomph::AlgebraicFishMesh< ELEMENT >, oomph::MacroElementNodeUpdateRefineableFishMesh< ELEMENT >, oomph::SpineMesh, oomph::MacroElementNodeUpdateMesh, oomph::AlgebraicMesh, and oomph::PerturbedSpineMesh.

288  {
289  // Get the current time
290  double t_start = TimingHelpers::timer();
291 
292 #ifdef PARANOID
293 #ifdef OOMPH_HAS_MPI
294  // Paranoid check to throw an error if node update is called for elements
295  // with nonuniformly spaced nodes for which some masters are 'external'
296  for (unsigned long n = 0; n < nnode(); n++)
297  {
298  Node* nod_pt = Node_pt[n];
299  if (nod_pt->is_hanging())
300  {
301  // Loop over master nodes
302  unsigned nmaster = nod_pt->hanging_pt()->nmaster();
303  for (unsigned imaster = 0; imaster < nmaster; imaster++)
304  {
305  // Get pointer to master node
306  Node* master_nod_pt = nod_pt->hanging_pt()->master_node_pt(imaster);
307 
308  // Get vector of all external halo nodes
309  Vector<Node*> external_halo_node_pt;
310  get_external_halo_node_pt(external_halo_node_pt);
311 
312  // Search the external halo storage for this node
313  Vector<Node*>::iterator it = std::find(external_halo_node_pt.begin(),
314  external_halo_node_pt.end(),
315  master_nod_pt);
316 
317  // Check if the node was found
318  if (it != external_halo_node_pt.end())
319  {
320  // Throw error becase node update won't work
321  // It's ok to throw an error here because this function is
322  // overloaded for Algebraic and MacroElementNodeUpdate
323  // Meshes. This is only a problem for meshes of ordinary
324  // nodes.
325  std::ostringstream err_stream;
326 
327  err_stream << "Calling node_update() for a mesh which contains"
328  << std::endl
329  << "master nodes which live in the external storage."
330  << std::endl
331  << "These nodes do not belong to elements on this"
332  << std::endl
333  << "processor and therefore cannot be updated locally."
334  << std::endl;
335 
336  throw OomphLibError(err_stream.str(),
339  }
340  }
341  }
342  }
343  // If we get to here then none of the masters of any of the nodes in the
344  // mesh live in the external storage, so we'll be fine if we carry on.
345 #endif
346 #endif
347 
349  Vector<double> s;
350  Vector<double> r;
351 
352  // NB: This repeats nodes a lot - surely it would be
353  // quicker to modify it so that it only does each node once,
354  // particularly in the update_all_solid_nodes=true case?
355  // Create a map to indicate whether or not we've updated a node already
356  std::map<Node*, bool> has_node_been_updated;
357 
358  // How many nodes are there?
359  unsigned n_node = nnode();
360 
361  // Loop over all Nodes
362  for (unsigned n = 0; n < n_node; n++)
363  {
364  // Get pointer to node
365  Node* nod_pt = node_pt(n);
366 
367  // Initialise the boolean value associated with this node
368  has_node_been_updated[nod_pt] = false;
369  }
370 
371  // Loop over all elements
372  unsigned nel = nelement();
373  for (unsigned e = 0; e < nel; e++)
374  {
375  // Try to cast to FiniteElement
376  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(element_pt(e));
377 
378  // If it's a finite element we can proceed: FiniteElements have
379  // nodes and a get_x() function
380  if (el_pt != 0)
381  {
382  // Find out dimension of element = number of local coordinates
383  unsigned ndim_el = el_pt->dim();
384  s.resize(ndim_el);
385 
386  // Loop over nodal points
387  unsigned n_node = el_pt->nnode();
388  for (unsigned j = 0; j < n_node; j++)
389  {
390  // Get pointer to node
391  Node* nod_pt = el_pt->node_pt(j);
392 
393  // Get spatial dimension of node
394  unsigned ndim_node = nod_pt->ndim();
395  r.resize(ndim_node);
396 
397  // For non-hanging nodes
398  if (!(nod_pt->is_hanging()))
399  {
400  // If we've not dealt with this Node yet
401  if (!has_node_been_updated[nod_pt])
402  {
403  // Get the position of the node
404  el_pt->local_coordinate_of_node(j, s);
405 
406  // Get new position
407  el_pt->get_x(s, r);
408 
409  // Try to cast to SolidNode
410  SolidNode* solid_node_pt = dynamic_cast<SolidNode*>(nod_pt);
411 
412  // Loop over coordinate directions
413  for (unsigned i = 0; i < ndim_node; i++)
414  {
415  // It's a SolidNode:
416  if (solid_node_pt != 0)
417  {
418  // only do it if explicitly requested!
419  if (update_all_solid_nodes)
420  {
421  solid_node_pt->x(i) = r[i];
422  }
423  }
424  // Not a SolidNode: Definitely update
425  else
426  {
427  nod_pt->x(i) = r[i];
428  }
429  }
430 
431  // Indicate that we're done with this node, regardless of whether
432  // or not it even needed updating
433  has_node_been_updated[nod_pt] = true;
434  } // if (!has_node_been_updated[nod_pt])
435  } // if (!(nod_pt->is_hanging()))
436  } // for (unsigned j=0;j<n_node;j++)
437  } // if (el_pt!=0)
438  } // for (unsigned e=0;e<nel;e++)
439 
440  // Now update the external halo nodes before we adjust the positions of the
441  // hanging nodes incase any are masters of local nodes
442 #ifdef OOMPH_HAS_MPI
443  // Loop over all external halo nodes with other processors
444  // and update them
445  for (std::map<unsigned, Vector<Node*>>::iterator it =
446  External_halo_node_pt.begin();
447  it != External_halo_node_pt.end();
448  it++)
449  {
450  // Get vector of external halo nodes
451  Vector<Node*> ext_halo_node_pt = (*it).second;
452  unsigned nnod = ext_halo_node_pt.size();
453  for (unsigned j = 0; j < nnod; j++)
454  {
455  ext_halo_node_pt[j]->node_update();
456  }
457  }
458 #endif
459 
460  // Now loop over hanging nodes and adjust their position
461  // in line with their hanging node constraints
462  for (unsigned long n = 0; n < n_node; n++)
463  {
464  Node* nod_pt = Node_pt[n];
465  if (nod_pt->is_hanging())
466  {
467  // Get spatial dimension of node
468  unsigned ndim_node = nod_pt->ndim();
469 
470  // Initialise
471  for (unsigned i = 0; i < ndim_node; i++)
472  {
473  nod_pt->x(i) = 0.0;
474  }
475 
476  // Loop over master nodes
477  unsigned nmaster = nod_pt->hanging_pt()->nmaster();
478  for (unsigned imaster = 0; imaster < nmaster; imaster++)
479  {
480  // Loop over directions
481  for (unsigned i = 0; i < ndim_node; i++)
482  {
483  nod_pt->x(i) +=
484  nod_pt->hanging_pt()->master_node_pt(imaster)->x(i) *
485  nod_pt->hanging_pt()->master_weight(imaster);
486  }
487  }
488  }
489  }
490 
491  // Loop over all nodes again and execute auxiliary node update
492  // function
493  for (unsigned long n = 0; n < n_node; n++)
494  {
495  Node_pt[n]->perform_auxiliary_node_update_fct();
496  }
497 
498  // Tell the user how long it's taken
499  oomph_info << "Time taken to update nodal positions [sec]: "
500  << TimingHelpers::timer() - t_start << std::endl;
501  }
r
Definition: UniformPSDSelfTest.py:20
double timer()
returns the time in seconds after some point in past
Definition: oomph_utilities.cc:1295

References oomph::FiniteElement::dim(), e(), element_pt(), oomph::FiniteElement::get_x(), oomph::Node::hanging_pt(), i, oomph::Node::is_hanging(), j, oomph::FiniteElement::local_coordinate_of_node(), oomph::HangInfo::master_node_pt(), oomph::HangInfo::master_weight(), n, oomph::Node::ndim(), nelement(), oomph::HangInfo::nmaster(), oomph::FiniteElement::nnode(), nnode(), oomph::FiniteElement::node_pt(), Node_pt, node_pt(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, UniformPSDSelfTest::r, s, oomph::TimingHelpers::timer(), and oomph::Node::x().

Referenced by oomph::AlgebraicCollapsibleChannelMesh< ELEMENT >::AlgebraicCollapsibleChannelMesh(), oomph::ChannelWithLeafletMesh< ELEMENT >::ChannelWithLeafletMesh(), oomph::CollapsibleChannelMesh< ELEMENT >::CollapsibleChannelMesh(), oomph::SegregatableFSIProblem::extrapolate_solid_data(), oomph::MyAlgebraicCollapsibleChannelMesh< ELEMENT >::MyAlgebraicCollapsibleChannelMesh(), oomph::PseudoElasticChannelWithLeafletMesh< ELEMENT >::PseudoElasticChannelWithLeafletMesh(), oomph::QuarterPipeMesh< ELEMENT >::QuarterPipeMesh(), and oomph::RefineableTwoDAnnularMesh< ELEMENT >::RefineableTwoDAnnularMesh().

◆ operator=()

void oomph::Mesh::operator= ( const Mesh )
delete

Broken assignment operator.

◆ output() [1/6]

void oomph::Mesh::output ( const std::string &  output_filename)
inline

Output for all elements.

976  {
977  std::ofstream outfile;
978  outfile.open(output_filename.c_str());
979  output(outfile);
980  outfile.close();
981  }
void output(std::ostream &outfile)
Output for all elements.
Definition: mesh.cc:2027

References output().

◆ output() [2/6]

void oomph::Mesh::output ( const std::string &  output_filename,
const unsigned n_plot 
)
inline

Output at f(n_plot) points in each element.

985  {
986  std::ofstream outfile;
987  outfile.open(output_filename.c_str());
988  output(outfile, n_plot);
989  outfile.close();
990  }

References output().

◆ output() [3/6]

void oomph::Mesh::output ( FILE *  file_pt)

Output for all elements (C-style output)

Output function for the mesh class

Loop over all elements and plot (i.e. execute the element's own output() function) (C style output)

2114  {
2115  // Loop over the elements and call their output functions
2116  // Assign Element_pt_range
2117  unsigned long Element_pt_range = Element_pt.size();
2118  for (unsigned long e = 0; e < Element_pt_range; e++)
2119  {
2120  // Try to cast to FiniteElement
2121  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
2122  if (el_pt == 0)
2123  {
2124  oomph_info << "Can't execute output(...) for non FiniteElements"
2125  << std::endl;
2126  }
2127  else
2128  {
2129 #ifdef OOMPH_HAS_MPI
2130  if (Output_halo_elements)
2131 #endif
2132  {
2133  el_pt->output(file_pt);
2134  }
2135 #ifdef OOMPH_HAS_MPI
2136  else
2137  {
2138  if (!el_pt->is_halo())
2139  {
2140  el_pt->output(file_pt);
2141  }
2142  }
2143 #endif
2144  }
2145  }
2146  }

References e(), Element_pt, oomph::oomph_info, and oomph::FiniteElement::output().

◆ output() [4/6]

void oomph::Mesh::output ( FILE *  file_pt,
const unsigned n_plot 
)

Output at f(n_plot) points in each element (C-style output)

Output function for the mesh class

Loop over all elements and plot (i.e. execute the element's own output() function). Use n_plot plot points in each coordinate direction. (C style output)

2157  {
2158  // Loop over the elements and call their output functions
2159  // Assign Element_pt_range
2160  unsigned long Element_pt_range = Element_pt.size();
2161  for (unsigned long e = 0; e < Element_pt_range; e++)
2162  {
2163  // Try to cast to FiniteElement
2164  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
2165  if (el_pt == 0)
2166  {
2167  oomph_info << "Can't execute output(...) for non FiniteElements"
2168  << std::endl;
2169  }
2170  else
2171  {
2172 #ifdef OOMPH_HAS_MPI
2173  if (Output_halo_elements)
2174 #endif
2175  {
2176  el_pt->output(file_pt, n_plot);
2177  }
2178 #ifdef OOMPH_HAS_MPI
2179  else
2180  {
2181  if (!el_pt->is_halo())
2182  {
2183  el_pt->output(file_pt, n_plot);
2184  }
2185  }
2186 #endif
2187  }
2188  }
2189  }

References e(), Element_pt, oomph::oomph_info, and oomph::FiniteElement::output().

◆ output() [5/6]

void oomph::Mesh::output ( std::ostream &  outfile)

Output for all elements.

Output function for the mesh class

Loop over all elements and plot (i.e. execute the element's own output() function)

2028  {
2029  // Loop over the elements and call their output functions
2030  // Assign Element_pt_range
2031  unsigned long Element_pt_range = Element_pt.size();
2032  for (unsigned long e = 0; e < Element_pt_range; e++)
2033  {
2034  // Try to cast to FiniteElement
2035  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
2036  if (el_pt == 0)
2037  {
2038  oomph_info << "Can't execute output(...) for non FiniteElements"
2039  << std::endl;
2040  }
2041  else
2042  {
2043 #ifdef OOMPH_HAS_MPI
2044  if (Output_halo_elements)
2045 #endif
2046  {
2047  el_pt->output(outfile);
2048  }
2049 #ifdef OOMPH_HAS_MPI
2050  else
2051  {
2052  if (!el_pt->is_halo())
2053  {
2054  el_pt->output(outfile);
2055  }
2056  }
2057 #endif
2058  }
2059  }
2060  }

References e(), Element_pt, oomph::oomph_info, and oomph::FiniteElement::output().

Referenced by ContactProblem< ELEMENT >::actions_after_adapt(), ContactProblem< ELEMENT >::actions_before_adapt(), oomph::RefineableTetgenMesh< ELEMENT >::adapt(), demo_smoothing_with_linear_elasticity(), demo_smoothing_with_nonlinear_elasticity(), demo_smoothing_with_poisson(), oomph::FSI_functions::doc_fsi(), oomph::StreamfunctionProblem::doc_solution(), oomph::NonLinearElasticitySmoothMesh< ELEMENT >::doc_solution(), oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::doc_solution(), doc_sparse_node_update(), main(), output(), output_both_versions(), oomph::MeshAsGeomObject::position(), and oomph::TreeBasedRefineableMeshBase::refine_as_in_reference_mesh().

◆ output() [6/6]

void oomph::Mesh::output ( std::ostream &  outfile,
const unsigned n_plot 
)

Output at f(n_plot) points in each element.

Output function for the mesh class

Loop over all elements and plot (i.e. execute the element's own output() function). Use n_plot plot points in each coordinate direction.

2070  {
2071  // Loop over the elements and call their output functions
2072  // Assign Element_pt_range
2073  unsigned long Element_pt_range = Element_pt.size();
2074 
2075  for (unsigned long e = 0; e < Element_pt_range; e++)
2076  {
2077  // Try to cast to FiniteElement
2078  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
2079  if (el_pt == 0)
2080  {
2081  oomph_info << "Can't execute output(...) for non FiniteElements"
2082  << std::endl;
2083  }
2084  else
2085  {
2086 #ifdef OOMPH_HAS_MPI
2087  if (Output_halo_elements)
2088 #endif
2089  {
2090  el_pt->output(outfile, n_plot);
2091  }
2092 #ifdef OOMPH_HAS_MPI
2093  else
2094  {
2095  if (!el_pt->is_halo())
2096  {
2097  el_pt->output(outfile, n_plot);
2098  }
2099  }
2100 #endif
2101  }
2102  }
2103  }

References e(), Element_pt, oomph::oomph_info, and oomph::FiniteElement::output().

◆ output_boundaries() [1/2]

void oomph::Mesh::output_boundaries ( const std::string &  output_filename)
inline

Output the nodes on the boundaries (into separate tecplot zones). Specify filename

1010  {
1011  std::ofstream outfile;
1012  outfile.open(output_filename.c_str());
1013  output_boundaries(outfile);
1014  outfile.close();
1015  }
void output_boundaries(std::ostream &outfile)
Output the nodes on the boundaries (into separate tecplot zones)
Definition: mesh.cc:1064

References output_boundaries().

◆ output_boundaries() [2/2]

void oomph::Mesh::output_boundaries ( std::ostream &  outfile)

Output the nodes on the boundaries (into separate tecplot zones)

Output function for the mesh boundaries

Loop over all boundaries and dump out the coordinates of the points on the boundary (in individual tecplot zones)

1065  {
1066  // Loop over the boundaries
1067  unsigned num_bound = nboundary();
1068  for (unsigned long ibound = 0; ibound < num_bound; ibound++)
1069  {
1070  unsigned nnod = Boundary_node_pt[ibound].size();
1071  if (nnod > 0)
1072  {
1073  outfile << "ZONE T=\"boundary" << ibound << "\"\n";
1074 
1075  for (unsigned inod = 0; inod < nnod; inod++)
1076  {
1077  Boundary_node_pt[ibound][inod]->output(outfile);
1078  }
1079  }
1080  }
1081  }

References Boundary_node_pt, and nboundary().

Referenced by output_boundaries().

◆ output_fct() [1/2]

void oomph::Mesh::output_fct ( std::ostream &  outfile,
const unsigned n_plot,
const double time,
FiniteElement::UnsteadyExactSolutionFctPt  exact_soln_pt 
)

Output a given time-dep. Vector function at f(n_plot) points in each element

Output function for the mesh class

Loop over all elements and plot (i.e. execute the element's own output() function) at time t. Use n_plot plot points in each coordinate direction.

2247  {
2248  // Loop over the elements and call their output functions
2249  // Assign Element_pt_range
2250  unsigned long Element_pt_range = Element_pt.size();
2251  for (unsigned long e = 0; e < Element_pt_range; e++)
2252  {
2253  // Try to cast to FiniteElement
2254  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
2255  if (el_pt == 0)
2256  {
2257  oomph_info << "Can't execute output_fct(...) for non FiniteElements"
2258  << std::endl;
2259  }
2260  else
2261  {
2262 #ifdef OOMPH_HAS_MPI
2263  if (Output_halo_elements)
2264 #endif
2265  {
2266  el_pt->output_fct(outfile, n_plot, time, exact_soln_pt);
2267  }
2268 #ifdef OOMPH_HAS_MPI
2269  else
2270  {
2271  if (!el_pt->is_halo())
2272  {
2273  el_pt->output_fct(outfile, n_plot, time, exact_soln_pt);
2274  }
2275  }
2276 #endif
2277  }
2278  }
2279  }

References e(), Element_pt, oomph::oomph_info, and oomph::FiniteElement::output_fct().

◆ output_fct() [2/2]

void oomph::Mesh::output_fct ( std::ostream &  outfile,
const unsigned n_plot,
FiniteElement::SteadyExactSolutionFctPt  exact_soln_pt 
)

Output a given Vector function at f(n_plot) points in each element.

Output function for the mesh class

Loop over all elements and plot (i.e. execute the element's own output() function). Use n_plot plot points in each coordinate direction.

2202  {
2203  // Loop over the elements and call their output functions
2204  // Assign Element_pt_range
2205  unsigned long Element_pt_range = Element_pt.size();
2206  for (unsigned long e = 0; e < Element_pt_range; e++)
2207  {
2208  // Try to cast to FiniteElement
2209  FiniteElement* el_pt = dynamic_cast<FiniteElement*>(Element_pt[e]);
2210  if (el_pt == 0)
2211  {
2212  oomph_info << "Can't execute output_fct(...) for non FiniteElements"
2213  << std::endl;
2214  }
2215  else
2216  {
2217 #ifdef OOMPH_HAS_MPI
2218  if (Output_halo_elements)
2219 #endif
2220  {
2221  el_pt->output_fct(outfile, n_plot, exact_soln_pt);
2222  }
2223 #ifdef OOMPH_HAS_MPI
2224  else
2225  {
2226  if (!el_pt->is_halo())
2227  {
2228  el_pt->output_fct(outfile, n_plot, exact_soln_pt);
2229  }
2230  }
2231 #endif
2232  }
2233  }
2234  }

References e(), Element_pt, oomph::oomph_info, and oomph::FiniteElement::output_fct().

Referenced by oomph::FpPressureAdvectionDiffusionProblem< ELEMENT >::doc_solution().

◆ output_fct_paraview() [1/2]

void oomph::Mesh::output_fct_paraview ( std::ofstream &  file_out,
const unsigned nplot,
const double time,
FiniteElement::UnsteadyExactSolutionFctPt  exact_soln_pt 
) const

Output in paraview format into specified file. Breaks up each element into sub-elements for plotting purposes. We assume that all elements are of the same type (fct will break break (in paranoid mode) if paraview output fcts of the elements are inconsistent).

Output in paraview format into specified file.

Breaks up each element into sub-elements for plotting purposes. We assume that all elements are of the same type (fct will break (in paranoid mode) if paraview output fcts of the elements are inconsistent).

1764  {
1765  // Change the scientific format so that E is used rather than e
1766  file_out.setf(std::ios_base::uppercase);
1767 
1768  // Decide how many elements there are to be plotted
1769  unsigned long number_of_elements = this->Element_pt.size();
1770 
1771  // Cast to finite element and return if cast fails.
1772  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(0));
1773 
1774 #ifdef PARANOID
1775  if (fe_pt == 0)
1776  {
1777  throw OomphLibError("Recast for FiniteElement failed for element 0!\n",
1780  }
1781 #endif
1782 
1783 
1784 #ifdef PARANOID
1785  // Check if all elements have the same number of degrees of freedom,
1786  // if they don't, paraview will break
1787  unsigned el_zero_ndof = fe_pt->nscalar_paraview();
1788  for (unsigned i = 1; i < number_of_elements; i++)
1789  {
1790  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1791  unsigned el_i_ndof = fe_pt->nscalar_paraview();
1792  if (el_zero_ndof != el_i_ndof)
1793  {
1794  std::stringstream error_stream;
1795  error_stream
1796  << "Element " << i << " has different number of degrees of freedom\n"
1797  << "than from previous elements, Paraview cannot handle this.\n"
1798  << "We suggest that the problem is broken up into submeshes instead."
1799  << std::endl;
1800  throw OomphLibError(
1801  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1802  }
1803  }
1804 #endif
1805 
1806  // Make variables to hold the number of nodes and elements
1807  unsigned long number_of_nodes = 0;
1808  unsigned long total_number_of_elements = 0;
1809 
1810  // Loop over all the elements to find total number of plot points
1811  for (unsigned i = 0; i < number_of_elements; i++)
1812  {
1813  // Cast to FiniteElement and (in paranoid mode) check
1814  // if cast has failed.
1815  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1816 
1817 #ifdef PARANOID
1818  if (fe_pt == 0)
1819  {
1820  std::stringstream error_stream;
1821  error_stream << "Recast for element " << i << " failed" << std::endl;
1822  throw OomphLibError(
1823  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1824  }
1825 #endif
1826 
1827  number_of_nodes += fe_pt->nplot_points_paraview(nplot);
1828  total_number_of_elements += fe_pt->nsub_elements_paraview(nplot);
1829  }
1830 
1831 
1832  // File Declaration
1833  //------------------
1834 
1835  // Insert the necessary lines plus header of file, and
1836  // number of nodes and elements
1837  file_out << "<?xml version=\"1.0\"?>\n"
1838  << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" "
1839  << "byte_order=\"LittleEndian\">\n"
1840  << "<UnstructuredGrid>\n"
1841  << "<Piece NumberOfPoints=\"" << number_of_nodes
1842  << "\" NumberOfCells=\"" << total_number_of_elements << "\">\n";
1843 
1844 
1845  // Point Data
1846  //-----------
1847 
1848  // Check the number of degrees of freedom
1849  unsigned ndof = fe_pt->nscalar_paraview();
1850 
1851  // Point data is going in here
1852  file_out << "<PointData ";
1853 
1854  // Insert just the first scalar name, since paraview reads everything
1855  // else after that as being of the same type. Get information from
1856  // first element.
1857  file_out << "Scalars=\"" << fe_pt->scalar_name_paraview(0) << "\">\n";
1858 
1859  // Loop over i scalar fields and j number of elements
1860  for (unsigned i = 0; i < ndof; i++)
1861  {
1862  file_out << "<DataArray type=\"Float32\" "
1863  << "Name=\"" << fe_pt->scalar_name_paraview(i) << "\" "
1864  << "format=\"ascii\""
1865  << ">\n";
1866 
1867  for (unsigned j = 0; j < number_of_elements; j++)
1868  {
1869  // Cast to FiniteElement and (in paranoid mode) check
1870  // if cast has failed.
1871  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(j));
1872 
1873 #ifdef PARANOID
1874  if (fe_pt == 0)
1875  {
1876  std::stringstream error_stream;
1877  error_stream << "Recast for element " << j << " failed" << std::endl;
1878  throw OomphLibError(error_stream.str(),
1881  }
1882 #endif
1883 
1884  fe_pt->scalar_value_fct_paraview(
1885  file_out, i, nplot, time, exact_soln_pt);
1886  }
1887 
1888  // Close of the DataArray
1889  file_out << "</DataArray>\n";
1890  }
1891 
1892  // Close off the PointData set
1893  file_out << "</PointData>\n";
1894 
1895 
1896  // Geometric Points
1897  //------------------
1898 
1899  file_out << "<Points>\n"
1900  << "<DataArray type=\"Float32\""
1901  << " NumberOfComponents=\""
1902  // This always has to be 3 for an unstructured grid
1903  << 3 << "\" "
1904  << "format=\"ascii\">\n";
1905 
1906  // Loop over all the elements to print their plot points
1907  for (unsigned i = 0; i < number_of_elements; i++)
1908  {
1909  // Cast to FiniteElement and (in paranoid mode) check
1910  // if cast has failed.
1911  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1912 
1913 #ifdef PARANOID
1914  if (fe_pt == 0)
1915  {
1916  std::stringstream error_stream;
1917  error_stream << "Recast for element " << i << " faild" << std::endl;
1918  throw OomphLibError(
1919  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1920  }
1921 #endif
1922 
1923  fe_pt->output_paraview(file_out, nplot);
1924  }
1925 
1926  file_out << "</DataArray>\n"
1927  << "</Points>\n";
1928 
1929 
1930  // Cells
1931  //-------
1932 
1933  file_out
1934  << "<Cells>\n"
1935  << "<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
1936 
1937  // Make counter for keeping track of all the local elements,
1938  // because Paraview requires global coordinates
1939  unsigned counter = 0;
1940 
1941  // Write connectivity with the local elements
1942  for (unsigned i = 0; i < number_of_elements; i++)
1943  {
1944  // Cast to FiniteElement and (in paranoid mode) check
1945  // if cast has failed.
1946  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1947 
1948 #ifdef PARANOID
1949  if (fe_pt == 0)
1950  {
1951  std::stringstream error_stream;
1952  error_stream << "Recast for element " << i << " faild" << std::endl;
1953  throw OomphLibError(
1954  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1955  }
1956 #endif
1957  fe_pt->write_paraview_output_offset_information(file_out, nplot, counter);
1958  }
1959 
1960  file_out << "</DataArray>\n"
1961  << "<DataArray type=\"Int32\" "
1962  << "Name=\"offsets\" format=\"ascii\">\n";
1963 
1964  // Make variable that holds the current offset number
1965  unsigned offset_sum = 0;
1966 
1967  // Write the offset for the specific elements
1968  for (unsigned i = 0; i < number_of_elements; i++)
1969  {
1970  // Cast to FiniteElement and (in paranoid mode) check
1971  // if cast has failed.
1972  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1973 
1974 #ifdef PARANOID
1975  if (fe_pt == 0)
1976  {
1977  std::stringstream error_stream;
1978  error_stream << "Recast for element " << i << " failed" << std::endl;
1979  throw OomphLibError(
1980  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1981  }
1982 #endif
1983  fe_pt->write_paraview_offsets(file_out, nplot, offset_sum);
1984  }
1985 
1986  file_out << "</DataArray>\n"
1987  << "<DataArray type=\"UInt8\" Name=\"types\">\n";
1988 
1989  // Loop over all elements to get the type that they have
1990  for (unsigned i = 0; i < number_of_elements; i++)
1991  {
1992  // Cast to FiniteElement and (in paranoid mode) check
1993  // if cast has failed.
1994  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1995 
1996 #ifdef PARANOID
1997  if (fe_pt == 0)
1998  {
1999  std::stringstream error_stream;
2000  error_stream << "Recast for element " << i << " failed" << std::endl;
2001  throw OomphLibError(
2002  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2003  }
2004 #endif
2005 
2006  fe_pt->write_paraview_type(file_out, nplot);
2007  }
2008 
2009  file_out << "</DataArray>\n"
2010  << "</Cells>\n";
2011 
2012 
2013  // File Closure
2014  //-------------
2015  file_out << "</Piece>\n"
2016  << "</UnstructuredGrid>\n"
2017  << "</VTKFile>";
2018  }

References Element_pt, element_pt(), i, j, oomph::FiniteElement::nplot_points_paraview(), oomph::FiniteElement::nscalar_paraview(), oomph::FiniteElement::nsub_elements_paraview(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::FiniteElement::output_paraview(), oomph::FiniteElement::scalar_name_paraview(), oomph::FiniteElement::scalar_value_fct_paraview(), oomph::FiniteElement::write_paraview_offsets(), oomph::FiniteElement::write_paraview_output_offset_information(), and oomph::FiniteElement::write_paraview_type().

◆ output_fct_paraview() [2/2]

void oomph::Mesh::output_fct_paraview ( std::ofstream &  file_out,
const unsigned nplot,
FiniteElement::SteadyExactSolutionFctPt  exact_soln_pt 
) const

Output in paraview format into specified file. Breaks up each element into sub-elements for plotting purposes. We assume that all elements are of the same type (fct will break break (in paranoid mode) if paraview output fcts of the elements are inconsistent).

Output in paraview format into specified file.

Breaks up each element into sub-elements for plotting purposes. We assume that all elements are of the same type (fct will break (in paranoid mode) if paraview output fcts of the elements are inconsistent).

1495  {
1496  // Change the scientific format so that E is used rather than e
1497  file_out.setf(std::ios_base::uppercase);
1498 
1499  // Decide how many elements there are to be plotted
1500  unsigned long number_of_elements = this->Element_pt.size();
1501 
1502  // Cast to finite element and return if cast fails.
1503  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(0));
1504 
1505 #ifdef PARANOID
1506  if (fe_pt == 0)
1507  {
1508  throw OomphLibError("Recast for FiniteElement failed for element 0!\n",
1511  }
1512 #endif
1513 
1514 
1515 #ifdef PARANOID
1516  // Check if all elements have the same number of degrees of freedom,
1517  // if they don't, paraview will break
1518  unsigned el_zero_ndof = fe_pt->nscalar_paraview();
1519  for (unsigned i = 1; i < number_of_elements; i++)
1520  {
1521  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1522  unsigned el_i_ndof = fe_pt->nscalar_paraview();
1523  if (el_zero_ndof != el_i_ndof)
1524  {
1525  std::stringstream error_stream;
1526  error_stream
1527  << "Element " << i << " has different number of degrees of freedom\n"
1528  << "than from previous elements, Paraview cannot handle this.\n"
1529  << "We suggest that the problem is broken up into submeshes instead."
1530  << std::endl;
1531  throw OomphLibError(
1532  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1533  }
1534  }
1535 #endif
1536 
1537  // Make variables to hold the number of nodes and elements
1538  unsigned long number_of_nodes = 0;
1539  unsigned long total_number_of_elements = 0;
1540 
1541  // Loop over all the elements to find total number of plot points
1542  for (unsigned i = 0; i < number_of_elements; i++)
1543  {
1544  // Cast to FiniteElement and (in paranoid mode) check
1545  // if cast has failed.
1546  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1547 
1548 #ifdef PARANOID
1549  if (fe_pt == 0)
1550  {
1551  std::stringstream error_stream;
1552  error_stream << "Recast for element " << i << " failed" << std::endl;
1553  throw OomphLibError(
1554  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1555  }
1556 #endif
1557 
1558  number_of_nodes += fe_pt->nplot_points_paraview(nplot);
1559  total_number_of_elements += fe_pt->nsub_elements_paraview(nplot);
1560  }
1561 
1562 
1563  // File Declaration
1564  //------------------
1565 
1566  // Insert the necessary lines plus header of file, and
1567  // number of nodes and elements
1568  file_out << "<?xml version=\"1.0\"?>\n"
1569  << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" "
1570  << "byte_order=\"LittleEndian\">\n"
1571  << "<UnstructuredGrid>\n"
1572  << "<Piece NumberOfPoints=\"" << number_of_nodes
1573  << "\" NumberOfCells=\"" << total_number_of_elements << "\">\n";
1574 
1575 
1576  // Point Data
1577  //-----------
1578 
1579  // Check the number of degrees of freedom
1580  unsigned ndof = fe_pt->nscalar_paraview();
1581 
1582  // Point data is going in here
1583  file_out << "<PointData ";
1584 
1585  // Insert just the first scalar name, since paraview reads everything
1586  // else after that as being of the same type. Get information from
1587  // first element.
1588  file_out << "Scalars=\"" << fe_pt->scalar_name_paraview(0) << "\">\n";
1589 
1590  // Loop over i scalar fields and j number of elements
1591  for (unsigned i = 0; i < ndof; i++)
1592  {
1593  file_out << "<DataArray type=\"Float32\" "
1594  << "Name=\"" << fe_pt->scalar_name_paraview(i) << "\" "
1595  << "format=\"ascii\""
1596  << ">\n";
1597 
1598  for (unsigned j = 0; j < number_of_elements; j++)
1599  {
1600  // Cast to FiniteElement and (in paranoid mode) check
1601  // if cast has failed.
1602  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(j));
1603 
1604 #ifdef PARANOID
1605  if (fe_pt == 0)
1606  {
1607  std::stringstream error_stream;
1608  error_stream << "Recast for element " << j << " failed" << std::endl;
1609  throw OomphLibError(error_stream.str(),
1612  }
1613 #endif
1614 
1615  fe_pt->scalar_value_fct_paraview(file_out, i, nplot, exact_soln_pt);
1616  }
1617 
1618  // Close of the DataArray
1619  file_out << "</DataArray>\n";
1620  }
1621 
1622  // Close off the PointData set
1623  file_out << "</PointData>\n";
1624 
1625 
1626  // Geometric Points
1627  //------------------
1628 
1629  file_out << "<Points>\n"
1630  << "<DataArray type=\"Float32\""
1631  << " NumberOfComponents=\""
1632  // This always has to be 3 for an unstructured grid
1633  << 3 << "\" "
1634  << "format=\"ascii\">\n";
1635 
1636  // Loop over all the elements to print their plot points
1637  for (unsigned i = 0; i < number_of_elements; i++)
1638  {
1639  // Cast to FiniteElement and (in paranoid mode) check
1640  // if cast has failed.
1641  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1642 
1643 #ifdef PARANOID
1644  if (fe_pt == 0)
1645  {
1646  std::stringstream error_stream;
1647  error_stream << "Recast for element " << i << " faild" << std::endl;
1648  throw OomphLibError(
1649  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1650  }
1651 #endif
1652 
1653  fe_pt->output_paraview(file_out, nplot);
1654  }
1655 
1656  file_out << "</DataArray>\n"
1657  << "</Points>\n";
1658 
1659 
1660  // Cells
1661  //-------
1662 
1663  file_out
1664  << "<Cells>\n"
1665  << "<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
1666 
1667  // Make counter for keeping track of all the local elements,
1668  // because Paraview requires global coordinates
1669  unsigned counter = 0;
1670 
1671  // Write connectivity with the local elements
1672  for (unsigned i = 0; i < number_of_elements; i++)
1673  {
1674  // Cast to FiniteElement and (in paranoid mode) check
1675  // if cast has failed.
1676  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1677 
1678 #ifdef PARANOID
1679  if (fe_pt == 0)
1680  {
1681  std::stringstream error_stream;
1682  error_stream << "Recast for element " << i << " faild" << std::endl;
1683  throw OomphLibError(
1684  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1685  }
1686 #endif
1687  fe_pt->write_paraview_output_offset_information(file_out, nplot, counter);
1688  }
1689 
1690  file_out << "</DataArray>\n"
1691  << "<DataArray type=\"Int32\" "
1692  << "Name=\"offsets\" format=\"ascii\">\n";
1693 
1694  // Make variable that holds the current offset number
1695  unsigned offset_sum = 0;
1696 
1697  // Write the offset for the specific elements
1698  for (unsigned i = 0; i < number_of_elements; i++)
1699  {
1700  // Cast to FiniteElement and (in paranoid mode) check
1701  // if cast has failed.
1702  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1703 
1704 #ifdef PARANOID
1705  if (fe_pt == 0)
1706  {
1707  std::stringstream error_stream;
1708  error_stream << "Recast for element " << i << " failed" << std::endl;
1709  throw OomphLibError(
1710  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1711  }
1712 #endif
1713  fe_pt->write_paraview_offsets(file_out, nplot, offset_sum);
1714  }
1715 
1716  file_out << "</DataArray>\n"
1717  << "<DataArray type=\"UInt8\" Name=\"types\">\n";
1718 
1719  // Loop over all elements to get the type that they have
1720  for (unsigned i = 0; i < number_of_elements; i++)
1721  {
1722  // Cast to FiniteElement and (in paranoid mode) check
1723  // if cast has failed.
1724  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1725 
1726 #ifdef PARANOID
1727  if (fe_pt == 0)
1728  {
1729  std::stringstream error_stream;
1730  error_stream << "Recast for element " << i << " failed" << std::endl;
1731  throw OomphLibError(
1732  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1733  }
1734 #endif
1735 
1736  fe_pt->write_paraview_type(file_out, nplot);
1737  }
1738 
1739  file_out << "</DataArray>\n"
1740  << "</Cells>\n";
1741 
1742 
1743  // File Closure
1744  //-------------
1745  file_out << "</Piece>\n"
1746  << "</UnstructuredGrid>\n"
1747  << "</VTKFile>";
1748  }

References Element_pt, element_pt(), i, j, oomph::FiniteElement::nplot_points_paraview(), oomph::FiniteElement::nscalar_paraview(), oomph::FiniteElement::nsub_elements_paraview(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::FiniteElement::output_paraview(), oomph::FiniteElement::scalar_name_paraview(), oomph::FiniteElement::scalar_value_fct_paraview(), oomph::FiniteElement::write_paraview_offsets(), oomph::FiniteElement::write_paraview_output_offset_information(), and oomph::FiniteElement::write_paraview_type().

◆ output_paraview()

void oomph::Mesh::output_paraview ( std::ofstream &  file_out,
const unsigned nplot 
) const

Output in paraview format into specified file. Breaks up each element into sub-elements for plotting purposes. We assume that all elements are of the same type (fct will break break (in paranoid mode) if paraview output fcts of the elements are inconsistent).

Output in paraview format into specified file.

Breaks up each element into sub-elements for plotting purposes. We assume that all elements are of the same type (fct will break (in paranoid mode) if paraview output fcts of the elements are inconsistent).

1227  {
1228  // Change the scientific format so that E is used rather than e
1229  file_out.setf(std::ios_base::uppercase);
1230 
1231  // Decide how many elements there are to be plotted
1232  unsigned long number_of_elements = this->Element_pt.size();
1233 
1234  // Cast to finite element and return if cast fails.
1235  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(0));
1236 
1237 #ifdef PARANOID
1238  if (fe_pt == 0)
1239  {
1240  throw OomphLibError("Recast for FiniteElement failed for element 0!\n",
1243  }
1244 #endif
1245 
1246 
1247 #ifdef PARANOID
1248  // Check if all elements have the same number of degrees of freedom,
1249  // if they don't, paraview will break
1250  unsigned el_zero_ndof = fe_pt->nscalar_paraview();
1251  for (unsigned i = 1; i < number_of_elements; i++)
1252  {
1253  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1254  unsigned el_i_ndof = fe_pt->nscalar_paraview();
1255  if (el_zero_ndof != el_i_ndof)
1256  {
1257  std::stringstream error_stream;
1258  error_stream
1259  << "Element " << i << " has different number of degrees of freedom\n"
1260  << "than from previous elements, Paraview cannot handle this.\n"
1261  << "We suggest that the problem is broken up into submeshes instead."
1262  << std::endl;
1263  throw OomphLibError(
1264  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1265  }
1266  }
1267 #endif
1268 
1269  // Make variables to hold the number of nodes and elements
1270  unsigned long number_of_nodes = 0;
1271  unsigned long total_number_of_elements = 0;
1272 
1273  // Loop over all the elements to find total number of plot points
1274  for (unsigned i = 0; i < number_of_elements; i++)
1275  {
1276  // Cast to FiniteElement and (in paranoid mode) check
1277  // if cast has failed.
1278  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1279 
1280 #ifdef PARANOID
1281  if (fe_pt == 0)
1282  {
1283  std::stringstream error_stream;
1284  error_stream << "Recast for element " << i << " failed" << std::endl;
1285  throw OomphLibError(
1286  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1287  }
1288 #endif
1289 
1290  number_of_nodes += fe_pt->nplot_points_paraview(nplot);
1291  total_number_of_elements += fe_pt->nsub_elements_paraview(nplot);
1292  }
1293 
1294 
1295  // File Declaration
1296  //------------------
1297 
1298  // Insert the necessary lines plus header of file, and
1299  // number of nodes and elements
1300  file_out << "<?xml version=\"1.0\"?>\n"
1301  << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" "
1302  << "byte_order=\"LittleEndian\">\n"
1303  << "<UnstructuredGrid>\n"
1304  << "<Piece NumberOfPoints=\"" << number_of_nodes
1305  << "\" NumberOfCells=\"" << total_number_of_elements << "\">\n";
1306 
1307 
1308  // Point Data
1309  //-----------
1310 
1311  // Check the number of degrees of freedom
1312  unsigned ndof = fe_pt->nscalar_paraview();
1313 
1314  // Point data is going in here
1315  file_out << "<PointData ";
1316 
1317  // Insert just the first scalar name, since paraview reads everything
1318  // else after that as being of the same type. Get information from
1319  // first element.
1320  file_out << "Scalars=\"" << fe_pt->scalar_name_paraview(0) << "\">\n";
1321 
1322  // Loop over i scalar fields and j number of elements
1323  for (unsigned i = 0; i < ndof; i++)
1324  {
1325  file_out << "<DataArray type=\"Float32\" "
1326  << "Name=\"" << fe_pt->scalar_name_paraview(i) << "\" "
1327  << "format=\"ascii\""
1328  << ">\n";
1329 
1330  for (unsigned j = 0; j < number_of_elements; j++)
1331  {
1332  // Cast to FiniteElement and (in paranoid mode) check
1333  // if cast has failed.
1334  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(j));
1335 
1336 #ifdef PARANOID
1337  if (fe_pt == 0)
1338  {
1339  std::stringstream error_stream;
1340  error_stream << "Recast for element " << j << " failed" << std::endl;
1341  throw OomphLibError(error_stream.str(),
1344  }
1345 #endif
1346 
1347  fe_pt->scalar_value_paraview(file_out, i, nplot);
1348  }
1349 
1350  // Close of the DataArray
1351  file_out << "</DataArray>\n";
1352  }
1353 
1354  // Close off the PointData set
1355  file_out << "</PointData>\n";
1356 
1357 
1358  // Geometric Points
1359  //------------------
1360 
1361  file_out << "<Points>\n"
1362  << "<DataArray type=\"Float32\""
1363  << " NumberOfComponents=\""
1364  // This always has to be 3 for an unstructured grid
1365  << 3 << "\" "
1366  << "format=\"ascii\">\n";
1367 
1368  // Loop over all the elements to print their plot points
1369  for (unsigned i = 0; i < number_of_elements; i++)
1370  {
1371  // Cast to FiniteElement and (in paranoid mode) check
1372  // if cast has failed.
1373  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1374 
1375 #ifdef PARANOID
1376  if (fe_pt == 0)
1377  {
1378  std::stringstream error_stream;
1379  error_stream << "Recast for element " << i << " faild" << std::endl;
1380  throw OomphLibError(
1381  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1382  }
1383 #endif
1384 
1385  fe_pt->output_paraview(file_out, nplot);
1386  }
1387 
1388  file_out << "</DataArray>\n"
1389  << "</Points>\n";
1390 
1391 
1392  // Cells
1393  //-------
1394 
1395  file_out
1396  << "<Cells>\n"
1397  << "<DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
1398 
1399  // Make counter for keeping track of all the local elements,
1400  // because Paraview requires global coordinates
1401  unsigned counter = 0;
1402 
1403  // Write connectivity with the local elements
1404  for (unsigned i = 0; i < number_of_elements; i++)
1405  {
1406  // Cast to FiniteElement and (in paranoid mode) check
1407  // if cast has failed.
1408  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1409 
1410 #ifdef PARANOID
1411  if (fe_pt == 0)
1412  {
1413  std::stringstream error_stream;
1414  error_stream << "Recast for element " << i << " faild" << std::endl;
1415  throw OomphLibError(
1416  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1417  }
1418 #endif
1419  fe_pt->write_paraview_output_offset_information(file_out, nplot, counter);
1420  }
1421 
1422  file_out << "</DataArray>\n"
1423  << "<DataArray type=\"Int32\" "
1424  << "Name=\"offsets\" format=\"ascii\">\n";
1425 
1426  // Make variable that holds the current offset number
1427  unsigned offset_sum = 0;
1428 
1429  // Write the offset for the specific elements
1430  for (unsigned i = 0; i < number_of_elements; i++)
1431  {
1432  // Cast to FiniteElement and (in paranoid mode) check
1433  // if cast has failed.
1434  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1435 
1436 #ifdef PARANOID
1437  if (fe_pt == 0)
1438  {
1439  std::stringstream error_stream;
1440  error_stream << "Recast for element " << i << " failed" << std::endl;
1441  throw OomphLibError(
1442  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1443  }
1444 #endif
1445  fe_pt->write_paraview_offsets(file_out, nplot, offset_sum);
1446  }
1447 
1448  file_out << "</DataArray>\n"
1449  << "<DataArray type=\"UInt8\" Name=\"types\">\n";
1450 
1451  // Loop over all elements to get the type that they have
1452  for (unsigned i = 0; i < number_of_elements; i++)
1453  {
1454  // Cast to FiniteElement and (in paranoid mode) check
1455  // if cast has failed.
1456  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(element_pt(i));
1457 
1458 #ifdef PARANOID
1459  if (fe_pt == 0)
1460  {
1461  std::stringstream error_stream;
1462  error_stream << "Recast for element " << i << " failed" << std::endl;
1463  throw OomphLibError(
1464  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1465  }
1466 #endif
1467 
1468  fe_pt->write_paraview_type(file_out, nplot);
1469  }
1470 
1471  file_out << "</DataArray>\n"
1472  << "</Cells>\n";
1473 
1474 
1475  // File Closure
1476  //-------------
1477  file_out << "</Piece>\n"
1478  << "</UnstructuredGrid>\n"
1479  << "</VTKFile>";
1480  }

References Element_pt, element_pt(), i, j, oomph::FiniteElement::nplot_points_paraview(), oomph::FiniteElement::nscalar_paraview(), oomph::FiniteElement::nsub_elements_paraview(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::FiniteElement::output_paraview(), oomph::FiniteElement::scalar_name_paraview(), oomph::FiniteElement::scalar_value_paraview(), oomph::FiniteElement::write_paraview_offsets(), oomph::FiniteElement::write_paraview_output_offset_information(), and oomph::FiniteElement::write_paraview_type().

◆ prune_dead_nodes()

Vector< Node * > oomph::Mesh::prune_dead_nodes ( )

Prune nodes. Nodes that have been marked as obsolete are removed from the mesh (and its boundary-node scheme). Returns vector of pointers to deleted nodes.

Nodes that have been marked as obsolete are removed from the mesh and the its boundaries. Returns vector of pointers to deleted nodes.

967  {
968  // Only copy the 'live' nodes across to new mesh
969  //----------------------------------------------
970 
971  // New Vector of pointers to nodes
972  Vector<Node*> new_node_pt;
973  Vector<Node*> deleted_node_pt;
974 
975  // Loop over all nodes in mesh
976  unsigned long n_node = nnode();
977  for (unsigned long n = 0; n < n_node; n++)
978  {
979  // If the node still exists: Copy across
980  if (!(Node_pt[n]->is_obsolete()))
981  {
982  new_node_pt.push_back(Node_pt[n]);
983  }
984  // Otherwise the Node is gone:
985  // Delete it for good if it does not lie on a boundary
986  // (if it lives on a boundary we have to remove it from
987  // the boundary lookup schemes below)
988  else
989  {
990  if (!(Node_pt[n]->is_on_boundary()))
991  {
992  deleted_node_pt.push_back(Node_pt[n]);
993  delete Node_pt[n];
994  Node_pt[n] = 0;
995  }
996  }
997  }
998 
999  // Now update old vector by setting it equal to the new vector
1000  Node_pt = new_node_pt;
1001 
1002 
1003  // Boundaries
1004  //-----------
1005 
1006  // Only copy the 'live' nodes into new boundary node arrays
1007  //---------------------------------------------------------
1008  // Loop over the boundaries
1009  unsigned num_bound = nboundary();
1010  for (unsigned ibound = 0; ibound < num_bound; ibound++)
1011  {
1012  // New Vector of pointers to existent boundary nodes
1013  Vector<Node*> new_boundary_node_pt;
1014 
1015  // Loop over the boundary nodes
1016  unsigned long Nboundary_node = Boundary_node_pt[ibound].size();
1017 
1018  // Reserve contiguous memory for new vector of pointers
1019  // Must be equal in size to the number of nodes or less
1020  new_boundary_node_pt.reserve(Nboundary_node);
1021 
1022  for (unsigned long n = 0; n < Nboundary_node; n++)
1023  {
1024  // If node still exists: Copy across
1025  if (!(Boundary_node_pt[ibound][n]->is_obsolete()))
1026  {
1027  new_boundary_node_pt.push_back(Boundary_node_pt[ibound][n]);
1028  }
1029  // Otherwise Node is gone: Delete it for good
1030  else
1031  {
1032  // The node may lie on multiple boundaries, so remove the node
1033  // from the current boundary
1034  Boundary_node_pt[ibound][n]->remove_from_boundary(ibound);
1035 
1036  // Now if the node is no longer on any boundaries, delete it
1037  if (!Boundary_node_pt[ibound][n]->is_on_boundary())
1038  {
1039  deleted_node_pt.push_back(
1040  dynamic_cast<Node*>(Boundary_node_pt[ibound][n]));
1041 
1042  delete Boundary_node_pt[ibound][n];
1043  }
1044  }
1045  }
1046 
1047  // Update the old vector by setting it equal to the new vector
1048  Boundary_node_pt[ibound] = new_boundary_node_pt;
1049 
1050  } // End of loop over boundaries
1051 
1052  // Tell us who you deleted
1053  return deleted_node_pt;
1054  }

References Boundary_node_pt, n, nboundary(), nnode(), and Node_pt.

Referenced by oomph::TreeBasedRefineableMeshBase::adapt_mesh(), oomph::TreeBasedRefineableMeshBase::p_adapt_mesh(), oomph::PMLCornerQuadMesh< ELEMENT >::PMLCornerQuadMesh(), and oomph::PMLQuadMesh< ELEMENT >::PMLQuadMesh().

◆ read()

void oomph::Mesh::read ( std::ifstream &  restart_file)
virtual

Read solution from restart file.

Try to cast to elastic node

Reimplemented in oomph::SpineMesh, and oomph::PerturbedSpineMesh.

1131  {
1132  std::string input_string;
1133 
1134  // Reorder the nodes within the mesh's node vector
1135  // to establish a standard ordering regardless of the sequence
1136  // of mesh refinements etc
1137  this->reorder_nodes();
1138 
1139  // Read nodes
1140 
1141  // Find number of nodes
1142  unsigned long n_node = this->nnode();
1143 
1144  // Read line up to termination sign
1145  getline(restart_file, input_string, '#');
1146 
1147  // Ignore rest of line
1148  restart_file.ignore(80, '\n');
1149 
1150  // Check # of nodes:
1151  unsigned long check_n_node = atoi(input_string.c_str());
1152  if (check_n_node != n_node)
1153  {
1154  std::ostringstream error_stream;
1155  error_stream << "The number of nodes allocated " << n_node
1156  << " is not the same as specified in the restart file "
1157  << check_n_node << std::endl;
1158 
1159  throw OomphLibError(
1160  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1161  }
1162 
1163  // Loop over the nodes
1164  for (unsigned long n = 0; n < n_node; n++)
1165  {
1167  SolidNode* el_node_pt = dynamic_cast<SolidNode*>(this->node_pt(n));
1168  if (el_node_pt != 0)
1169  {
1170  el_node_pt->read(restart_file);
1171  }
1172  else
1173  {
1174  this->node_pt(n)->read(restart_file);
1175  }
1176  }
1177 
1178  // Read internal data of elements:
1179  //--------------------------------
1180  // Loop over elements and deal with internal data
1181  unsigned n_element = this->nelement();
1182  for (unsigned e = 0; e < n_element; e++)
1183  {
1184  GeneralisedElement* el_pt = this->element_pt(e);
1185  unsigned n_internal = el_pt->ninternal_data();
1186  if (n_internal > 0)
1187  {
1188  // Read line up to termination sign
1189  getline(restart_file, input_string, '#');
1190 
1191  // Ignore rest of line
1192  restart_file.ignore(80, '\n');
1193 
1194  // Check # of internals :
1195  unsigned long check_n_internal = atoi(input_string.c_str());
1196  if (check_n_internal != n_internal)
1197  {
1198  std::ostringstream error_stream;
1199  error_stream << "The number of internal data " << n_internal
1200  << " is not the same as specified in the restart file "
1201  << check_n_internal << std::endl;
1202 
1203  throw OomphLibError(error_stream.str(),
1206  }
1207 
1208  for (unsigned i = 0; i < n_internal; i++)
1209  {
1210  el_pt->internal_data_pt(i)->read(restart_file);
1211  }
1212  }
1213  }
1214  }
virtual void reorder_nodes(const bool &use_old_ordering=true)
Definition: mesh.cc:508
void read(std::ifstream &restart_file)
Read nodal position and associated data from file for restart.
Definition: nodes.cc:1996

References e(), element_pt(), i, oomph::GeneralisedElement::internal_data_pt(), n, nelement(), oomph::GeneralisedElement::ninternal_data(), nnode(), node_pt(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::Data::read(), oomph::Node::read(), oomph::SolidNode::read(), reorder_nodes(), and oomph::Global_string_for_annotation::string().

Referenced by oomph::PerturbedSpineMesh::read(), oomph::SpineMesh::read(), and oomph::Problem::read().

◆ remove_boundary_node()

void oomph::Mesh::remove_boundary_node ( const unsigned b,
Node *const &  node_pt 
)

Remove a node from the boundary b.

Remove the node node_pt from the b-th boundary of the mesh This function also removes the information from the Node itself

222  {
223  // Find the location of the node in the boundary
224  Vector<Node*>::iterator it = std::find(
226  // If the node is on this boundary
227  if (it != Boundary_node_pt[b].end())
228  {
229  // Remove the node from the mesh's list of boundary nodes
230  Boundary_node_pt[b].erase(it);
231  // Now remove the node's boundary information
233  }
234  // If not do nothing
235  }
virtual void remove_from_boundary(const unsigned &b)
Definition: nodes.cc:2350

References b, Boundary_node_pt, Eigen::placeholders::end, node_pt(), and oomph::Node::remove_from_boundary().

Referenced by delete_all_external_storage(), and ElasticTwoLayerMesh< ELEMENT >::ElasticTwoLayerMesh().

◆ remove_boundary_nodes() [1/2]

void oomph::Mesh::remove_boundary_nodes ( )

Clear all pointers to boundary nodes.

Remove all information about mesh boundaries.

205  {
206  // Loop over each boundary call remove_boundary_nodes
207  unsigned n_bound = Boundary_node_pt.size();
208  for (unsigned b = 0; b < n_bound; b++)
209  {
211  }
212  // Clear the storage
213  Boundary_node_pt.clear();
214  }
void remove_boundary_nodes()
Clear all pointers to boundary nodes.
Definition: mesh.cc:204

References b, and Boundary_node_pt.

Referenced by STSpineMesh< ELEMENT, INTERFACE_ELEMENT >::add_mesh(), CombTipSpineMesh< ELEMENT, INTERFACE_ELEMENT >::change_boundaries(), oomph::ChannelWithLeafletMesh< ELEMENT >::ChannelWithLeafletMesh(), oomph::CollapsibleChannelMesh< ELEMENT >::CollapsibleChannelMesh(), and oomph::FSIDrivenCavityMesh< ELEMENT >::FSIDrivenCavityMesh().

◆ remove_boundary_nodes() [2/2]

void oomph::Mesh::remove_boundary_nodes ( const unsigned b)

Remove all information about nodes stored on the b-th boundary of the mesh

Remove the information about nodes stored on the b-th boundary of the mesh

189  {
190  // Loop over all the nodes on the boundary and call
191  // their remove_from_boundary function
192  unsigned n_boundary_node = Boundary_node_pt[b].size();
193  for (unsigned n = 0; n < n_boundary_node; n++)
194  {
196  }
197  // Clear the storage
198  Boundary_node_pt[b].clear();
199  }

References b, Boundary_node_pt, boundary_node_pt(), n, and oomph::Node::remove_from_boundary().

◆ reorder_nodes()

void oomph::Mesh::reorder_nodes ( const bool use_old_ordering = true)
virtual

Re-order nodes in the order in which they appear in elements – can be overloaded for more efficient re-ordering

Reorder nodes in the order in which they are encountered when stepping through the elements

509  {
510  // Create storage for the reordered nodes
511  Vector<Node*> reordering;
512 
513  // Get the reordered nodes (without altering the mesh's node vector)
514  get_node_reordering(reordering, use_old_ordering);
515 
516  // Get the number of nodes in the mesh
517  unsigned n_node = nnode();
518 
519  // Loop over all of the nodes
520  for (unsigned i = 0; i < n_node; i++)
521  {
522  // Replace the Mesh's i-th node pointer with the reordered node pointer
523  node_pt(i) = reordering[i];
524  }
525  } // End of reorder_nodes

References get_node_reordering(), i, nnode(), and node_pt().

Referenced by oomph::TreeBasedRefineableMeshBase::adapt(), oomph::TreeBasedRefineableMeshBase::adapt_mesh(), oomph::TreeBasedRefineableMeshBase::p_adapt(), oomph::TreeBasedRefineableMeshBase::p_adapt_mesh(), and read().

◆ reset_boundary_element_info()

virtual void oomph::Mesh::reset_boundary_element_info ( Vector< unsigned > &  ntmp_boundary_elements,
Vector< Vector< unsigned >> &  ntmp_boundary_elements_in_region,
Vector< FiniteElement * > &  deleted_elements 
)
inlinevirtual

Virtual function to perform the reset boundary elements info rutines.

Reimplemented in oomph::TriangleMeshBase.

288  {
289  std::ostringstream error_stream;
290  error_stream << "Empty default reset boundary element info function"
291  << "called.\n";
292  error_stream << "This should be overloaded in a specific "
293  << "TriangleMeshBase\n";
294  throw OomphLibError(error_stream.str(),
295  "Mesh::reset_boundary_element_info()",
297  }

References OOMPH_EXCEPTION_LOCATION.

◆ scale_mesh()

virtual void oomph::Mesh::scale_mesh ( const double factor)
inlinevirtual

Scale all nodal coordinates by given factor. Virtual so it can be overloaded in SolidMesh class where it also re-assigns the Lagrangian coordinates.

Reimplemented in oomph::SolidMesh.

374  {
375  unsigned nnod = this->nnode();
376  unsigned dim = this->node_pt(0)->ndim();
377  for (unsigned j = 0; j < nnod; j++)
378  {
379  Node* nod_pt = this->node_pt(j);
380  for (unsigned i = 0; i < dim; i++)
381  {
382  nod_pt->x(i) *= factor;
383  }
384  }
385  }

References i, j, oomph::Node::ndim(), nnode(), node_pt(), and oomph::Node::x().

Referenced by oomph::SolidMesh::scale_mesh().

◆ self_test()

unsigned oomph::Mesh::self_test ( )

Self-test: Check elements and nodes. Return 0 for OK.

779  {
780  // Initialise
781  bool passed = true;
782 
783  // Check the mesh for repeated nodes (issues its own error message)
784  if (0 != check_for_repeated_nodes()) passed = false;
785 
786  // hierher -- re-enable once problem with Hermite elements has been
787  // resolved.
788  // // Check if there are any inverted elements
789  // bool mesh_has_inverted_elements=false;
790  // check_inverted_elements(mesh_has_inverted_elements);
791  // if (mesh_has_inverted_elements)
792  // {
793  // passed=false;
794  // oomph_info << "\n ERROR: Mesh has inverted elements\n"
795  // << " Run Mesh::check_inverted_elements(...) with"
796  // << " with output stream to find out which elements are"
797  // << " inverted.\n";
798  // }
799 
800  // Loop over the elements, check for duplicates and do self test
801  std::set<GeneralisedElement*> element_set_pt;
802  unsigned long Element_pt_range = Element_pt.size();
803  for (unsigned long i = 0; i < Element_pt_range; i++)
804  {
805  if (Element_pt[i]->self_test() != 0)
806  {
807  passed = false;
808  oomph_info << "\n ERROR: Failed Element::self_test() for element i="
809  << i << std::endl;
810  }
811  // Add to set (which ignores duplicates):
812  element_set_pt.insert(Element_pt[i]);
813  }
814 
815  // Check for duplicates:
816  if (element_set_pt.size() != Element_pt_range)
817  {
818  oomph_info << "ERROR: " << Element_pt_range - element_set_pt.size()
819  << " duplicate elements were encountered in mesh!"
820  << std::endl;
821  passed = false;
822  }
823 
824 
825  // Loop over the nodes, check for duplicates and do self test
826  std::set<Node*> node_set_pt;
827  unsigned long Node_pt_range = Node_pt.size();
828  for (unsigned long i = 0; i < Node_pt_range; i++)
829  {
830  if (Node_pt[i]->self_test() != 0)
831  {
832  passed = false;
833  oomph_info << "\n ERROR: Failed Node::self_test() for node i=" << i
834  << std::endl;
835  }
836  // Add to set (which ignores duplicates):
837  node_set_pt.insert(Node_pt[i]);
838  }
839 
840  // Check for duplicates:
841  if (node_set_pt.size() != Node_pt_range)
842  {
843  oomph_info << "ERROR: " << Node_pt_range - node_set_pt.size()
844  << " duplicate nodes were encountered in mesh!" << std::endl;
845  passed = false;
846  }
847 
848  // Return verdict
849  if (passed)
850  {
851  return 0;
852  }
853  else
854  {
855  return 1;
856  }
857  }
unsigned check_for_repeated_nodes(const double &epsilon=1.0e-12)
Definition: mesh.h:752
unsigned self_test()
Self-test: Check elements and nodes. Return 0 for OK.
Definition: mesh.cc:778

References check_for_repeated_nodes(), Element_pt, i, Node_pt, and oomph::oomph_info.

Referenced by oomph::RefineableEighthSphereMesh< ELEMENT >::RefineableEighthSphereMesh(), oomph::RefineableFullCircleMesh< ELEMENT >::RefineableFullCircleMesh(), oomph::RefineableQuarterTubeMesh< ELEMENT >::RefineableQuarterTubeMesh(), oomph::RefineableTubeMesh< ELEMENT >::RefineableTubeMesh(), and oomph::AlgebraicMesh::self_test().

◆ set_consistent_pinned_values_for_continuation()

void oomph::Mesh::set_consistent_pinned_values_for_continuation ( ContinuationStorageScheme *const &  continuation_storage_pt)

Set consistent values for pinned data in continuation.

Set the values of auxilliary data used in continuation problems when the data is pinned.

2438  {
2439  // Loop over the nodes
2440  const unsigned long n_node = this->nnode();
2441  for (unsigned long n = 0; n < n_node; n++)
2442  {
2443  continuation_storage_pt->set_consistent_pinned_values(this->Node_pt[n]);
2444  continuation_storage_pt->set_consistent_pinned_positions(
2445  this->Node_pt[n]);
2446  }
2447 
2448  // Loop over the elements
2449  const unsigned long n_element = this->nelement();
2450  for (unsigned long e = 0; e < n_element; e++)
2451  {
2452  // Cache pointer to the elemnet
2453  GeneralisedElement* const elem_pt = this->element_pt(e);
2454  // Find the number of internal dofs
2455  const unsigned n_internal = elem_pt->ninternal_data();
2456 
2457  // Loop over internal dofs and test the data
2458  for (unsigned j = 0; j < n_internal; j++)
2459  {
2460  continuation_storage_pt->set_consistent_pinned_values(
2461  elem_pt->internal_data_pt(j));
2462  }
2463  }
2464  }

References e(), element_pt(), oomph::GeneralisedElement::internal_data_pt(), j, n, nelement(), oomph::GeneralisedElement::ninternal_data(), nnode(), Node_pt, oomph::ContinuationStorageScheme::set_consistent_pinned_positions(), and oomph::ContinuationStorageScheme::set_consistent_pinned_values().

Referenced by oomph::Problem::set_consistent_pinned_values_for_continuation().

◆ set_elemental_internal_time_stepper()

void oomph::Mesh::set_elemental_internal_time_stepper ( TimeStepper *const &  time_stepper_pt,
const bool preserve_existing_data 
)

Set the timestepper associated with the internal data stored within elements in the meah

Set the time stepper associated with all internal data stored in the elements in the mesh

2537  {
2538  // Loop over the elements
2539  const unsigned long n_element = this->nelement();
2540  for (unsigned long e = 0; e < n_element; e++)
2541  {
2542  // Find the number of internal dofs
2543  const unsigned n_internal = this->element_pt(e)->ninternal_data();
2544 
2545  // Loop over internal dofs and set the timestepper
2546  for (unsigned j = 0; j < n_internal; j++)
2547  {
2548  this->element_pt(e)->internal_data_pt(j)->set_time_stepper(
2549  time_stepper_pt, preserve_existing_data);
2550  }
2551  }
2552  }

References e(), element_pt(), j, and nelement().

Referenced by set_nodal_and_elemental_time_stepper().

◆ set_mesh_level_time_stepper()

void oomph::Mesh::set_mesh_level_time_stepper ( TimeStepper *const &  time_stepper_pt,
const bool preserve_existing_data 
)
virtual

Function that can be used to set any additional timestepper data stored at the Mesh (as opposed to nodal and elemental) levels. This is virtual so that it can be overloaded in the appropriate Meshes. Examples include the SpineMeshes and adaptive triangle and tet meshes

Virtual function that should be overloaded if the mesh has any mesh level storage of the timestepper

Reimplemented in oomph::TriangleMesh< ELEMENT >, oomph::TriangleMesh< FLUID_ELEMENT >, oomph::TriangleMesh< SOLID_ELEMENT >, oomph::TriangleMesh< HELMHOLTZ_ELEMENT >, oomph::TriangleMesh< POROELASTICITY_ELEMENT >, oomph::TriangleMesh< ELASTICITY_ELEMENT >, oomph::TriangleMesh< oomph::TPoissonElement< 2, 2 > >, oomph::TetgenMesh< ELEMENT >, and oomph::SpineMesh.

2404  {
2405 #ifdef PARANOID
2407  {
2408  std::ostringstream warning_stream;
2409  warning_stream
2410  << "Empty set_mesh_level_time_stepper() has been called.\n"
2411  << "This function needs to be overloaded to reset any (pointers to) \n"
2412  << "timesteppers for meshes that store timesteppers in locations "
2413  "other\n"
2414  << "than the Nodes or Elements;\n"
2415  << "e.g. SpineMeshes have SpineData with timesteppers,\n"
2416  << "Triangle and TetMeshes store the timestepper for use in "
2417  "adaptivity.\n\n\n";
2418  warning_stream
2419  << "If you are solving a continuation or bifurcation detecion\n"
2420  << "problem and strange things are happening, then check that\n"
2421  << "you don't need to overload this function for your mesh."
2422  << "\n This warning can be suppressed by setting:\n"
2423  << "Mesh::Suppress_warning_about_empty_mesh_level_time_stepper_"
2424  "function=true"
2425  << std::endl;
2426  OomphLibWarning(
2427  warning_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2428  }
2429 #endif
2430  }
static bool Suppress_warning_about_empty_mesh_level_time_stepper_function
Static boolean flag to control warning about mesh level timesteppers.
Definition: mesh.h:233

References OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and Suppress_warning_about_empty_mesh_level_time_stepper_function.

Referenced by oomph::Problem::set_timestepper_for_all_data().

◆ set_nboundary()

void oomph::Mesh::set_nboundary ( const unsigned nbound)
inline

◆ set_nodal_and_elemental_time_stepper()

void oomph::Mesh::set_nodal_and_elemental_time_stepper ( TimeStepper *const &  time_stepper_pt,
const bool preserve_existing_data 
)
inline

Set the timestepper associated with all nodal and elemental data stored in the mesh.

1034  {
1035  this->set_nodal_time_stepper(time_stepper_pt, preserve_existing_data);
1036  this->set_elemental_internal_time_stepper(time_stepper_pt,
1037  preserve_existing_data);
1038  }
void set_elemental_internal_time_stepper(TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
Definition: mesh.cc:2535
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.
Definition: mesh.cc:2516

References set_elemental_internal_time_stepper(), and set_nodal_time_stepper().

Referenced by oomph::Problem::set_timestepper_for_all_data().

◆ set_nodal_time_stepper()

void oomph::Mesh::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.

Set the time stepper associated with all the nodal data in the problem

2518  {
2519  // Loop over the nodes
2520  const unsigned long n_node = this->nnode();
2521  for (unsigned long n = 0; n < n_node; n++)
2522  {
2523  // Set the timestepper associated with each node
2524  this->Node_pt[n]->set_time_stepper(time_stepper_pt,
2525  preserve_existing_data);
2526  this->Node_pt[n]->set_position_time_stepper(time_stepper_pt,
2527  preserve_existing_data);
2528  }
2529  }

References n, nnode(), and Node_pt.

Referenced by set_nodal_and_elemental_time_stepper().

◆ setup_boundary_element_info() [1/2]

◆ setup_boundary_element_info() [2/2]

virtual void oomph::Mesh::setup_boundary_element_info ( std::ostream &  outfile)
inlinevirtual

Setup lookup schemes which establish whic elements are located next to mesh's boundaries. Doc in outfile (if it's open). (Empty virtual function – implement this for specific Mesh classes)

Reimplemented in oomph::HermiteQuadMesh< ELEMENT >, oomph::TriangleMeshBase, oomph::TetMeshBase, oomph::QuadMeshBase, oomph::LineMeshBase, oomph::BrickMeshBase, and oomph::RefineableSolidCubicMesh< ELEMENT >.

281 {}

◆ shift_time_values()

void oomph::Mesh::shift_time_values ( )

Shift time-dependent data along for next timestep: Deal with nodal Data/positions and the element's internal Data

Shift time-dependent data along for next timestep: Again this is achieved by looping over all data and calling the functions defined in each data object's timestepper.

2327  {
2328  // Loop over the elements which shift their internal data
2329  // via their own timesteppers
2330  const unsigned long Nelement = nelement();
2331  for (unsigned long e = 0; e < Nelement; e++)
2332  {
2333  // Find the number of internal dofs
2334  const unsigned Ninternal = element_pt(e)->ninternal_data();
2335  // Loop over internal dofs and shift the time values
2336  // using the internals data's timestepper
2337  for (unsigned j = 0; j < Ninternal; j++)
2338  {
2339  element_pt(e)
2340  ->internal_data_pt(j)
2341  ->time_stepper_pt()
2342  ->shift_time_values(element_pt(e)->internal_data_pt(j));
2343  }
2344  }
2345 
2346  // Loop over the nodes
2347  const unsigned long n_node = nnode();
2348  for (unsigned long n = 0; n < n_node; n++)
2349  {
2350  // Shift the Data associated with the nodes with the Node's own
2351  // timestepper
2352  Node_pt[n]->time_stepper_pt()->shift_time_values(Node_pt[n]);
2353  // Push history of nodal positions back
2354  Node_pt[n]->position_time_stepper_pt()->shift_time_positions(Node_pt[n]);
2355  }
2356  }

References e(), element_pt(), j, n, nelement(), nnode(), and Node_pt.

Referenced by oomph::Problem::shift_time_values().

◆ total_size()

double oomph::Mesh::total_size ( )
inline

Determine the sum of all "sizes" of the FiniteElements in the mesh (non-FiniteElements are ignored). This gives the length/area/volume occupied by the mesh

709  {
710  double size = 0.0;
711  unsigned nel = nelement();
712  for (unsigned e = 0; e < nel; e++)
713  {
714  FiniteElement* fe_pt = finite_element_pt(e);
715  if (fe_pt != 0)
716  {
717  size += fe_pt->size();
718  }
719  }
720  return size;
721  }

References e(), finite_element_pt(), nelement(), size, and oomph::FiniteElement::size().

Friends And Related Function Documentation

◆ Problem

friend class Problem
friend

Problem is a friend.

Member Data Documentation

◆ Boundary_coordinate_exists

◆ Boundary_element_pt

◆ Boundary_node_pt

Vector<Vector<Node*> > oomph::Mesh::Boundary_node_pt
protected

Vector of Vector of pointers to nodes on the boundaries: Boundary_node_pt(b,n). Note that this is private to force the use of the add_boundary_node() function, which ensures that the reverse look-up schemes for the nodes are set up.

Referenced by add_boundary_node(), boundary_node_pt(), copy_boundary_node_data_from_nodes(), ElasticTwoLayerMesh< ELEMENT >::ElasticTwoLayerMesh(), merge_meshes(), nboundary(), nboundary_node(), output_boundaries(), prune_dead_nodes(), remove_boundary_node(), remove_boundary_nodes(), and set_nboundary().

◆ Default_TimeStepper

Steady< 0 > oomph::Mesh::Default_TimeStepper
static

◆ Element_pt

Vector<GeneralisedElement*> oomph::Mesh::Element_pt
protected

Vector of pointers to generalised elements.

Referenced by oomph::TreeBasedRefineableMeshBase::adapt_mesh(), add_element_pt(), oomph::jh_mesh< ELEMENT >::assign_fluid_element_vector(), oomph::streamfunction_mesh::assign_fluid_element_vector(), assign_global_eqn_numbers(), assign_local_eqn_numbers(), oomph::BackupMeshForProjection< GEOMETRIC_ELEMENT >::BackupMeshForProjection(), oomph::GmshTetMesh< ELEMENT >::build_from_scaffold(), compute_error(), compute_norm(), convert_to_boundary_node(), oomph::GmshTetScaffoldMesh::create_mesh_from_msh_file(), describe_dofs(), describe_local_dofs(), oomph::EighthSphereMesh< ELEMENT >::EighthSphereMesh(), oomph::PerturbedSpineMesh::element_node_pt(), oomph::SolidMesh::element_node_pt(), oomph::SpineMesh::element_node_pt(), element_pt(), finite_element_pt(), flush_element_storage(), oomph::FullCircleMesh< ELEMENT >::FullCircleMesh(), oomph::GeompackQuadScaffoldMesh::GeompackQuadScaffoldMesh(), oomph::jh_mesh< ELEMENT >::make_flux_element(), oomph::jh_mesh< ELEMENT >::make_traction_elements(), oomph::streamfunction_mesh::make_traction_elements(), merge_meshes(), nelement(), output(), output_fct(), output_fct_paraview(), output_paraview(), oomph::QuarterCircleSectorMesh< ELEMENT >::QuarterCircleSectorMesh(), oomph::QuarterTubeMesh< ELEMENT >::QuarterTubeMesh(), oomph::RectangleWithHoleMesh< ELEMENT >::RectangleWithHoleMesh(), oomph::jh_mesh< ELEMENT >::remove_traction_elements(), oomph::streamfunction_mesh::remove_traction_elements(), self_test(), oomph::SimpleCubicScaffoldTetMesh::SimpleCubicScaffoldTetMesh(), oomph::SimpleRectangularTriMesh< ELEMENT >::SimpleRectangularTriMesh(), oomph::TetMeshBase::split_elements_in_corners(), oomph::TetgenScaffoldMesh::TetgenScaffoldMesh(), oomph::ThinLayerBrickOnTetMesh< ELEMENT >::ThinLayerBrickOnTetMesh(), oomph::TriangleScaffoldMesh::TriangleScaffoldMesh(), oomph::TubeMesh< ELEMENT >::TubeMesh(), and ~Mesh().

◆ Face_index_at_boundary

◆ Lookup_for_elements_next_boundary_is_setup

◆ Node_pt

Vector<Node*> oomph::Mesh::Node_pt
protected

Vector of pointers to nodes.

Referenced by add_node_pt(), assign_global_eqn_numbers(), assign_initial_values_impulsive(), oomph::BackupMeshForProjection< GEOMETRIC_ELEMENT >::BackupMeshForProjection(), oomph::GmshTetMesh< ELEMENT >::build_from_scaffold(), calculate_predictions(), oomph::TriangleScaffoldMesh::check_mesh_integrity(), convert_to_boundary_node(), oomph::GmshTetScaffoldMesh::create_mesh_from_msh_file(), delete_all_external_storage(), describe_dofs(), does_pointer_correspond_to_mesh_data(), oomph::EighthSphereMesh< ELEMENT >::EighthSphereMesh(), flush_node_storage(), oomph::FullCircleMesh< ELEMENT >::FullCircleMesh(), oomph::GeompackQuadScaffoldMesh::GeompackQuadScaffoldMesh(), merge_meshes(), nnode(), oomph::PerturbedSpineMesh::node_pt(), oomph::AlgebraicMesh::node_pt(), node_pt(), oomph::SolidMesh::node_pt(), oomph::SpineMesh::node_pt(), oomph::PerturbedSpineMesh::node_update(), node_update(), oomph::SpineMesh::node_update(), prune_dead_nodes(), oomph::QuarterCircleSectorMesh< ELEMENT >::QuarterCircleSectorMesh(), oomph::QuarterTubeMesh< ELEMENT >::QuarterTubeMesh(), oomph::RectangleWithHoleMesh< ELEMENT >::RectangleWithHoleMesh(), self_test(), set_consistent_pinned_values_for_continuation(), oomph::SolidMesh::set_lagrangian_nodal_coordinates(), set_nodal_time_stepper(), shift_time_values(), oomph::SimpleCubicScaffoldTetMesh::SimpleCubicScaffoldTetMesh(), oomph::SimpleRectangularTriMesh< ELEMENT >::SimpleRectangularTriMesh(), oomph::Refineable_r_mesh< ELEMENT >::stretch_mesh(), oomph::TetgenScaffoldMesh::TetgenScaffoldMesh(), oomph::ThinLayerBrickOnTetMesh< ELEMENT >::ThinLayerBrickOnTetMesh(), oomph::TriangleScaffoldMesh::TriangleScaffoldMesh(), oomph::TubeMesh< ELEMENT >::TubeMesh(), oomph::WomersleyMesh< WOMERSLEY_ELEMENT >::WomersleyMesh(), and ~Mesh().

◆ Suppress_warning_about_empty_mesh_level_time_stepper_function

bool oomph::Mesh::Suppress_warning_about_empty_mesh_level_time_stepper_function
static
Initial value:
=
false

Static boolean flag to control warning about mesh level timesteppers.

Boolean used to control warning about empty mesh level timestepper function

Referenced by set_mesh_level_time_stepper().


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