26#ifndef OOMPH_BRETHERTON_SPINE_MESH_HEADER
27#define OOMPH_BRETHERTON_SPINE_MESH_HEADER
43 template<
class ELEMENT,
class INTERFACE_ELEMENT>
68 const unsigned& nhalf,
70 GeomObject* lower_wall_pt,
71 GeomObject* upper_wall_pt,
72 const double& zeta_start,
73 const double& zeta_transition_start,
74 const double& zeta_transition_end,
75 const double& zeta_end,
76 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper);
106 unsigned np = this->finite_element_pt(0)->nnode_1d();
112 Vector<double>& initial_zeta,
113 const Vector<double>& spine_base,
114 const Vector<double>& spine_end);
118 const double& zeta_lo_transition_end,
119 const double& zeta_up_transition_start,
120 const double& zeta_up_transition_end);
126 unsigned n_spine = this->nspine();
127 for (
unsigned i = 0; i < n_spine; i++)
129 this->spine_pt(i)->spine_height_pt()->pin(0);
138 unsigned id = spine_node_pt->node_update_fct_id();
170 std::ostringstream error_message;
171 error_message <<
"Incorrect spine update id " <<
id << std::endl;
173 throw OomphLibError(error_message.str(),
174 OOMPH_CURRENT_FUNCTION,
175 OOMPH_EXCEPTION_LOCATION);
207 double w = spine_node_pt->fraction();
209 double h = spine_node_pt->h();
212 Vector<double> s_lo(1);
213 s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
216 Vector<double> r_wall_lo(2);
217 spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo, r_wall_lo);
220 spine_node_pt->x(0) = r_wall_lo[0];
221 spine_node_pt->x(1) = r_wall_lo[1] + w * h;
230 double w = spine_node_pt->fraction();
232 double h = spine_node_pt->h();
235 Vector<double> s_lo(1);
236 s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
239 Vector<double> r_wall_lo(2);
240 spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo, r_wall_lo);
243 Vector<double> s_transition_lo(1), s_transition_up(1);
244 s_transition_lo[0] = spine_node_pt->spine_pt()->geom_parameter(1);
245 s_transition_up[0] = spine_node_pt->spine_pt()->geom_parameter(2);
246 Vector<double> r_transition_lo(2), r_transition_up(2);
247 spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_transition_lo,
249 spine_node_pt->spine_pt()->geom_object_pt(2)->position(s_transition_up,
252 Vector<double> spine_centre(2);
254 spine_centre[0] = 0.5 * (r_transition_lo[0] + r_transition_up[0]);
262 N[0] = spine_centre[0] - r_wall_lo[0];
263 N[1] = spine_centre[1] - r_wall_lo[1];
264 double inv_length = 1.0 / sqrt(N[0] * N[0] + N[1] * N[1]);
266 spine_node_pt->x(0) = r_wall_lo[0] + w * h * N[0] * inv_length;
267 spine_node_pt->x(1) = r_wall_lo[1] + w * h * N[1] * inv_length;
276 double w = spine_node_pt->fraction();
278 double h = spine_node_pt->h();
281 Vector<double> s_lo(1), s_up(1);
282 s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
283 s_up[0] = spine_node_pt->spine_pt()->geom_parameter(1);
286 Vector<double> r_lo(2), r_up(2);
287 spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo, r_lo);
288 spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_up, r_up);
291 double vertical_fraction = spine_node_pt->spine_pt()->geom_parameter(2);
294 Vector<double> S0(2);
295 S0[0] = r_lo[0] + vertical_fraction * (r_up[0] - r_lo[0]);
296 S0[1] = r_lo[1] + vertical_fraction * (r_up[1] - r_lo[1]);
299 Vector<double> s_transition_lo(1), s_transition_up(1);
300 s_transition_lo[0] = spine_node_pt->spine_pt()->geom_parameter(3);
301 s_transition_up[0] = spine_node_pt->spine_pt()->geom_parameter(4);
302 Vector<double> r_transition_lo(2), r_transition_up(2);
303 spine_node_pt->spine_pt()->geom_object_pt(2)->position(s_transition_lo,
305 spine_node_pt->spine_pt()->geom_object_pt(3)->position(s_transition_up,
308 Vector<double> spine_centre(2);
310 spine_centre[0] = 0.5 * (r_transition_lo[0] + r_transition_up[0]);
318 N[0] = spine_centre[0] - S0[0];
319 N[1] = spine_centre[1] - S0[1];
321 double inv_length = 1.0 / sqrt(N[0] * N[0] + N[1] * N[1]);
323 spine_node_pt->x(0) = S0[0] + w * h * N[0] * inv_length;
324 spine_node_pt->x(1) = S0[1] + w * h * N[1] * inv_length;
333 double w = spine_node_pt->fraction();
335 double h = spine_node_pt->h();
338 Vector<double> s_lo(1), s_up(1);
339 s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
340 s_up[0] = spine_node_pt->spine_pt()->geom_parameter(1);
343 Vector<double> r_lo(2), r_up(2);
344 spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo, r_lo);
345 spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_up, r_up);
348 double vertical_fraction = spine_node_pt->spine_pt()->geom_parameter(2);
351 Vector<double> S0(2);
352 S0[0] = r_lo[0] + vertical_fraction * (r_up[0] - r_lo[0]);
353 S0[1] = r_lo[1] + vertical_fraction * (r_up[1] - r_lo[1]);
356 Vector<double> s_transition_lo(1), s_transition_up(1);
357 s_transition_lo[0] = spine_node_pt->spine_pt()->geom_parameter(3);
358 s_transition_up[0] = spine_node_pt->spine_pt()->geom_parameter(4);
359 Vector<double> r_transition_lo(2), r_transition_up(2);
360 spine_node_pt->spine_pt()->geom_object_pt(2)->position(s_transition_lo,
362 spine_node_pt->spine_pt()->geom_object_pt(3)->position(s_transition_up,
365 Vector<double> spine_centre(2);
367 spine_centre[0] = 0.5 * (r_transition_lo[0] + r_transition_up[0]);
375 N[0] = spine_centre[0] - S0[0];
376 N[1] = spine_centre[1] - S0[1];
378 double inv_length = 1.0 / sqrt(N[0] * N[0] + N[1] * N[1]);
380 spine_node_pt->x(0) = S0[0] + w * h * N[0] * inv_length;
381 spine_node_pt->x(1) = S0[1] + w * h * N[1] * inv_length;
390 double w = spine_node_pt->fraction();
392 double h = spine_node_pt->h();
395 Vector<double> s_up(1);
396 s_up[0] = spine_node_pt->spine_pt()->geom_parameter(0);
399 Vector<double> r_wall_up(2);
400 spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_up, r_wall_up);
403 Vector<double> s_transition_lo(1), s_transition_up(1);
404 s_transition_lo[0] = spine_node_pt->spine_pt()->geom_parameter(1);
405 s_transition_up[0] = spine_node_pt->spine_pt()->geom_parameter(2);
406 Vector<double> r_transition_lo(2), r_transition_up(2);
407 spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_transition_lo,
409 spine_node_pt->spine_pt()->geom_object_pt(2)->position(s_transition_up,
412 Vector<double> spine_centre(2);
414 spine_centre[0] = 0.5 * (r_transition_lo[0] + r_transition_up[0]);
422 N[0] = spine_centre[0] - r_wall_up[0];
423 N[1] = spine_centre[1] - r_wall_up[1];
424 double inv_length = 1.0 / sqrt(N[0] * N[0] + N[1] * N[1]);
427 spine_node_pt->x(0) = r_wall_up[0] + w * h * N[0] * inv_length;
428 spine_node_pt->x(1) = r_wall_up[1] + w * h * N[1] * inv_length;
437 double w = spine_node_pt->fraction();
439 double h = spine_node_pt->h();
442 Vector<double> s_up(1);
443 s_up[0] = spine_node_pt->spine_pt()->geom_parameter(0);
446 Vector<double> r_wall_up(2);
447 spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_up, r_wall_up);
450 spine_node_pt->x(0) = r_wall_up[0];
451 spine_node_pt->x(1) = r_wall_up[1] - w * h;
461 double w = spine_node_pt->fraction();
464 Vector<double> s_lo(1), s_up(1);
465 s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
466 s_up[0] = spine_node_pt->spine_pt()->geom_parameter(1);
469 Vector<double> r_lo(2), r_up(2);
470 spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo, r_lo);
471 spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_up, r_up);
474 spine_node_pt->x(0) = r_lo[0] + w * (r_up[0] - r_lo[0]);
475 spine_node_pt->x(1) = r_lo[1] + w * (r_up[1] - r_lo[1]);
Mesh for 2D Bretherton problem – based on single layer mesh. Templated by spine-ified Navier-Stokes e...
FiniteElement *& interface_element_pt(const unsigned long &i)
Access functions for pointers to interface elements.
void spine_node_update_film_lower(SpineNode *spine_node_pt)
Update function for the deposited film region in the lower part of the domain: Vertical spines.
GeomObject * Lower_wall_pt
Pointer to geometric object that represents the lower wall.
void spine_node_update_horizontal_transition_lower(SpineNode *spine_node_pt)
Update function for the horizontal transitition region in the lower part of the domain: Spine points ...
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.
double Zeta_start
Start coordinate on wall.
double Zeta_transition_end
Wall coordinate of end of transition region.
unsigned Nhalf
Number of elements in vertical transition region (there are twice as many elements across the channel...
GeomObject * Upper_wall_pt
Pointer to geometric object that represents the upper wall.
Vector< FiniteElement * > Bulk_element_pt
Vector of pointers to element in the fluid layer.
unsigned Nx2
Number of elements along wall in horizontal transition region.
unsigned Nx3
Number of elements along wall in channel region.
FiniteElement *& bulk_element_pt(const unsigned long &i)
Access functions for pointers to elements in bulk.
double Default_spine_centre_fraction
Default spine fraction.
void set_spine_centre_fraction_pt(double *const &fraction_pt)
Set the pointer to the spine centre's vertial fraction.
void spine_node_update_film_upper(SpineNode *spine_node_pt)
Update function for the deposited film region in the upper part of the domain: Vertical spines.
double H
Thickness of deposited film.
ELEMENT * control_element_pt()
Pointer to control element (just under the symmetry line near the bubble tip, so the bubble tip is lo...
unsigned long nbulk() const
Number of elements in bulk.
unsigned Nh
Number of elements across the deposited film.
void pin_all_spines()
Pin all spines so the mesh can be used for computation without free surfaces.
void initial_element_reorder()
Initial reordering elements of the elements – before the channel mesh is added. Vertical stacks of el...
void spine_node_update_channel(SpineNode *spine_node_pt)
Update function for the nodes in the channel region ahead of the finger tip: Nodes are evenly distrib...
double spine_centre_fraction() const
Read the value of the spine centre's vertical fraction.
void spine_node_update_vertical_transition_upper(SpineNode *spine_node_pt)
Update function for the vertical transitition region in the upper part of the domain: Spine points to...
Vector< FiniteElement * > Interface_element_pt
Vector of pointers to interface elements.
ELEMENT * Control_element_pt
Pointer to control element (just under the symmetry line near the bubble tip; the bubble tip is locat...
void spine_node_update(SpineNode *spine_node_pt)
General node update function implements pure virtual function defined in SpineMesh base class and per...
void spine_node_update_vertical_transition_lower(SpineNode *spine_node_pt)
Update function for the vertical transitition region in the lower part of the domain: Spine points to...
void spine_node_update_horizontal_transition_upper(SpineNode *spine_node_pt)
Update function for the horizontal transitition region in the upper part of the domain: Spine points ...
double Zeta_end
Wall coordinate of end of liquid filled region (inflow)
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.
unsigned nfree_surface_spines()
Number of free-surface spines (i.e. excluding the dummy spines in the channel region)
unsigned long ninterface_element() const
Number of elements on interface.
double * Spine_centre_fraction_pt
Pointer to vertical fraction of the spine centre.
unsigned Nx1
Number of elements along wall in deposited film region.
double Zeta_transition_start
Wall coordinate of start of the transition region.
Single-layer spine mesh class derived from standard 2D mesh. The mesh contains a layer of spinified f...