bretherton_spine_mesh.template.h
Go to the documentation of this file.
1 // LIC// ====================================================================
2 // LIC// This file forms part of oomph-lib, the object-oriented,
3 // LIC// multi-physics finite-element library, available
4 // LIC// at http://www.oomph-lib.org.
5 // LIC//
6 // LIC// Copyright (C) 2006-2022 Matthias Heil and Andrew Hazel
7 // LIC//
8 // LIC// This library is free software; you can redistribute it and/or
9 // LIC// modify it under the terms of the GNU Lesser General Public
10 // LIC// License as published by the Free Software Foundation; either
11 // LIC// version 2.1 of the License, or (at your option) any later version.
12 // LIC//
13 // LIC// This library is distributed in the hope that it will be useful,
14 // LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // LIC// Lesser General Public License for more details.
17 // LIC//
18 // LIC// You should have received a copy of the GNU Lesser General Public
19 // LIC// License along with this library; if not, write to the Free Software
20 // LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // LIC// 02110-1301 USA.
22 // LIC//
23 // LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 // LIC//
25 // LIC//====================================================================
26 #ifndef OOMPH_BRETHERTON_SPINE_MESH_HEADER
27 #define OOMPH_BRETHERTON_SPINE_MESH_HEADER
28 
29 
30 // The mesh
33 
34 namespace oomph
35 {
36  //============================================================================
43  //============================================================================
44  template<class ELEMENT, class INTERFACE_ELEMENT>
45  class BrethertonSpineMesh : public SingleLayerSpineMesh<ELEMENT>
46  {
47  public:
65  const unsigned& nx1,
66  const unsigned& nx2,
67  const unsigned& nx3,
68  const unsigned& nh,
69  const unsigned& nhalf,
70  const double& h,
71  GeomObject* lower_wall_pt,
72  GeomObject* upper_wall_pt,
73  const double& zeta_start,
74  const double& zeta_transition_start,
75  const double& zeta_transition_end,
76  const double& zeta_end,
77  TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper);
78 
79 
81  FiniteElement*& interface_element_pt(const unsigned long& i)
82  {
83  return Interface_element_pt[i];
84  }
85 
87  unsigned long ninterface_element() const
88  {
89  return Interface_element_pt.size();
90  }
91 
93  FiniteElement*& bulk_element_pt(const unsigned long& i)
94  {
95  return Bulk_element_pt[i];
96  }
97 
99  unsigned long nbulk() const
100  {
101  return Bulk_element_pt.size();
102  }
103 
104 
108  {
109  unsigned np = this->finite_element_pt(0)->nnode_1d();
110  return 2 * (Nx1 + Nx2 + Nhalf) * (np - 1);
111  }
112 
113 
115  double find_distance_to_free_surface(GeomObject* const& fs_geom_object_pt,
116  Vector<double>& initial_zeta,
117  const Vector<double>& spine_base,
118  const Vector<double>& spine_end);
119 
121  void reposition_spines(const double& zeta_lo_transition_start,
122  const double& zeta_lo_transition_end,
123  const double& zeta_up_transition_start,
124  const double& zeta_up_transition_end);
125 
129  {
130  unsigned n_spine = this->nspine();
131  for (unsigned i = 0; i < n_spine; i++)
132  {
133  this->spine_pt(i)->spine_height_pt()->pin(0);
134  }
135  }
136 
140  void spine_node_update(SpineNode* spine_node_pt)
141  {
142  unsigned id = spine_node_pt->node_update_fct_id();
143  switch (id)
144  {
145  case 0:
146  spine_node_update_film_lower(spine_node_pt);
147  break;
148 
149  case 1:
151  break;
152 
153  case 2:
155  break;
156 
157  case 3:
159  break;
160 
161  case 4:
163  break;
164 
165  case 5:
166  spine_node_update_film_upper(spine_node_pt);
167  break;
168 
169  case 6:
170  spine_node_update_channel(spine_node_pt);
171  break;
172 
173  default:
174  std::ostringstream error_message;
175  error_message << "Incorrect spine update id " << id << std::endl;
176 
177  throw OomphLibError(error_message.str(),
180  }
181  }
182 
183 
188  {
189  return Control_element_pt;
190  }
191 
192 
194  double spine_centre_fraction() const
195  {
196  return *Spine_centre_fraction_pt;
197  }
198 
200  void set_spine_centre_fraction_pt(double* const& fraction_pt)
201  {
202  Spine_centre_fraction_pt = fraction_pt;
203  }
204 
205  protected:
209  {
210  // Get fraction along the spine
211  double w = spine_node_pt->fraction();
212  // Get spine height
213  double h = spine_node_pt->h();
214 
215  // Get wall coordinate
216  Vector<double> s_lo(1);
217  s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
218 
219  // Get position vector to wall
220  Vector<double> r_wall_lo(2);
221  spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo, r_wall_lo);
222 
223  // Update the nodal position
224  spine_node_pt->x(0) = r_wall_lo[0];
225  spine_node_pt->x(1) = r_wall_lo[1] + w * h;
226  }
227 
228 
232  {
233  // Get fraction along the spine
234  double w = spine_node_pt->fraction();
235  // Get spine height
236  double h = spine_node_pt->h();
237 
238  // Get wall coordinate
239  Vector<double> s_lo(1);
240  s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
241 
242  // Get position vector to wall
243  Vector<double> r_wall_lo(2);
244  spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo, r_wall_lo);
245 
246  // Get the spine centre
247  Vector<double> s_transition_lo(1), s_transition_up(1);
248  s_transition_lo[0] = spine_node_pt->spine_pt()->geom_parameter(1);
249  s_transition_up[0] = spine_node_pt->spine_pt()->geom_parameter(2);
250  Vector<double> r_transition_lo(2), r_transition_up(2);
251  spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_transition_lo,
252  r_transition_lo);
253  spine_node_pt->spine_pt()->geom_object_pt(2)->position(s_transition_up,
254  r_transition_up);
255 
256  Vector<double> spine_centre(2);
257  // Horizontal position is always halfway between the walls
258  spine_centre[0] = 0.5 * (r_transition_lo[0] + r_transition_up[0]);
259  // Vertical spine centre is given by fraction between the walls
260  spine_centre[1] =
261  r_transition_lo[1] +
262  spine_centre_fraction() * (r_transition_up[1] - r_transition_lo[1]);
263 
264  // Get vector twoards spine origin
265  Vector<double> N(2);
266  N[0] = spine_centre[0] - r_wall_lo[0];
267  N[1] = spine_centre[1] - r_wall_lo[1];
268  double inv_length = 1.0 / sqrt(N[0] * N[0] + N[1] * N[1]);
269  // Update the nodal position
270  spine_node_pt->x(0) = r_wall_lo[0] + w * h * N[0] * inv_length;
271  spine_node_pt->x(1) = r_wall_lo[1] + w * h * N[1] * inv_length;
272  }
273 
274 
278  {
279  // Get fraction along the spine
280  double w = spine_node_pt->fraction();
281  // Get spine height
282  double h = spine_node_pt->h();
283 
284  // Get local coordinates
285  Vector<double> s_lo(1), s_up(1);
286  s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
287  s_up[0] = spine_node_pt->spine_pt()->geom_parameter(1);
288 
289  // Get position vector to wall
290  Vector<double> r_lo(2), r_up(2);
291  spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo, r_lo);
292  spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_up, r_up);
293 
294  // Get fraction along vertical line across
295  double vertical_fraction = spine_node_pt->spine_pt()->geom_parameter(2);
296 
297  // Origin of spine
298  Vector<double> S0(2);
299  S0[0] = r_lo[0] + vertical_fraction * (r_up[0] - r_lo[0]);
300  S0[1] = r_lo[1] + vertical_fraction * (r_up[1] - r_lo[1]);
301 
302 
303  // Get the spine centre
304  Vector<double> s_transition_lo(1), s_transition_up(1);
305  s_transition_lo[0] = spine_node_pt->spine_pt()->geom_parameter(3);
306  s_transition_up[0] = spine_node_pt->spine_pt()->geom_parameter(4);
307  Vector<double> r_transition_lo(2), r_transition_up(2);
308  spine_node_pt->spine_pt()->geom_object_pt(2)->position(s_transition_lo,
309  r_transition_lo);
310  spine_node_pt->spine_pt()->geom_object_pt(3)->position(s_transition_up,
311  r_transition_up);
312 
313  Vector<double> spine_centre(2);
314  // Horizontal position is always halfway between the walls
315  spine_centre[0] = 0.5 * (r_transition_lo[0] + r_transition_up[0]);
316  // Vertical spine centre is given by fraction between the walls
317  spine_centre[1] =
318  r_transition_lo[1] +
319  spine_centre_fraction() * (r_transition_up[1] - r_transition_lo[1]);
320 
321  // Get vector towards origin
322  Vector<double> N(2);
323  N[0] = spine_centre[0] - S0[0];
324  N[1] = spine_centre[1] - S0[1];
325 
326  double inv_length = 1.0 / sqrt(N[0] * N[0] + N[1] * N[1]);
327  // Update the nodal position
328  spine_node_pt->x(0) = S0[0] + w * h * N[0] * inv_length;
329  spine_node_pt->x(1) = S0[1] + w * h * N[1] * inv_length;
330  }
331 
332 
336  {
337  // Get fraction along the spine
338  double w = spine_node_pt->fraction();
339  // Get spine height
340  double h = spine_node_pt->h();
341 
342  // Get local coordinates
343  Vector<double> s_lo(1), s_up(1);
344  s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
345  s_up[0] = spine_node_pt->spine_pt()->geom_parameter(1);
346 
347  // Get position vector to wall
348  Vector<double> r_lo(2), r_up(2);
349  spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo, r_lo);
350  spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_up, r_up);
351 
352  // Get fraction along vertical line across
353  double vertical_fraction = spine_node_pt->spine_pt()->geom_parameter(2);
354 
355  // Origin of spine
356  Vector<double> S0(2);
357  S0[0] = r_lo[0] + vertical_fraction * (r_up[0] - r_lo[0]);
358  S0[1] = r_lo[1] + vertical_fraction * (r_up[1] - r_lo[1]);
359 
360 
361  // Get the spine centre
362  Vector<double> s_transition_lo(1), s_transition_up(1);
363  s_transition_lo[0] = spine_node_pt->spine_pt()->geom_parameter(3);
364  s_transition_up[0] = spine_node_pt->spine_pt()->geom_parameter(4);
365  Vector<double> r_transition_lo(2), r_transition_up(2);
366  spine_node_pt->spine_pt()->geom_object_pt(2)->position(s_transition_lo,
367  r_transition_lo);
368  spine_node_pt->spine_pt()->geom_object_pt(3)->position(s_transition_up,
369  r_transition_up);
370 
371  Vector<double> spine_centre(2);
372  // Horizontal position is always halfway between the walls
373  spine_centre[0] = 0.5 * (r_transition_lo[0] + r_transition_up[0]);
374  // Vertical spine centre is given by fraction between the walls
375  spine_centre[1] =
376  r_transition_lo[1] +
377  spine_centre_fraction() * (r_transition_up[1] - r_transition_lo[1]);
378 
379  // Get vector towards origin
380  Vector<double> N(2);
381  N[0] = spine_centre[0] - S0[0];
382  N[1] = spine_centre[1] - S0[1];
383 
384  double inv_length = 1.0 / sqrt(N[0] * N[0] + N[1] * N[1]);
385  // Update the nodal position
386  spine_node_pt->x(0) = S0[0] + w * h * N[0] * inv_length;
387  spine_node_pt->x(1) = S0[1] + w * h * N[1] * inv_length;
388  }
389 
390 
394  {
395  // Get fraction along the spine
396  double w = spine_node_pt->fraction();
397  // Get spine height
398  double h = spine_node_pt->h();
399 
400  // Get wall coordinate
401  Vector<double> s_up(1);
402  s_up[0] = spine_node_pt->spine_pt()->geom_parameter(0);
403 
404  // Get position vector to wall
405  Vector<double> r_wall_up(2);
406  spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_up, r_wall_up);
407 
408  // Get the spine centre
409  Vector<double> s_transition_lo(1), s_transition_up(1);
410  s_transition_lo[0] = spine_node_pt->spine_pt()->geom_parameter(1);
411  s_transition_up[0] = spine_node_pt->spine_pt()->geom_parameter(2);
412  Vector<double> r_transition_lo(2), r_transition_up(2);
413  spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_transition_lo,
414  r_transition_lo);
415  spine_node_pt->spine_pt()->geom_object_pt(2)->position(s_transition_up,
416  r_transition_up);
417 
418  Vector<double> spine_centre(2);
419  // Horizontal position is always halfway between the walls
420  spine_centre[0] = 0.5 * (r_transition_lo[0] + r_transition_up[0]);
421  // Vertical spine centre is given by fraction between the walls
422  spine_centre[1] =
423  r_transition_lo[1] +
424  spine_centre_fraction() * (r_transition_up[1] - r_transition_lo[1]);
425 
426  // Get vector towards origin
427  Vector<double> N(2);
428  N[0] = spine_centre[0] - r_wall_up[0];
429  N[1] = spine_centre[1] - r_wall_up[1];
430  double inv_length = 1.0 / sqrt(N[0] * N[0] + N[1] * N[1]);
431 
432  // Update the nodal position
433  spine_node_pt->x(0) = r_wall_up[0] + w * h * N[0] * inv_length;
434  spine_node_pt->x(1) = r_wall_up[1] + w * h * N[1] * inv_length;
435  }
436 
437 
441  {
442  // Get fraction along the spine
443  double w = spine_node_pt->fraction();
444  // Get spine height
445  double h = spine_node_pt->h();
446 
447  // Get wall coordinate
448  Vector<double> s_up(1);
449  s_up[0] = spine_node_pt->spine_pt()->geom_parameter(0);
450 
451  // Get position vector to wall
452  Vector<double> r_wall_up(2);
453  spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_up, r_wall_up);
454 
455  // Update the nodal position
456  spine_node_pt->x(0) = r_wall_up[0];
457  spine_node_pt->x(1) = r_wall_up[1] - w * h;
458  }
459 
460 
465  {
466  // Get fraction along the spine
467  double w = spine_node_pt->fraction();
468 
469  // Get upper and lower local coordinates
470  Vector<double> s_lo(1), s_up(1);
471  s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
472  s_up[0] = spine_node_pt->spine_pt()->geom_parameter(1);
473 
474  // Get position vector to lower wall
475  Vector<double> r_lo(2), r_up(2);
476  spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo, r_lo);
477  spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_up, r_up);
478 
479  // Update the nodal position
480  spine_node_pt->x(0) = r_lo[0] + w * (r_up[0] - r_lo[0]);
481  spine_node_pt->x(1) = r_lo[1] + w * (r_up[1] - r_lo[1]);
482  }
483 
484 
493 
495  unsigned Nx1;
496 
498  unsigned Nx2;
499 
501  unsigned Nx3;
502 
505  unsigned Nhalf;
506 
508  unsigned Nh;
509 
511  double H;
512 
515 
518 
520  double Zeta_start;
521 
523  double Zeta_end;
524 
527 
530 
533 
536 
541 
544 
547  };
548 
549 } // namespace oomph
550 
551 #endif
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
int i
Definition: BiCGSTAB_step_by_step.cpp:9
RowVector3d w
Definition: Matrix_resize_int.cpp:3
Definition: bretherton_spine_mesh.template.h:46
void spine_node_update_film_lower(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:208
GeomObject * Lower_wall_pt
Pointer to geometric object that represents the lower wall.
Definition: bretherton_spine_mesh.template.h:517
void spine_node_update_horizontal_transition_lower(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:231
void reposition_spines(const double &zeta_lo_transition_start, const double &zeta_lo_transition_end, const double &zeta_up_transition_start, const double &zeta_up_transition_end)
Reposition the spines in response to changes in geometry.
Definition: bretherton_spine_mesh.template.cc:1158
BrethertonSpineMesh(const unsigned &nx1, const unsigned &nx2, const unsigned &nx3, const unsigned &nh, const unsigned &nhalf, const double &h, GeomObject *lower_wall_pt, GeomObject *upper_wall_pt, const double &zeta_start, const double &zeta_transition_start, const double &zeta_transition_end, const double &zeta_end, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Definition: bretherton_spine_mesh.template.cc:58
double Zeta_start
Start coordinate on wall.
Definition: bretherton_spine_mesh.template.h:520
double Zeta_transition_end
Wall coordinate of end of transition region.
Definition: bretherton_spine_mesh.template.h:529
unsigned Nhalf
Definition: bretherton_spine_mesh.template.h:505
GeomObject * Upper_wall_pt
Pointer to geometric object that represents the upper wall.
Definition: bretherton_spine_mesh.template.h:514
Vector< FiniteElement * > Bulk_element_pt
Vector of pointers to element in the fluid layer.
Definition: bretherton_spine_mesh.template.h:543
unsigned Nx2
Number of elements along wall in horizontal transition region.
Definition: bretherton_spine_mesh.template.h:498
unsigned Nx3
Number of elements along wall in channel region.
Definition: bretherton_spine_mesh.template.h:501
double Default_spine_centre_fraction
Default spine fraction.
Definition: bretherton_spine_mesh.template.h:535
void set_spine_centre_fraction_pt(double *const &fraction_pt)
Set the pointer to the spine centre's vertial fraction.
Definition: bretherton_spine_mesh.template.h:200
void spine_node_update_film_upper(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:440
double H
Thickness of deposited film.
Definition: bretherton_spine_mesh.template.h:511
unsigned long nbulk() const
Number of elements in bulk.
Definition: bretherton_spine_mesh.template.h:99
unsigned Nh
Number of elements across the deposited film.
Definition: bretherton_spine_mesh.template.h:508
void pin_all_spines()
Definition: bretherton_spine_mesh.template.h:128
void initial_element_reorder()
Definition: bretherton_spine_mesh.template.cc:1028
void spine_node_update_channel(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:464
double spine_centre_fraction() const
Read the value of the spine centre's vertical fraction.
Definition: bretherton_spine_mesh.template.h:194
void spine_node_update_vertical_transition_upper(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:335
Vector< FiniteElement * > Interface_element_pt
Vector of pointers to interface elements.
Definition: bretherton_spine_mesh.template.h:546
ELEMENT * Control_element_pt
Definition: bretherton_spine_mesh.template.h:540
FiniteElement *& interface_element_pt(const unsigned long &i)
Access functions for pointers to interface elements.
Definition: bretherton_spine_mesh.template.h:81
FiniteElement *& bulk_element_pt(const unsigned long &i)
Access functions for pointers to elements in bulk.
Definition: bretherton_spine_mesh.template.h:93
void spine_node_update(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:140
ELEMENT * control_element_pt()
Definition: bretherton_spine_mesh.template.h:187
void spine_node_update_vertical_transition_lower(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:277
void spine_node_update_horizontal_transition_upper(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:393
double Zeta_end
Wall coordinate of end of liquid filled region (inflow)
Definition: bretherton_spine_mesh.template.h:523
double find_distance_to_free_surface(GeomObject *const &fs_geom_object_pt, Vector< double > &initial_zeta, const Vector< double > &spine_base, const Vector< double > &spine_end)
Recalculate the spine lengths after repositioning.
Definition: bretherton_spine_mesh.template.cc:1066
unsigned nfree_surface_spines()
Definition: bretherton_spine_mesh.template.h:107
unsigned long ninterface_element() const
Number of elements on interface.
Definition: bretherton_spine_mesh.template.h:87
double * Spine_centre_fraction_pt
Pointer to vertical fraction of the spine centre.
Definition: bretherton_spine_mesh.template.h:532
unsigned Nx1
Number of elements along wall in deposited film region.
Definition: bretherton_spine_mesh.template.h:495
double Zeta_transition_start
Wall coordinate of start of the transition region.
Definition: bretherton_spine_mesh.template.h:526
void pin(const unsigned &i)
Pin the i-th stored variable.
Definition: nodes.h:385
Definition: elements.h:1313
virtual unsigned nnode_1d() const
Definition: elements.h:2218
Definition: geom_objects.h:101
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
static Steady< 0 > Default_TimeStepper
The Steady Timestepper.
Definition: mesh.h:75
FiniteElement * finite_element_pt(const unsigned &e) const
Definition: mesh.h:473
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:1060
Definition: oomph_definitions.h:222
Definition: single_layer_spine_mesh.template.h:47
unsigned long nspine() const
Return the number of spines in the mesh.
Definition: spines.h:635
Spine *& spine_pt(const unsigned long &i)
Return the i-th spine in the mesh.
Definition: spines.h:623
Definition: spines.h:328
double & h()
Access function to spine height.
Definition: spines.h:397
Spine *& spine_pt()
Access function to spine.
Definition: spines.h:372
unsigned & node_update_fct_id()
Access function to ID of node update function (within specific mesh)
Definition: spines.h:384
double & fraction()
Set reference to fraction along spine.
Definition: spines.h:378
GeomObject *& geom_object_pt(const unsigned &i)
Definition: spines.h:244
double & geom_parameter(const unsigned &i)
Definition: spines.h:287
Data *& spine_height_pt()
Access function to Data object that stores the spine height.
Definition: spines.h:156
Definition: timesteppers.h:231
@ N
Definition: constructor.cpp:22
double S0
Strength of source function in inner region.
Definition: stefan_boltzmann.cc:148
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86