26 #ifndef OOMPH_BRETHERTON_SPINE_MESH_HEADER
27 #define OOMPH_BRETHERTON_SPINE_MESH_HEADER
44 template<
class ELEMENT,
class INTERFACE_ELEMENT>
69 const unsigned& nhalf,
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);
109 unsigned np = this->finite_element_pt(0)->nnode_1d();
116 Vector<double>& initial_zeta,
117 const Vector<double>& spine_base,
118 const Vector<double>& spine_end);
122 const double& zeta_lo_transition_end,
123 const double& zeta_up_transition_start,
124 const double& zeta_up_transition_end);
130 unsigned n_spine = this->nspine();
131 for (
unsigned i = 0; i < n_spine; i++)
133 this->spine_pt(i)->spine_height_pt()->pin(0);
142 unsigned id = spine_node_pt->node_update_fct_id();
174 std::ostringstream error_message;
175 error_message <<
"Incorrect spine update id " <<
id << std::endl;
177 throw OomphLibError(error_message.str(),
178 OOMPH_CURRENT_FUNCTION,
179 OOMPH_EXCEPTION_LOCATION);
211 double w = spine_node_pt->fraction();
213 double h = spine_node_pt->h();
216 Vector<double> s_lo(1);
217 s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
220 Vector<double> r_wall_lo(2);
221 spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo, r_wall_lo);
224 spine_node_pt->x(0) = r_wall_lo[0];
225 spine_node_pt->x(1) = r_wall_lo[1] + w * h;
234 double w = spine_node_pt->fraction();
236 double h = spine_node_pt->h();
239 Vector<double> s_lo(1);
240 s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
243 Vector<double> r_wall_lo(2);
244 spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo, r_wall_lo);
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,
253 spine_node_pt->spine_pt()->geom_object_pt(2)->position(s_transition_up,
256 Vector<double> spine_centre(2);
258 spine_centre[0] = 0.5 * (r_transition_lo[0] + r_transition_up[0]);
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]);
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;
280 double w = spine_node_pt->fraction();
282 double h = spine_node_pt->h();
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);
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);
295 double vertical_fraction = spine_node_pt->spine_pt()->geom_parameter(2);
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]);
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,
310 spine_node_pt->spine_pt()->geom_object_pt(3)->position(s_transition_up,
313 Vector<double> spine_centre(2);
315 spine_centre[0] = 0.5 * (r_transition_lo[0] + r_transition_up[0]);
323 N[0] = spine_centre[0] - S0[0];
324 N[1] = spine_centre[1] - S0[1];
326 double inv_length = 1.0 / sqrt(N[0] * N[0] + N[1] * N[1]);
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;
338 double w = spine_node_pt->fraction();
340 double h = spine_node_pt->h();
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);
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);
353 double vertical_fraction = spine_node_pt->spine_pt()->geom_parameter(2);
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]);
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,
368 spine_node_pt->spine_pt()->geom_object_pt(3)->position(s_transition_up,
371 Vector<double> spine_centre(2);
373 spine_centre[0] = 0.5 * (r_transition_lo[0] + r_transition_up[0]);
381 N[0] = spine_centre[0] - S0[0];
382 N[1] = spine_centre[1] - S0[1];
384 double inv_length = 1.0 / sqrt(N[0] * N[0] + N[1] * N[1]);
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;
396 double w = spine_node_pt->fraction();
398 double h = spine_node_pt->h();
401 Vector<double> s_up(1);
402 s_up[0] = spine_node_pt->spine_pt()->geom_parameter(0);
405 Vector<double> r_wall_up(2);
406 spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_up, r_wall_up);
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,
415 spine_node_pt->spine_pt()->geom_object_pt(2)->position(s_transition_up,
418 Vector<double> spine_centre(2);
420 spine_centre[0] = 0.5 * (r_transition_lo[0] + r_transition_up[0]);
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]);
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;
443 double w = spine_node_pt->fraction();
445 double h = spine_node_pt->h();
448 Vector<double> s_up(1);
449 s_up[0] = spine_node_pt->spine_pt()->geom_parameter(0);
452 Vector<double> r_wall_up(2);
453 spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_up, r_wall_up);
456 spine_node_pt->x(0) = r_wall_up[0];
457 spine_node_pt->x(1) = r_wall_up[1] - w * h;
467 double w = spine_node_pt->fraction();
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);
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);
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]);
Mesh for 2D Bretherton problem – based on single layer mesh. Templated by spine-ified Navier-Stokes e...
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.
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)
Constructor. Arguments:
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.
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.
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...
FiniteElement *& interface_element_pt(const unsigned long &i)
Access functions for pointers to interface elements.
FiniteElement *& bulk_element_pt(const unsigned long &i)
Access functions for pointers to elements in bulk.
void spine_node_update(SpineNode *spine_node_pt)
General node update function implements pure virtual function defined in SpineMesh base class and per...
ELEMENT * control_element_pt()
Pointer to control element (just under the symmetry line near the bubble tip, so the bubble tip is lo...
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...
////////////////////////////////////////////////////////////////////// //////////////////////////////...