oomph::QuarterTubeMesh< ELEMENT > Class Template Reference

#include <quarter_tube_mesh.template.h>

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

Public Member Functions

 QuarterTubeMesh (GeomObject *wall_pt, const Vector< double > &xi_lo, const double &fract_mid, const Vector< double > &xi_hi, const unsigned &nlayer, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
virtual ~QuarterTubeMesh ()
 Destructor: empty. More...
 
GeomObject *& wall_pt ()
 Access function to GeomObject representing wall. More...
 
QuarterTubeDomaindomain_pt ()
 Access function to domain. More...
 
QuarterTubeDomain::BLSquashFctPtbl_squash_fct_pt ()
 
virtual QuarterTubeDomain::AxialSpacingFctPtaxial_spacing_fct_pt ()
 Function pointer for function for axial spacing. More...
 
QuarterTubeDomaindomain_pt () const
 Access function to underlying domain. More...
 
- Public Member Functions inherited from oomph::BrickMeshBase
 BrickMeshBase ()
 Constructor (empty) More...
 
 BrickMeshBase (const BrickMeshBase &)=delete
 Broken copy constructor. More...
 
virtual ~BrickMeshBase ()
 Broken assignment operator. 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 Attributes

QuarterTubeDomainDomain_pt
 Pointer to domain. More...
 
GeomObjectWall_pt
 Pointer to the geometric object that represents the curved wall. More...
 
Vector< doubleXi_lo
 Lower limits for the coordinates along the wall. More...
 
double Fract_mid
 Fraction along wall where outer ring is to be divided. More...
 
Vector< doubleXi_hi
 Upper limits for the coordinates along the wall. 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...
 
- 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)
 

Detailed Description

template<class ELEMENT>
class oomph::QuarterTubeMesh< ELEMENT >

3D quarter tube mesh class. The domain is specified by the GeomObject that identifies boundary 3. Non-refineable base version!

The mesh boundaries are numbered as follows:

  • Boundary 0: "Inflow" cross section; located along the line parametrised by \( \xi_0 = \xi_0^{lo} \) on the geometric object that specifies the wall.
  • Boundary 1: Plane x=0
  • Boundary 2: Plane y=0
  • Boundary 3: The curved wall
  • Boundary 4: "Outflow" cross section; located along the line parametrised by \( \xi_0 = \xi_0^{hi} \) on the geometric object that specifies the wall.

IMPORTANT NOTE: The interface looks more general than it should. The toplogy must remain that of a quarter tube, or the mesh generation will break.

Constructor & Destructor Documentation

◆ QuarterTubeMesh()

template<class ELEMENT >
oomph::QuarterTubeMesh< ELEMENT >::QuarterTubeMesh ( GeomObject wall_pt,
const Vector< double > &  xi_lo,
const double fract_mid,
const Vector< double > &  xi_hi,
const unsigned nlayer,
TimeStepper time_stepper_pt = &Mesh::Default_TimeStepper 
)

Constructor: Pass pointer to geometric object that specifies the wall, start and end coordinates on the geometric object, and the fraction along which the dividing line is to be placed, and the timestepper. Timestepper defaults to Steady dummy timestepper.

Constructor for deformable quarter tube mesh class. The domain is specified by the GeomObject that identifies boundary 3. Pass pointer to geometric object that specifies the wall, start and end coordinates on the geometric object, and the fraction along which the dividing line is to be placed, and the timestepper. Timestepper defaults to Static dummy timestepper.

50  : Wall_pt(wall_pt), Xi_lo(xi_lo), Fract_mid(fract_mid), Xi_hi(xi_hi)
51  {
52  // Mesh can only be built with 3D Qelements.
53  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(3);
54 
55  // Build macro element-based domain
56  Domain_pt = new QuarterTubeDomain(wall_pt, xi_lo, fract_mid, xi_hi, nlayer);
57 
58  // Set the number of boundaries
59  set_nboundary(5);
60 
61  // We have only bothered to parametrise boundary 3
63 
64  // Allocate the store for the elements
65  unsigned nelem = 3 * nlayer;
66  Element_pt.resize(nelem);
67 
68  // Create dummy element so we can determine the number of nodes
69  ELEMENT* dummy_el_pt = new ELEMENT;
70 
71  // Read out the number of linear points in the element
72  unsigned n_p = dummy_el_pt->nnode_1d();
73 
74  // Kill the element
75  delete dummy_el_pt;
76 
77  // Can now allocate the store for the nodes
78  unsigned nnodes_total =
79  (n_p * n_p + (n_p - 1) * n_p + (n_p - 1) * (n_p - 1)) *
80  (1 + nlayer * (n_p - 1));
81  Node_pt.resize(nnodes_total);
82 
83 
84  Vector<double> s(3);
85  Vector<double> r(3);
86 
87  // Storage for the intrinsic boundary coordinate
88  Vector<double> zeta(2);
89 
90  // Loop over elements and create all nodes
91  for (unsigned ielem = 0; ielem < nelem; ielem++)
92  {
93  // Create element
94  Element_pt[ielem] = new ELEMENT;
95 
96  // Loop over rows in z/s_2-direction
97  for (unsigned i2 = 0; i2 < n_p; i2++)
98  {
99  // Loop over rows in y/s_1-direction
100  for (unsigned i1 = 0; i1 < n_p; i1++)
101  {
102  // Loop over rows in x/s_0-direction
103  for (unsigned i0 = 0; i0 < n_p; i0++)
104  {
105  // Local node number
106  unsigned jnod_local = i0 + i1 * n_p + i2 * n_p * n_p;
107 
108  // Create the node
109  Node* node_pt = finite_element_pt(ielem)->construct_node(
110  jnod_local, time_stepper_pt);
111 
112  // Set the position of the node from macro element mapping
113  s[0] = -1.0 + 2.0 * double(i0) / double(n_p - 1);
114  s[1] = -1.0 + 2.0 * double(i1) / double(n_p - 1);
115  s[2] = -1.0 + 2.0 * double(i2) / double(n_p - 1);
117 
118  node_pt->x(0) = r[0];
119  node_pt->x(1) = r[1];
120  node_pt->x(2) = r[2];
121  }
122  }
123  }
124  }
125 
126  // Initialise number of global nodes
127  unsigned node_count = 0;
128 
129  // Tolerance for node killing:
130  double node_kill_tol = 1.0e-12;
131 
132  // Check for error in node killing
133  bool stopit = false;
134 
135  // Loop over elements
136  for (unsigned ielem = 0; ielem < nelem; ielem++)
137  {
138  // Which layer?
139  unsigned ilayer = unsigned(ielem / 3);
140 
141  // Which macro element?
142  switch (ielem % 3)
143  {
144  // Macro element 0: Central box
145  //-----------------------------
146  case 0:
147 
148 
149  // Loop over rows in z/s_2-direction
150  for (unsigned i2 = 0; i2 < n_p; i2++)
151  {
152  // Loop over rows in y/s_1-direction
153  for (unsigned i1 = 0; i1 < n_p; i1++)
154  {
155  // Loop over rows in x/s_0-direction
156  for (unsigned i0 = 0; i0 < n_p; i0++)
157  {
158  // Local node number
159  unsigned jnod_local = i0 + i1 * n_p + i2 * n_p * n_p;
160 
161  // Has the node been killed?
162  bool killed = false;
163 
164  // First layer of all nodes in s_2 direction gets killed
165  // and re-directed to nodes in previous element layer
166  if ((i2 == 0) && (ilayer > 0))
167  {
168  // Neighbour element
169  unsigned ielem_neigh = ielem - 3;
170 
171  // Node in neighbour element
172  unsigned i0_neigh = i0;
173  unsigned i1_neigh = i1;
174  unsigned i2_neigh = n_p - 1;
175  unsigned jnod_local_neigh =
176  i0_neigh + i1_neigh * n_p + i2_neigh * n_p * n_p;
177 
178  // Check:
179  for (unsigned i = 0; i < 3; i++)
180  {
181  double error = std::fabs(
182  finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
183  finite_element_pt(ielem_neigh)
184  ->node_pt(jnod_local_neigh)
185  ->x(i));
186  if (error > node_kill_tol)
187  {
188  oomph_info << "Error in node killing for i " << i << " "
189  << error << std::endl;
190  stopit = true;
191  }
192  }
193 
194  // Kill node
195  delete finite_element_pt(ielem)->node_pt(jnod_local);
196  killed = true;
197 
198  // Set pointer to neighbour:
199  finite_element_pt(ielem)->node_pt(jnod_local) =
200  finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
201  }
202 
203  // No duplicate node: Copy across to mesh
204  if (!killed)
205  {
206  Node_pt[node_count] =
207  finite_element_pt(ielem)->node_pt(jnod_local);
208 
209  // Set boundaries:
210 
211  // Back: Boundary 0
212  if ((i2 == 0) && (ilayer == 0))
213  {
214  this->convert_to_boundary_node(Node_pt[node_count]);
215  add_boundary_node(0, Node_pt[node_count]);
216  }
217 
218  // Front: Boundary 4
219  if ((i2 == n_p - 1) && (ilayer == nlayer - 1))
220  {
221  this->convert_to_boundary_node(Node_pt[node_count]);
222  add_boundary_node(4, Node_pt[node_count]);
223  }
224 
225  // Left symmetry plane: Boundary 1
226  if (i0 == 0)
227  {
228  this->convert_to_boundary_node(Node_pt[node_count]);
229  add_boundary_node(1, Node_pt[node_count]);
230  }
231 
232  // Bottom symmetry plane: Boundary 2
233  if (i1 == 0)
234  {
235  this->convert_to_boundary_node(Node_pt[node_count]);
236  add_boundary_node(2, Node_pt[node_count]);
237  }
238 
239  // Increment node counter
240  node_count++;
241  }
242  }
243  }
244  }
245 
246 
247  break;
248 
249  // Macro element 1: Lower right box
250  //---------------------------------
251  case 1:
252 
253 
254  // Loop over rows in z/s_2-direction
255  for (unsigned i2 = 0; i2 < n_p; i2++)
256  {
257  // Loop over rows in y/s_1-direction
258  for (unsigned i1 = 0; i1 < n_p; i1++)
259  {
260  // Loop over rows in x/s_0-direction
261  for (unsigned i0 = 0; i0 < n_p; i0++)
262  {
263  // Local node number
264  unsigned jnod_local = i0 + i1 * n_p + i2 * n_p * n_p;
265 
266  // Has the node been killed?
267  bool killed = false;
268 
269  // First layer of all nodes in s_2 direction gets killed
270  // and re-directed to nodes in previous element layer
271  if ((i2 == 0) && (ilayer > 0))
272  {
273  // Neighbour element
274  unsigned ielem_neigh = ielem - 3;
275 
276  // Node in neighbour element
277  unsigned i0_neigh = i0;
278  unsigned i1_neigh = i1;
279  unsigned i2_neigh = n_p - 1;
280  unsigned jnod_local_neigh =
281  i0_neigh + i1_neigh * n_p + i2_neigh * n_p * n_p;
282 
283 
284  // Check:
285  for (unsigned i = 0; i < 3; i++)
286  {
287  double error = std::fabs(
288  finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
289  finite_element_pt(ielem_neigh)
290  ->node_pt(jnod_local_neigh)
291  ->x(i));
292  if (error > node_kill_tol)
293  {
294  oomph_info << "Error in node killing for i " << i << " "
295  << error << std::endl;
296  stopit = true;
297  }
298  }
299 
300  // Kill node
301  delete finite_element_pt(ielem)->node_pt(jnod_local);
302  killed = true;
303 
304  // Set pointer to neighbour:
305  finite_element_pt(ielem)->node_pt(jnod_local) =
306  finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
307  }
308  // Not in first layer:
309  else
310  {
311  // Duplicate node: kill and set pointer to central element
312  if (i0 == 0)
313  {
314  // Neighbour element
315  unsigned ielem_neigh = ielem - 1;
316 
317  // Node in neighbour element
318  unsigned i0_neigh = n_p - 1;
319  unsigned i1_neigh = i1;
320  unsigned i2_neigh = i2;
321  unsigned jnod_local_neigh =
322  i0_neigh + i1_neigh * n_p + i2_neigh * n_p * n_p;
323 
324 
325  // Check:
326  for (unsigned i = 0; i < 3; i++)
327  {
328  double error = std::fabs(
329  finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
330  finite_element_pt(ielem_neigh)
331  ->node_pt(jnod_local_neigh)
332  ->x(i));
333  if (error > node_kill_tol)
334  {
335  oomph_info << "Error in node killing for i " << i << " "
336  << error << std::endl;
337  stopit = true;
338  }
339  }
340 
341  // Kill node
342  delete finite_element_pt(ielem)->node_pt(jnod_local);
343  killed = true;
344 
345  // Set pointer to neighbour:
346  finite_element_pt(ielem)->node_pt(jnod_local) =
347  finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
348  }
349  }
350 
351  // No duplicate node: Copy across to mesh
352  if (!killed)
353  {
354  Node_pt[node_count] =
355  finite_element_pt(ielem)->node_pt(jnod_local);
356 
357  // Set boundaries:
358 
359  // Back: Boundary 0
360  if ((i2 == 0) && (ilayer == 0))
361  {
362  this->convert_to_boundary_node(Node_pt[node_count]);
363  add_boundary_node(0, Node_pt[node_count]);
364  }
365 
366  // Front: Boundary 4
367  if ((i2 == n_p - 1) && (ilayer == nlayer - 1))
368  {
369  this->convert_to_boundary_node(Node_pt[node_count]);
370  add_boundary_node(4, Node_pt[node_count]);
371  }
372 
373  // Bottom symmetry plane: Boundary 2
374  if (i1 == 0)
375  {
376  this->convert_to_boundary_node(Node_pt[node_count]);
377  add_boundary_node(2, Node_pt[node_count]);
378  }
379 
380  // Tube wall: Boundary 3
381  if (i0 == n_p - 1)
382  {
383  this->convert_to_boundary_node(Node_pt[node_count]);
384  add_boundary_node(3, Node_pt[node_count]);
385 
386 
387  // Get axial boundary coordinate
388  zeta[0] = Xi_lo[0] +
389  (double(ilayer) + double(i2) / double(n_p - 1)) *
390  (Xi_hi[0] - Xi_lo[0]) / double(nlayer);
391 
392  // Get azimuthal boundary coordinate
393  zeta[1] = Xi_lo[1] + double(i1) / double(n_p - 1) * 0.5 *
394  (Xi_hi[1] - Xi_lo[1]);
395 
396  Node_pt[node_count]->set_coordinates_on_boundary(3, zeta);
397  }
398 
399  // Increment node counter
400  node_count++;
401  }
402  }
403  }
404  }
405 
406  break;
407 
408 
409  // Macro element 2: Top left box
410  //--------------------------------
411  case 2:
412 
413  // Loop over rows in z/s_2-direction
414  for (unsigned i2 = 0; i2 < n_p; i2++)
415  {
416  // Loop over rows in y/s_1-direction
417  for (unsigned i1 = 0; i1 < n_p; i1++)
418  {
419  // Loop over rows in x/s_0-direction
420  for (unsigned i0 = 0; i0 < n_p; i0++)
421  {
422  // Local node number
423  unsigned jnod_local = i0 + i1 * n_p + i2 * n_p * n_p;
424 
425  // Has the node been killed?
426  bool killed = false;
427 
428  // First layer of all nodes in s_2 direction gets killed
429  // and re-directed to nodes in previous element layer
430  if ((i2 == 0) && (ilayer > 0))
431  {
432  // Neighbour element
433  unsigned ielem_neigh = ielem - 3;
434 
435  // Node in neighbour element
436  unsigned i0_neigh = i0;
437  unsigned i1_neigh = i1;
438  unsigned i2_neigh = n_p - 1;
439  unsigned jnod_local_neigh =
440  i0_neigh + i1_neigh * n_p + i2_neigh * n_p * n_p;
441 
442  // Check:
443  for (unsigned i = 0; i < 3; i++)
444  {
445  double error = std::fabs(
446  finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
447  finite_element_pt(ielem_neigh)
448  ->node_pt(jnod_local_neigh)
449  ->x(i));
450  if (error > node_kill_tol)
451  {
452  oomph_info << "Error in node killing for i " << i << " "
453  << error << std::endl;
454  stopit = true;
455  }
456  }
457 
458  // Kill node
459  delete finite_element_pt(ielem)->node_pt(jnod_local);
460  killed = true;
461 
462  // Set pointer to neighbour:
463  finite_element_pt(ielem)->node_pt(jnod_local) =
464  finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
465  }
466  // Not in first layer:
467  else
468  {
469  // Duplicate node: kill and set pointer to node in bottom
470  // right element
471  if (i0 == n_p - 1)
472  {
473  // Neighbour element
474  unsigned ielem_neigh = ielem - 1;
475 
476  // Node in neighbour element
477  unsigned i0_neigh = i1;
478  unsigned i1_neigh = n_p - 1;
479  unsigned i2_neigh = i2;
480  unsigned jnod_local_neigh =
481  i0_neigh + i1_neigh * n_p + i2_neigh * n_p * n_p;
482 
483  // Check:
484  for (unsigned i = 0; i < 3; i++)
485  {
486  double error = std::fabs(
487  finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
488  finite_element_pt(ielem_neigh)
489  ->node_pt(jnod_local_neigh)
490  ->x(i));
491  if (error > node_kill_tol)
492  {
493  oomph_info << "Error in node killing for i " << i << " "
494  << error << std::endl;
495  stopit = true;
496  }
497  }
498 
499  // Kill node
500  delete finite_element_pt(ielem)->node_pt(jnod_local);
501  killed = true;
502 
503  // Set pointer to neighbour:
504  finite_element_pt(ielem)->node_pt(jnod_local) =
505  finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
506  }
507 
508 
509  // Duplicate node: kill and set pointer to central element
510  if ((i1 == 0) && (i0 != n_p - 1))
511  {
512  // Neighbour element
513  unsigned ielem_neigh = ielem - 2;
514 
515  // Node in neighbour element
516  unsigned i0_neigh = i0;
517  unsigned i1_neigh = n_p - 1;
518  unsigned i2_neigh = i2;
519  unsigned jnod_local_neigh =
520  i0_neigh + i1_neigh * n_p + i2_neigh * n_p * n_p;
521 
522  // Check:
523  for (unsigned i = 0; i < 3; i++)
524  {
525  double error = std::fabs(
526  finite_element_pt(ielem)->node_pt(jnod_local)->x(i) -
527  finite_element_pt(ielem_neigh)
528  ->node_pt(jnod_local_neigh)
529  ->x(i));
530  if (error > node_kill_tol)
531  {
532  oomph_info << "Error in node killing for i " << i << " "
533  << error << std::endl;
534  stopit = true;
535  }
536  }
537 
538  // Kill node
539  delete finite_element_pt(ielem)->node_pt(jnod_local);
540  killed = true;
541 
542  // Set pointer to neighbour:
543  finite_element_pt(ielem)->node_pt(jnod_local) =
544  finite_element_pt(ielem_neigh)->node_pt(jnod_local_neigh);
545  }
546 
547  // No duplicate node: Copy across to mesh
548  if (!killed)
549  {
550  Node_pt[node_count] =
551  finite_element_pt(ielem)->node_pt(jnod_local);
552 
553  // Set boundaries:
554 
555  // Back: Boundary 0
556  if ((i2 == 0) && (ilayer == 0))
557  {
558  this->convert_to_boundary_node(Node_pt[node_count]);
559  add_boundary_node(0, Node_pt[node_count]);
560  }
561 
562  // Front: Boundary 4
563  if ((i2 == n_p - 1) && (ilayer == nlayer - 1))
564  {
565  this->convert_to_boundary_node(Node_pt[node_count]);
566  add_boundary_node(4, Node_pt[node_count]);
567  }
568 
569  // Left symmetry plane: Boundary 1
570  if (i0 == 0)
571  {
572  this->convert_to_boundary_node(Node_pt[node_count]);
573  add_boundary_node(1, Node_pt[node_count]);
574  }
575 
576 
577  // Tube wall: Boundary 3
578  if (i1 == n_p - 1)
579  {
580  this->convert_to_boundary_node(Node_pt[node_count]);
581  add_boundary_node(3, Node_pt[node_count]);
582 
583 
584  // Get axial boundary coordinate
585  zeta[0] =
586  Xi_lo[0] +
587  (double(ilayer) + double(i2) / double(n_p - 1)) *
588  (Xi_hi[0] - Xi_lo[0]) / double(nlayer);
589 
590  // Get azimuthal boundary coordinate
591  zeta[1] = Xi_hi[1] - double(i0) / double(n_p - 1) * 0.5 *
592  (Xi_hi[1] - Xi_lo[1]);
593 
594  Node_pt[node_count]->set_coordinates_on_boundary(3, zeta);
595  }
596 
597  // Increment node counter
598  node_count++;
599  }
600  }
601  }
602  }
603  }
604 
605  break;
606  }
607  }
608 
609  // Terminate if there's been an error
610  if (stopit)
611  {
612  std::ostringstream error_stream;
613  error_stream << "Error in killing nodes\n"
614  << "The most probable cause is that the domain is not\n"
615  << "compatible with the mesh.\n"
616  << "For the QuarterTubeMesh, the domain must be\n"
617  << "topologically consistent with a quarter tube with a\n"
618  << "non-curved centreline.\n";
619  throw OomphLibError(
620  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
621  }
622 
623  // Setup boundary element lookup schemes
625  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
void setup_boundary_element_info()
Definition: brick_mesh.h:195
MacroElement * macro_element_pt(const unsigned &i)
Access to i-th macro element.
Definition: domain.h:116
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
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
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
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
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition: mesh.h:186
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:1060
QuarterTubeDomain * Domain_pt
Pointer to domain.
Definition: quarter_tube_mesh.template.h:121
Vector< double > Xi_lo
Lower limits for the coordinates along the wall.
Definition: quarter_tube_mesh.template.h:127
GeomObject * Wall_pt
Pointer to the geometric object that represents the curved wall.
Definition: quarter_tube_mesh.template.h:124
Vector< double > Xi_hi
Upper limits for the coordinates along the wall.
Definition: quarter_tube_mesh.template.h:133
double Fract_mid
Fraction along wall where outer ring is to be divided.
Definition: quarter_tube_mesh.template.h:130
GeomObject *& wall_pt()
Access function to GeomObject representing wall.
Definition: quarter_tube_mesh.template.h:86
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
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 oomph::Mesh::add_boundary_node(), oomph::Mesh::Boundary_coordinate_exists, oomph::FiniteElement::construct_node(), oomph::Mesh::convert_to_boundary_node(), oomph::QuarterTubeMesh< ELEMENT >::Domain_pt, oomph::Mesh::Element_pt, calibrate::error, boost::multiprecision::fabs(), oomph::Mesh::finite_element_pt(), i, oomph::Domain::macro_element_pt(), oomph::MacroElement::macro_map(), oomph::FiniteElement::node_pt(), oomph::Mesh::Node_pt, oomph::Mesh::node_pt(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, UniformPSDSelfTest::r, s, oomph::Mesh::set_nboundary(), oomph::BrickMeshBase::setup_boundary_element_info(), oomph::QuarterTubeMesh< ELEMENT >::wall_pt(), plotDoE::x, oomph::Node::x(), oomph::QuarterTubeMesh< ELEMENT >::Xi_hi, oomph::QuarterTubeMesh< ELEMENT >::Xi_lo, and Eigen::zeta().

◆ ~QuarterTubeMesh()

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

Destructor: empty.

81  {
82  delete Domain_pt;
83  }

References oomph::QuarterTubeMesh< ELEMENT >::Domain_pt.

Member Function Documentation

◆ axial_spacing_fct_pt()

template<class ELEMENT >
virtual QuarterTubeDomain::AxialSpacingFctPt& oomph::QuarterTubeMesh< ELEMENT >::axial_spacing_fct_pt ( )
inlinevirtual

Function pointer for function for axial spacing.

Reimplemented in oomph::AlgebraicRefineableQuarterTubeMesh< ELEMENT >.

109  {
111  }
AxialSpacingFctPt & axial_spacing_fct_pt()
Definition: quarter_tube_domain.h:116

References oomph::QuarterTubeDomain::axial_spacing_fct_pt(), and oomph::QuarterTubeMesh< ELEMENT >::Domain_pt.

◆ bl_squash_fct_pt()

template<class ELEMENT >
QuarterTubeDomain::BLSquashFctPt& oomph::QuarterTubeMesh< ELEMENT >::bl_squash_fct_pt ( )
inline

Function pointer for function that squashes the outer macro elements towards the wall by mapping the input value of the "radial" macro element coordinate to the return value (defined in the underlying Domain object)

102  {
103  return Domain_pt->bl_squash_fct_pt();
104  }
BLSquashFctPt & bl_squash_fct_pt()
Definition: quarter_tube_domain.h:94

References oomph::QuarterTubeDomain::bl_squash_fct_pt(), and oomph::QuarterTubeMesh< ELEMENT >::Domain_pt.

◆ domain_pt() [1/2]

template<class ELEMENT >
QuarterTubeDomain* oomph::QuarterTubeMesh< ELEMENT >::domain_pt ( )
inline

◆ domain_pt() [2/2]

template<class ELEMENT >
QuarterTubeDomain* oomph::QuarterTubeMesh< ELEMENT >::domain_pt ( ) const
inline

Access function to underlying domain.

115  {
116  return Domain_pt;
117  }

References oomph::QuarterTubeMesh< ELEMENT >::Domain_pt.

◆ wall_pt()

template<class ELEMENT >
GeomObject*& oomph::QuarterTubeMesh< ELEMENT >::wall_pt ( )
inline

Member Data Documentation

◆ Domain_pt

◆ Fract_mid

template<class ELEMENT >
double oomph::QuarterTubeMesh< ELEMENT >::Fract_mid
protected

Fraction along wall where outer ring is to be divided.

◆ Wall_pt

template<class ELEMENT >
GeomObject* oomph::QuarterTubeMesh< ELEMENT >::Wall_pt
protected

◆ Xi_hi

template<class ELEMENT >
Vector<double> oomph::QuarterTubeMesh< ELEMENT >::Xi_hi
protected

Upper limits for the coordinates along the wall.

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

◆ Xi_lo

template<class ELEMENT >
Vector<double> oomph::QuarterTubeMesh< ELEMENT >::Xi_lo
protected

Lower limits for the coordinates along the wall.

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


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