30 #ifndef OOMPH_BRETHERTON_SPINE_MESH_HEADER    31 #define OOMPH_BRETHERTON_SPINE_MESH_HEADER    49 template <
class ELEMENT, 
class INTERFACE_ELEMENT>
    74                      const unsigned &nhalf,
    76                      GeomObject* lower_wall_pt,
    77                      GeomObject* upper_wall_pt,
    78                      const double& zeta_start, 
    79                      const double& zeta_transition_start,
    80                      const double& zeta_transition_end,
    81                      const double& zeta_end,
    82                      TimeStepper* time_stepper_pt=
    83                      &Mesh::Default_TimeStepper);
   105    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);
   139    unsigned id=spine_node_pt->node_update_fct_id();
   171      std::ostringstream error_message;
   172      error_message << 
"Incorrect spine update id " << 
id << std::endl;
   174      throw OomphLibError(error_message.str(),
   175                          OOMPH_CURRENT_FUNCTION,
   176                          OOMPH_EXCEPTION_LOCATION);
   202    double w = spine_node_pt->fraction();
   204    double h = spine_node_pt->h();
   207    Vector<double> s_lo(1);
   208    s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
   211    Vector<double> r_wall_lo(2);
   212    spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo,r_wall_lo);
   215    spine_node_pt->x(0) = r_wall_lo[0];
   216    spine_node_pt->x(1) = r_wall_lo[1] + w*h;
   225    double w = spine_node_pt->fraction();
   227    double h = spine_node_pt->h();
   230    Vector<double> s_lo(1);
   231    s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
   234    Vector<double> r_wall_lo(2);
   235    spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo,r_wall_lo);
   238    Vector<double> s_transition_lo(1), s_transition_up(1);
   239    s_transition_lo[0] = spine_node_pt->spine_pt()->geom_parameter(1);
   240    s_transition_up[0] = spine_node_pt->spine_pt()->geom_parameter(2);
   241    Vector<double> r_transition_lo(2), r_transition_up(2);
   242    spine_node_pt->spine_pt()->geom_object_pt(1)->
   243     position(s_transition_lo,r_transition_lo);
   244    spine_node_pt->spine_pt()->geom_object_pt(2)->
   245     position(s_transition_up,r_transition_up);
   247    Vector<double> spine_centre(2);
   249    spine_centre[0] = 0.5*(r_transition_lo[0] + r_transition_up[0]);
   251    spine_centre[1] = r_transition_lo[1] + 
   256    N[0] = spine_centre[0] - r_wall_lo[0];
   257    N[1] = spine_centre[1] - r_wall_lo[1];
   258    double inv_length=1.0/sqrt(N[0]*N[0]+N[1]*N[1]);
   260    spine_node_pt->x(0) = r_wall_lo[0] + w*h*N[0]*inv_length;
   261    spine_node_pt->x(1) = r_wall_lo[1] + w*h*N[1]*inv_length;
   271    double w = spine_node_pt->fraction();
   273    double h = spine_node_pt->h();
   276    Vector<double> s_lo(1), s_up(1);
   277    s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
   278    s_up[0] = spine_node_pt->spine_pt()->geom_parameter(1);
   281    Vector<double> r_lo(2), r_up(2);
   282    spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo,r_lo);
   283    spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_up,r_up);
   286    double vertical_fraction = spine_node_pt->spine_pt()->geom_parameter(2);
   289    Vector<double> S0(2);
   290    S0[0] = r_lo[0] + vertical_fraction*(r_up[0]-r_lo[0]);
   291    S0[1] = r_lo[1] + vertical_fraction*(r_up[1]-r_lo[1]);
   295    Vector<double> s_transition_lo(1), s_transition_up(1);
   296    s_transition_lo[0] = spine_node_pt->spine_pt()->geom_parameter(3);
   297    s_transition_up[0] = spine_node_pt->spine_pt()->geom_parameter(4);
   298    Vector<double> r_transition_lo(2), r_transition_up(2);
   299    spine_node_pt->spine_pt()->geom_object_pt(2)->
   300     position(s_transition_lo,r_transition_lo);
   301    spine_node_pt->spine_pt()->geom_object_pt(3)->
   302     position(s_transition_up,r_transition_up);
   304    Vector<double> spine_centre(2);
   306    spine_centre[0] = 0.5*(r_transition_lo[0] + r_transition_up[0]);
   308    spine_centre[1] = r_transition_lo[1] + 
   313    N[0] = spine_centre[0] - S0[0];
   314    N[1] = spine_centre[1] - S0[1];
   316    double inv_length=1.0/sqrt(N[0]*N[0]+N[1]*N[1]);
   318    spine_node_pt->x(0) = S0[0] + w*h*N[0]*inv_length;
   319    spine_node_pt->x(1) = S0[1] + w*h*N[1]*inv_length;
   328    double w = spine_node_pt->fraction();
   330    double h = spine_node_pt->h();
   333    Vector<double> s_lo(1), s_up(1);
   334    s_lo[0] = spine_node_pt->spine_pt()->geom_parameter(0);
   335    s_up[0] = spine_node_pt->spine_pt()->geom_parameter(1);
   338    Vector<double> r_lo(2), r_up(2);
   339    spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo,r_lo);
   340    spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_up,r_up);
   343    double vertical_fraction = spine_node_pt->spine_pt()->geom_parameter(2);
   346    Vector<double> S0(2);
   347    S0[0] = r_lo[0] + vertical_fraction*(r_up[0]-r_lo[0]);
   348    S0[1] = r_lo[1] + vertical_fraction*(r_up[1]-r_lo[1]);
   352    Vector<double> s_transition_lo(1), s_transition_up(1);
   353    s_transition_lo[0] = spine_node_pt->spine_pt()->geom_parameter(3);
   354    s_transition_up[0] = spine_node_pt->spine_pt()->geom_parameter(4);
   355    Vector<double> r_transition_lo(2), r_transition_up(2);
   356    spine_node_pt->spine_pt()->geom_object_pt(2)->
   357     position(s_transition_lo,r_transition_lo);
   358    spine_node_pt->spine_pt()->geom_object_pt(3)->
   359     position(s_transition_up,r_transition_up);
   361    Vector<double> spine_centre(2);
   363    spine_centre[0] = 0.5*(r_transition_lo[0] + r_transition_up[0]);
   365    spine_centre[1] = r_transition_lo[1] + 
   370    N[0] = spine_centre[0] - S0[0];
   371    N[1] = spine_centre[1] - S0[1];
   373    double inv_length=1.0/sqrt(N[0]*N[0]+N[1]*N[1]);
   375    spine_node_pt->x(0) = S0[0] + w*h*N[0]*inv_length;
   376    spine_node_pt->x(1) = S0[1] + w*h*N[1]*inv_length;
   386    double w = spine_node_pt->fraction();
   388    double h = spine_node_pt->h();
   391    Vector<double> s_up(1);
   392    s_up[0] = spine_node_pt->spine_pt()->geom_parameter(0);
   395    Vector<double> r_wall_up(2);
   396    spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_up,r_wall_up);
   399    Vector<double> s_transition_lo(1), s_transition_up(1);
   400    s_transition_lo[0] = spine_node_pt->spine_pt()->geom_parameter(1);
   401    s_transition_up[0] = spine_node_pt->spine_pt()->geom_parameter(2);
   402    Vector<double> r_transition_lo(2), r_transition_up(2);
   403    spine_node_pt->spine_pt()->geom_object_pt(1)->
   404     position(s_transition_lo,r_transition_lo);
   405    spine_node_pt->spine_pt()->geom_object_pt(2)->
   406     position(s_transition_up,r_transition_up);
   408    Vector<double> spine_centre(2);
   410    spine_centre[0] = 0.5*(r_transition_lo[0] + r_transition_up[0]);
   412    spine_centre[1] = r_transition_lo[1] + 
   417    N[0]= spine_centre[0] - r_wall_up[0];
   418    N[1]= spine_centre[1] - r_wall_up[1];
   419    double inv_length=1.0/sqrt(N[0]*N[0]+N[1]*N[1]);
   422    spine_node_pt->x(0) = r_wall_up[0] + w*h*N[0]*inv_length;
   423    spine_node_pt->x(1) = r_wall_up[1] + w*h*N[1]*inv_length;
   433    double w = spine_node_pt->fraction();
   435    double h = spine_node_pt->h();
   438    Vector<double> s_up(1);
   439    s_up[0] = spine_node_pt->spine_pt()->geom_parameter(0);
   442    Vector<double> r_wall_up(2);
   443    spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_up,r_wall_up);
   446    spine_node_pt->x(0) = r_wall_up[0];
   447    spine_node_pt->x(1) = r_wall_up[1] - w*h;
   457    double w = spine_node_pt->fraction();
   460    Vector<double> s_lo(1), s_up(1);
   461    s_lo[0]=spine_node_pt->spine_pt()->geom_parameter(0);
   462    s_up[0]=spine_node_pt->spine_pt()->geom_parameter(1);
   465    Vector<double> r_lo(2), r_up(2);
   466    spine_node_pt->spine_pt()->geom_object_pt(0)->position(s_lo,r_lo);
   467    spine_node_pt->spine_pt()->geom_object_pt(1)->position(s_up,r_up);
   470    spine_node_pt->x(0) = r_lo[0] + w*(r_up[0]-r_lo[0]);
   471    spine_node_pt->x(1) = r_lo[1] + w*(r_up[1]-r_lo[1]);
 unsigned Nhalf
Number of elements in vertical transition region (there are twice as many elements across the channel...
double Zeta_end
Wall coordinate of end of liquid filled region (inflow) 
ELEMENT * Control_element_pt
Pointer to control element (just under the symmetry line near the bubble tip; the bubble tip is locat...
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: 
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...
double Zeta_transition_end
Wall coordinate of end of transition region. 
double * Spine_centre_fraction_pt
Pointer to vertical fraction of the spine centre. 
double Default_spine_centre_fraction
Default spine fraction. 
FiniteElement *& bulk_element_pt(const unsigned long &i)
Access functions for pointers to elements in bulk. 
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...
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(SpineNode *spine_node_pt)
General node update function implements pure virtual function defined in SpineMesh base class and per...
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. 
unsigned Nx3
Number of elements along wall in channel region. 
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...
unsigned Nx1
Number of elements along wall in deposited film region. 
double H
Thickness of deposited film. 
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 ...
double Zeta_transition_start
Wall coordinate of start of the transition region. 
unsigned long nbulk() const
Number of elements in bulk. 
double spine_centre_fraction() const
Read the value of the spine centre's vertical fraction. 
unsigned Nh
Number of elements across the deposited film. 
unsigned nfree_surface_spines()
unsigned Nx2
Number of elements along wall in horizontal transition region. 
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 Zeta_start
Start coordinate on wall. 
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 ...
void set_spine_centre_fraction_pt(double *const &fraction_pt)
Set the pointer to the spine centre's vertial fraction. 
unsigned long ninterface_element() const
Number of elements on interface. 
Vector< FiniteElement * > Interface_element_pt
Vector of pointers to interface elements. 
FiniteElement *& interface_element_pt(const unsigned long &i)
Access functions for pointers to interface elements. 
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. 
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. 
GeomObject * Lower_wall_pt
Pointer to geometric object that represents the lower wall. 
void initial_element_reorder()
Initial reordering elements of the elements – before the channel mesh is added. Vertical stacks of e...
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...