oomph::FishMesh< ELEMENT > Class Template Reference

#include <fish_mesh.template.h>

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

Public Member Functions

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

Protected Types

enum  { Lower_body , Upper_body , Lower_fin , Upper_fin }
 Remesh function ids. More...
 

Protected Member Functions

void build_mesh (TimeStepper *time_stepper_pt)
 Build the mesh, using the geometric object identified by Back_pt. More...
 
- Protected Member Functions inherited from oomph::Mesh
unsigned long assign_global_eqn_numbers (Vector< double * > &Dof_pt)
 Assign (global) equation numbers to the nodes. More...
 
void describe_dofs (std::ostream &out, const std::string &current_string) const
 
void describe_local_dofs (std::ostream &out, const std::string &current_string) const
 
void assign_local_eqn_numbers (const bool &store_local_dof_pt)
 Assign local equation numbers in all elements. More...
 
void convert_to_boundary_node (Node *&node_pt, const Vector< FiniteElement * > &finite_element_pt)
 
void convert_to_boundary_node (Node *&node_pt)
 

Protected Attributes

GeomObjectBack_pt
 Pointer to fish back. More...
 
FishDomainDomain_pt
 Pointer to domain. More...
 
bool Must_kill_fish_back
 Do I need to kill the fish back geom object? More...
 
- Protected Attributes inherited from oomph::Mesh
Vector< Vector< Node * > > Boundary_node_pt
 
bool Lookup_for_elements_next_boundary_is_setup
 
Vector< Vector< FiniteElement * > > Boundary_element_pt
 
Vector< Vector< int > > Face_index_at_boundary
 
Vector< Node * > Node_pt
 Vector of pointers to nodes. More...
 
Vector< GeneralisedElement * > Element_pt
 Vector of pointers to generalised elements. More...
 
std::vector< boolBoundary_coordinate_exists
 

Additional Inherited Members

- Public Types inherited from oomph::Mesh
typedef void(FiniteElement::* SteadyExactSolutionFctPt) (const Vector< double > &x, Vector< double > &soln)
 
typedef void(FiniteElement::* UnsteadyExactSolutionFctPt) (const double &time, const Vector< double > &x, Vector< double > &soln)
 
- Static Public Attributes inherited from oomph::Mesh
static Steady< 0 > Default_TimeStepper
 The Steady Timestepper. More...
 
static bool Suppress_warning_about_empty_mesh_level_time_stepper_function
 Static boolean flag to control warning about mesh level timesteppers. More...
 

Detailed Description

template<class ELEMENT>
class oomph::FishMesh< ELEMENT >

Fish shaped mesh. The geometry is defined by the Domain object FishDomain.

Member Enumeration Documentation

◆ anonymous enum

template<class ELEMENT >
anonymous enum
protected

Remesh function ids.

Enumerator
Lower_body 
Upper_body 
Lower_fin 
Upper_fin 
94  {
95  Lower_body,
96  Upper_body,
97  Lower_fin,
98  Upper_fin
99  };
@ Lower_body
Definition: fish_mesh.template.h:95
@ Lower_fin
Definition: fish_mesh.template.h:97
@ Upper_fin
Definition: fish_mesh.template.h:98
@ Upper_body
Definition: fish_mesh.template.h:96

Constructor & Destructor Documentation

◆ FishMesh() [1/2]

template<class ELEMENT >
oomph::FishMesh< ELEMENT >::FishMesh ( TimeStepper time_stepper_pt = &Mesh::Default_TimeStepper)

Constructor: Pass pointer to timestepper (defaults to the (Steady) default timestepper defined in Mesh)

Constructor: Pass pointer to timestepper. (defaults to (Steady) default timestepper defined in Mesh)

40  {
41  // Mesh can only be built with 2D Qelements.
42  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
43 
44  // Fish back is a circle of radius 1, centred at (0.5,0.0)
45  double x_c = 0.5;
46  double y_c = 0.0;
47  double r_back = 1.0;
48  Back_pt = new Circle(x_c, y_c, r_back);
49 
50  // I've created the fishback -- I need to kill it.
51  Must_kill_fish_back = true;
52 
53  // Now build the mesh
54  build_mesh(time_stepper_pt);
55  }
GeomObject * Back_pt
Pointer to fish back.
Definition: fish_mesh.template.h:105
void build_mesh(TimeStepper *time_stepper_pt)
Build the mesh, using the geometric object identified by Back_pt.
Definition: fish_mesh.template.cc:83
bool Must_kill_fish_back
Do I need to kill the fish back geom object?
Definition: fish_mesh.template.h:111

◆ FishMesh() [2/2]

template<class ELEMENT >
oomph::FishMesh< ELEMENT >::FishMesh ( GeomObject back_pt,
TimeStepper time_stepper_pt = &Mesh::Default_TimeStepper 
)

Constructor: Pass pointer GeomObject that defines the fish's back and pointer to timestepper (defaults to the (Steady) default timestepper defined in Mesh)

Constructor: Pass pointer GeomObject that defines the fish's back and pointer to timestepper. (defaults to (Steady) default timestepper defined in Mesh)

65  : Back_pt(back_pt)
66  {
67  // Mesh can only be built with 2D Qelements.
68  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
69 
70  // Back_pt has already been set....
71  Must_kill_fish_back = false;
72 
73  // Now build the mesh
74  build_mesh(time_stepper_pt);
75  }

References oomph::FishMesh< ELEMENT >::build_mesh(), and oomph::FishMesh< ELEMENT >::Must_kill_fish_back.

◆ ~FishMesh()

template<class ELEMENT >
virtual oomph::FishMesh< ELEMENT >::~FishMesh ( )
inlinevirtual

Destructor: Kill the geom object that represents the fish's back (if necessary)

70  {
72  {
73  delete Back_pt;
74  Back_pt = 0;
75  }
76  }

References oomph::FishMesh< ELEMENT >::Back_pt, and oomph::FishMesh< ELEMENT >::Must_kill_fish_back.

Member Function Documentation

◆ build_mesh()

template<class ELEMENT >
void oomph::FishMesh< ELEMENT >::build_mesh ( TimeStepper time_stepper_pt)
protected

Build the mesh, using the geometric object identified by Back_pt.

Build the mesh, using the geometric object that defines the fish's back.

84  {
85  // Mesh can only be built with 2D Qelements.
86  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
87 
88  // Build domain: Pass the pointer to the geometric object that
89  // represents the fish's back (pointed to by the FishMesh's
90  // private data member, Back_pt, and the values of the
91  // Lagrangian coordinate along this object at the "tail"
92  // and the "nose":
93  double xi_lo = 2.6;
94  double xi_hi = 0.4;
95  Domain_pt = new FishDomain(Back_pt, xi_lo, xi_hi);
96 
97  // Plot the domain? Keep this here in case we need to doc it
98  bool plot_it = false;
99  if (plot_it)
100  {
101  // Output the domain
102  std::ofstream some_file;
103 
104  // Number of plot points in each coordinate direction.
105  unsigned npts = 10;
106 
107  // Output domain
108  some_file.open("fish_domain.dat");
109  Domain_pt->output(some_file, npts);
110  Domain_pt->output_macro_element_boundaries(some_file, npts);
111  some_file.close();
112  }
113 
114  // Set the number of boundaries
115  set_nboundary(7);
116 
117 
118  // We will store boundary coordinates on the curvilinear boundaries
119  //(boundaries 0 and 4) along the fish's belly and its back.
120  Boundary_coordinate_exists[0] = true;
121  Boundary_coordinate_exists[4] = true;
122 
123  // Allocate the storage for the elements
124  unsigned nelem = 4;
125  Element_pt.resize(nelem);
126 
127  // Create dummy element so we can determine the number of nodes
128  ELEMENT* dummy_el_pt = new ELEMENT;
129 
130  // Read out the number of linear points in the element
131  unsigned n_node_1d = dummy_el_pt->nnode_1d();
132 
133  // Kill the element
134  delete dummy_el_pt;
135 
136  // Can now allocate the store for the nodes
137  unsigned nnodes_total =
138  (2 * (n_node_1d - 1) + 1) * (2 * (n_node_1d - 1) + 1);
139  Node_pt.resize(nnodes_total);
140 
141 
142  Vector<double> s(2), s_fraction(2);
143  Vector<double> r(2);
144 
145 
146  // Create elements and all nodes in element
147  //-----------------------------------------
148  // (ignore repetitions for now -- we'll clean them up later)
149  //----------------------------------------------------------
150  for (unsigned e = 0; e < nelem; e++)
151  {
152  // Create element
153  Element_pt[e] = new ELEMENT;
154 
155  // Loop over rows in y/s_1-direction
156  for (unsigned i1 = 0; i1 < n_node_1d; i1++)
157  {
158  // Loop over rows in x/s_0-direction
159  for (unsigned i0 = 0; i0 < n_node_1d; i0++)
160  {
161  // Local node number
162  unsigned j_local = i0 + i1 * n_node_1d;
163 
164  // Create the node and store pointer to it
165  Node* node_pt =
166  finite_element_pt(e)->construct_node(j_local, time_stepper_pt);
167 
168  // Work out the node's coordinates in the finite element's local
169  // coordinate system:
170  finite_element_pt(e)->local_fraction_of_node(j_local, s_fraction);
171 
172  s[0] = -1.0 + 2.0 * s_fraction[0];
173  s[1] = -1.0 + 2.0 * s_fraction[1];
174 
175  // Get the global position of the node from macro element mapping
177 
178  // Set the nodal position
179  node_pt->x(0) = r[0];
180  node_pt->x(1) = r[1];
181  }
182  }
183  } // end of loop over elements
184 
185 
186  // Kill repeated nodes and replace by pointers to nodes in appropriate
187  //---------------------------------------------------------------------
188  // neighbour. Also add node pointers to boundary arrays.
189  //------------------------------------------------------
190 
191  // Initialise number of global nodes
192  unsigned node_count = 0;
193 
194  // Check for error in node killing
195  bool stopit = false;
196 
197 
198  // Max tolerance for error in node killing
199  double Max_tol_in_node_killing = 1.0e-12;
200 
201  // First element: Lower body: all nodes survive
202  //---------------------------------------------
203  unsigned e = 0;
204 
205  // Loop over rows in y/s_1-direction
206  for (unsigned i1 = 0; i1 < n_node_1d; i1++)
207  {
208  // Loop over rows in x/s_0-direction
209  for (unsigned i0 = 0; i0 < n_node_1d; i0++)
210  {
211  // Local node number
212  unsigned j_local = i0 + i1 * n_node_1d;
213 
214  // No duplicate node: Copy new node across to mesh
215  Node_pt[node_count] = finite_element_pt(e)->node_pt(j_local);
216 
217  // Set boundaries:
218 
219  // If we're on the boundary need to convert the node
220  // into a boundary node
221  if ((i0 == 0) || (i1 == 0))
222  {
223  this->convert_to_boundary_node(Node_pt[node_count]);
224  }
225 
226  // Lower jaw: boundary 6
227  if (i0 == 0)
228  {
229  add_boundary_node(6, Node_pt[node_count]);
230  }
231 
232  // Belly: boundary 0
233  if (i1 == 0)
234  {
235  add_boundary_node(0, Node_pt[node_count]);
236 
237  // Set the boundary coordinate
238  Vector<double> zeta(1);
239  zeta[0] =
240  xi_lo + (xi_hi - xi_lo) * double(i0) / double(n_node_1d - 1);
241  Node_pt[node_count]->set_coordinates_on_boundary(0, zeta);
242  }
243 
244  // Increment node counter
245  node_count++;
246  }
247  }
248 
249 
250  // Lower fin: Western row of nodes is duplicate from element 0
251  //------------------------------------------------------------
252  e = 1;
253 
254  // Loop over rows in y/s_1-direction
255  for (unsigned i1 = 0; i1 < n_node_1d; i1++)
256  {
257  // Loop over rows in x/s_0-direction
258  for (unsigned i0 = 0; i0 < n_node_1d; i0++)
259  {
260  // Local node number
261  unsigned j_local = i0 + i1 * n_node_1d;
262 
263  // Has the node been killed?
264  bool killed = false;
265 
266  // First vertical row of nodes in s_1 direction get killed
267  // and re-directed to nodes in element 0
268  if (i0 == 0)
269  {
270  // Neighbour element
271  unsigned e_neigh = 0;
272 
273  // Node in neighbour element
274  unsigned i0_neigh = n_node_1d - 1;
275  unsigned i1_neigh = i1;
276  unsigned j_local_neigh = i0_neigh + i1_neigh * n_node_1d;
277 
278 
279  // Check:
280  for (unsigned i = 0; i < 2; i++)
281  {
282  double error = std::fabs(
283  finite_element_pt(e)->node_pt(j_local)->x(i) -
284  finite_element_pt(e_neigh)->node_pt(j_local_neigh)->x(i));
285  if (error > Max_tol_in_node_killing)
286  {
287  oomph_info << "Error in node killing for i " << i << " " << error
288  << std::endl;
289  stopit = true;
290  }
291  }
292 
293  // Kill node
294  delete finite_element_pt(e)->node_pt(j_local);
295  killed = true;
296 
297  // Set pointer to neighbour:
298  finite_element_pt(e)->node_pt(j_local) =
299  finite_element_pt(e_neigh)->node_pt(j_local_neigh);
300  }
301 
302 
303  // No duplicate node: Copy across to mesh
304  if (!killed)
305  {
306  // Copy the node across
307  Node_pt[node_count] = finite_element_pt(e)->node_pt(j_local);
308 
309  // If we're on a boundary turn the node into
310  // a boundary node
311  if ((i1 == 0) || (i0 == n_node_1d - 1))
312  {
313  this->convert_to_boundary_node(Node_pt[node_count]);
314  }
315 
316  // Increment node counter
317  node_count++;
318  }
319 
320  // Set boundaries:
321 
322  // Bottom of tail: boundary 1
323  if (i1 == 0)
324  {
326  }
327 
328  // Vertical bit of tail: boundary 2
329  if (i0 == n_node_1d - 1)
330  {
332  }
333  }
334  }
335 
336 
337  // Upper body: Southern row of nodes is duplicate from element 0
338  //--------------------------------------------------------------
339  e = 2;
340 
341  // Loop over rows in y/s_1-direction
342  for (unsigned i1 = 0; i1 < n_node_1d; i1++)
343  {
344  // Loop over rows in x/s_0-direction
345  for (unsigned i0 = 0; i0 < n_node_1d; i0++)
346  {
347  // Local node number
348  unsigned j_local = i0 + i1 * n_node_1d;
349 
350  // Has the node been killed?
351  bool killed = false;
352 
353  // First horizontal row of nodes in s_0 direction get killed
354  // and re-directed to nodes in element 0
355  if (i1 == 0)
356  {
357  // Neighbour element
358  unsigned e_neigh = 0;
359 
360  // Node in neighbour element
361  unsigned i0_neigh = i0;
362  unsigned i1_neigh = n_node_1d - 1;
363  unsigned j_local_neigh = i0_neigh + i1_neigh * n_node_1d;
364 
365  // Check:
366  for (unsigned i = 0; i < 2; i++)
367  {
368  double error = std::fabs(
369  finite_element_pt(e)->node_pt(j_local)->x(i) -
370  finite_element_pt(e_neigh)->node_pt(j_local_neigh)->x(i));
371  if (error > Max_tol_in_node_killing)
372  {
373  oomph_info << "Error in node killing for i " << i << " " << error
374  << std::endl;
375  stopit = true;
376  }
377  }
378 
379  // Kill node
380  delete finite_element_pt(e)->node_pt(j_local);
381  killed = true;
382 
383  // Set pointer to neighbour:
384  finite_element_pt(e)->node_pt(j_local) =
385  finite_element_pt(e_neigh)->node_pt(j_local_neigh);
386  }
387 
388  // No duplicate node: Copy across to mesh
389  if (!killed)
390  {
391  // Copy the old node across to the mesh
392  Node_pt[node_count] = finite_element_pt(e)->node_pt(j_local);
393 
394  // If we're on a boundary, convert the node into a boundary
395  // node. This will automatically update the entry in the mesh
396  if ((i1 == n_node_1d - 1) || (i0 == 0))
397  {
398  this->convert_to_boundary_node(Node_pt[node_count]);
399  }
400 
401  // Increment node counter
402  node_count++;
403  }
404 
405  // Set boundaries:
406 
407  // Back: boundary 4
408  if (i1 == n_node_1d - 1)
409  {
411 
412  // Set the boundary coordinate
413  Vector<double> zeta(1);
414  zeta[0] =
415  xi_lo + (xi_hi - xi_lo) * double(i0) / double(n_node_1d - 1);
417  4, zeta);
418  }
419 
420  // Upper jaw: boundary 5
421  if (i0 == 0)
422  {
424  }
425  }
426  }
427 
428 
429  // Upper fin: Western/southern row of nodes is duplicate from element 2/1
430  //-----------------------------------------------------------------------
431  e = 3;
432 
433  // Loop over rows in y/s_1-direction
434  for (unsigned i1 = 0; i1 < n_node_1d; i1++)
435  {
436  // Loop over rows in x/s_0-direction
437  for (unsigned i0 = 0; i0 < n_node_1d; i0++)
438  {
439  // Local node number
440  unsigned j_local = i0 + i1 * n_node_1d;
441 
442  // Has the node been killed?
443  bool killed = false;
444 
445  // First vertical row of nodes in s_1 direction get killed
446  // and re-directed to nodes in element 2
447  if (i0 == 0)
448  {
449  // Neighbour element
450  unsigned e_neigh = 2;
451 
452  // Node in neighbour element
453  unsigned i0_neigh = n_node_1d - 1;
454  unsigned i1_neigh = i1;
455  unsigned j_local_neigh = i0_neigh + i1_neigh * n_node_1d;
456 
457 
458  // Check:
459  for (unsigned i = 0; i < 2; i++)
460  {
461  double error = std::fabs(
462  finite_element_pt(e)->node_pt(j_local)->x(i) -
463  finite_element_pt(e_neigh)->node_pt(j_local_neigh)->x(i));
464  if (error > Max_tol_in_node_killing)
465  {
466  oomph_info << "Error in node killing for i " << i << " " << error
467  << std::endl;
468  stopit = true;
469  }
470  }
471 
472  // Kill node
473  delete finite_element_pt(e)->node_pt(j_local);
474  killed = true;
475 
476  // Set pointer to neighbour:
477  finite_element_pt(e)->node_pt(j_local) =
478  finite_element_pt(e_neigh)->node_pt(j_local_neigh);
479  }
480 
481 
482  // First horizontal row of nodes in s_0 direction (apart from
483  // first node get killed and re-directed to nodes in element 1
484  if ((i0 != 0) && (i1 == 0))
485  {
486  // Neighbour element
487  unsigned e_neigh = 1;
488 
489  // Node in neighbour element
490  unsigned i0_neigh = i0;
491  unsigned i1_neigh = n_node_1d - 1;
492  unsigned j_local_neigh = i0_neigh + i1_neigh * n_node_1d;
493 
494 
495  // Check:
496  for (unsigned i = 0; i < 2; i++)
497  {
498  double error = std::fabs(
499  finite_element_pt(e)->node_pt(j_local)->x(i) -
500  finite_element_pt(e_neigh)->node_pt(j_local_neigh)->x(i));
501  if (error > Max_tol_in_node_killing)
502  {
503  oomph_info << "Error in node killing for i " << i << " " << error
504  << std::endl;
505  stopit = true;
506  }
507  }
508 
509  // Kill node
510  delete finite_element_pt(e)->node_pt(j_local);
511  killed = true;
512 
513  // Set pointer to neighbour:
514  finite_element_pt(e)->node_pt(j_local) =
515  finite_element_pt(e_neigh)->node_pt(j_local_neigh);
516  }
517 
518 
519  // No duplicate node: Copy across to mesh
520  if (!killed)
521  {
522  // Now copy the node across
523  Node_pt[node_count] = finite_element_pt(e)->node_pt(j_local);
524 
525  // If we're on the boundary, convert the node into
526  // a boundary node
527  if ((i1 == n_node_1d - 1) || (i0 == n_node_1d - 1))
528  {
529  this->convert_to_boundary_node(Node_pt[node_count]);
530  }
531 
532  // Increment node counter
533  node_count++;
534  }
535 
536  // Set boundaries:
537 
538  // To of tail: boundary 3
539  if (i1 == n_node_1d - 1)
540  {
542  }
543 
544 
545  // Vertical bit of tail: boundary 2
546  if (i0 == n_node_1d - 1)
547  {
549  }
550  }
551  }
552 
553  // Terminate if there's been an error
554  if (stopit)
555  {
556  std::ostringstream error_message;
557  error_message << "Error occured in node killing!\n";
558  error_message
559  << "Max. permitted difference in position of the two nodes\n "
560  << "that get 'merged' : " << Max_tol_in_node_killing << std::endl;
561 
562  throw OomphLibError(
563  error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
564  }
565 
566 
567  // Loop over all elements and set macro element pointer
568  unsigned n_element = this->nelement();
569  for (unsigned e = 0; e < n_element; e++)
570  {
571  // Get pointer to element
572  FiniteElement* el_pt = this->finite_element_pt(e);
573 
574  // Set pointer to macro element to enable MacroElement-based
575  // remesh. Also enables the curvlinear boundaries
576  // of the mesh/domain get picked up during adaptive
577  // mesh refinement in derived classes.
578  el_pt->set_macro_elem_pt(this->Domain_pt->macro_element_pt(e));
579  }
580 
581 
582  // Setup boundary element lookup schemes
584 
585 
586  // Check the boundary coordinates
587 #ifdef PARANOID
588  {
589  Vector<double> zeta(1);
590  Vector<double> r(2);
591  bool stopit = false;
592  unsigned num_bound = nboundary();
593  for (unsigned ibound = 0; ibound < num_bound; ibound++)
594  {
595  if (boundary_coordinate_exists(ibound))
596  {
597  unsigned num_nod = nboundary_node(ibound);
598  for (unsigned inod = 0; inod < num_nod; inod++)
599  {
600  // Get the boundary coordinate
601  boundary_node_pt(ibound, inod)
603 
604  // Get position from wall object
605  Back_pt->position(zeta, r);
606 
607  // Flip it
608  if (ibound == 0) r[1] = -r[1];
609 
610  // Check:
611  for (unsigned i = 0; i < 2; i++)
612  {
613  double error =
614  std::fabs(r[i] - boundary_node_pt(ibound, inod)->x(i));
615  if (error > Max_tol_in_node_killing)
616  {
617  oomph_info << "Error in boundary coordinate for direction " << i
618  << " on boundary " << ibound << ":" << error
619  << std::endl;
620 
621  oomph_info << "x: " << r[0] << " "
622  << boundary_node_pt(ibound, inod)->x(0) << std::endl;
623 
624  oomph_info << "y: " << r[1] << " "
625  << boundary_node_pt(ibound, inod)->x(1) << std::endl
626  << std::endl;
627  stopit = true;
628  }
629  }
630  }
631  }
632  }
633 
634  // Terminate if there's been an error
635  if (stopit)
636  {
637  std::ostringstream error_message;
638  error_message << "Error occured in boundary coordinate setup!\n";
639  error_message << "Max. tolerance: " << Max_tol_in_node_killing
640  << std::endl;
641 
642  throw OomphLibError(error_message.str(),
645  }
646  }
647 #endif
648  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
void output(const std::string &filename, const unsigned &nplot)
Output macro elements.
Definition: domain.h:129
MacroElement * macro_element_pt(const unsigned &i)
Access to i-th macro element.
Definition: domain.h:116
void output_macro_element_boundaries(const std::string &filename, const unsigned &nplot)
Output all macro element boundaries as tecplot zones.
Definition: domain.h:187
virtual Node * construct_node(const unsigned &n)
Definition: elements.h:2509
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
virtual void local_fraction_of_node(const unsigned &j, Vector< double > &s_fraction)
Definition: elements.cc:3191
FishDomain * Domain_pt
Pointer to domain.
Definition: fish_mesh.template.h:108
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
void macro_map(const Vector< double > &s, Vector< double > &r)
The mapping from local to global coordinates at the current time : r(s)
Definition: macro_element.h:126
void add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
Definition: mesh.cc:243
unsigned long nboundary_node(const unsigned &ibound) const
Return number of nodes on a particular boundary.
Definition: mesh.h:833
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition: mesh.h:183
std::vector< bool > Boundary_coordinate_exists
Definition: mesh.h:190
FiniteElement * finite_element_pt(const unsigned &e) const
Definition: mesh.h:473
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
void convert_to_boundary_node(Node *&node_pt, const Vector< FiniteElement * > &finite_element_pt)
Definition: mesh.cc:2590
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
Definition: mesh.h:436
Node *& boundary_node_pt(const unsigned &b, const unsigned &n)
Return pointer to node n on boundary b.
Definition: mesh.h:493
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition: mesh.h:186
bool boundary_coordinate_exists(const unsigned &i) const
Indicate whether the i-th boundary has an intrinsic coordinate.
Definition: mesh.h:565
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:1060
virtual void set_coordinates_on_boundary(const unsigned &b, const unsigned &k, const Vector< double > &boundary_zeta)
Definition: nodes.cc:2394
virtual void get_coordinates_on_boundary(const unsigned &b, const unsigned &k, Vector< double > &boundary_zeta)
Definition: nodes.cc:2379
void setup_boundary_element_info()
Definition: quad_mesh.h:73
RealScalar s
Definition: level1_cplx_impl.h:130
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
void plot_it(const std::string filename)
Plot "landscape" of residuals (only for 2D problems!)
Definition: spring_contact.cc:211
r
Definition: UniformPSDSelfTest.py:20
Real fabs(const Real &a)
Definition: boostmultiprec.cpp:117
int error
Definition: calibrate.py:297
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
list x
Definition: plotDoE.py:28
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References e(), calibrate::error, boost::multiprecision::fabs(), i, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, GlobalFct::plot_it(), UniformPSDSelfTest::r, s, oomph::FiniteElement::set_macro_elem_pt(), plotDoE::x, oomph::Node::x(), and Eigen::zeta().

Referenced by oomph::FishMesh< ELEMENT >::FishMesh().

◆ domain_pt()

template<class ELEMENT >
FishDomain*& oomph::FishMesh< ELEMENT >::domain_pt ( )
inline

◆ fish_back_pt()

template<class ELEMENT >
GeomObject*& oomph::FishMesh< ELEMENT >::fish_back_pt ( )
inline

Access function to geom object that represents the fish's back.

80  {
81  return Back_pt;
82  }

References oomph::FishMesh< ELEMENT >::Back_pt.

Member Data Documentation

◆ Back_pt

◆ Domain_pt

template<class ELEMENT >
FishDomain* oomph::FishMesh< ELEMENT >::Domain_pt
protected

◆ Must_kill_fish_back

template<class ELEMENT >
bool oomph::FishMesh< ELEMENT >::Must_kill_fish_back
protected

Do I need to kill the fish back geom object?

Referenced by oomph::FishMesh< ELEMENT >::FishMesh(), and oomph::FishMesh< ELEMENT >::~FishMesh().


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