oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT > Class Template Reference

#include <bretherton_spine_mesh.template.h>

+ Inheritance diagram for oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >:

Public Member Functions

 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)
 
FiniteElement *& interface_element_pt (const unsigned long &i)
 Access functions for pointers to interface elements. More...
 
unsigned long ninterface_element () const
 Number of elements on interface. More...
 
FiniteElement *& bulk_element_pt (const unsigned long &i)
 Access functions for pointers to elements in bulk. More...
 
unsigned long nbulk () const
 Number of elements in bulk. More...
 
unsigned nfree_surface_spines ()
 
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. More...
 
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. More...
 
void pin_all_spines ()
 
void spine_node_update (SpineNode *spine_node_pt)
 
ELEMENT * control_element_pt ()
 
double spine_centre_fraction () const
 Read the value of the spine centre's vertical fraction. More...
 
void set_spine_centre_fraction_pt (double *const &fraction_pt)
 Set the pointer to the spine centre's vertial fraction. More...
 
- Public Member Functions inherited from oomph::SingleLayerSpineMesh< ELEMENT >
 SingleLayerSpineMesh (const unsigned &nx, const unsigned &ny, const double &lx, const double &h, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
 SingleLayerSpineMesh (const unsigned &nx, const unsigned &ny, const double &lx, const double &h, const bool &periodic_in_x, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
- Public Member Functions inherited from oomph::RectangularQuadMesh< ELEMENT >
 RectangularQuadMesh (const unsigned &nx, const unsigned &ny, const double &lx, const double &ly, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
 RectangularQuadMesh (const unsigned &nx, const unsigned &ny, const double &xmin, const double &xmax, const double &ymin, const double &ymax, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
 RectangularQuadMesh (const unsigned &nx, const unsigned &ny, const double &lx, const double &ly, const bool &periodic_in_x, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
 RectangularQuadMesh (const unsigned &nx, const unsigned &ny, const double &xmin, const double &xmax, const double &ymin, const double &ymax, const bool &periodic_in_x, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
const unsignednx () const
 Return number of elements in x direction. More...
 
const unsignedny () const
 Return number of elements in y direction. More...
 
const double x_min () const
 Return the minimum value of x coordinate. More...
 
const double x_max () const
 Return the maximum value of x coordinate. More...
 
const double y_min () const
 Return the minimum value of y coordinate. More...
 
const double y_max () const
 Return the maximum value of y coordinate. More...
 
virtual void element_reorder ()
 
virtual double x_spacing_function (unsigned xelement, unsigned xnode, unsigned yelement, unsigned ynode)
 
virtual double y_spacing_function (unsigned xelement, unsigned xnode, unsigned yelement, unsigned ynode)
 
- Public Member Functions inherited from oomph::QuadMeshBase
 QuadMeshBase ()
 Constructor (empty) More...
 
 QuadMeshBase (const QuadMeshBase &node)=delete
 Broken copy constructor. More...
 
void operator= (const QuadMeshBase &)=delete
 Broken assignment operator. More...
 
virtual ~QuadMeshBase ()
 Destructor (empty) 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 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...
 
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)
 
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...
 
- Public Member Functions inherited from oomph::SpineMesh
virtual ~SpineMesh ()
 Destructor to clean up the memory allocated to the spines. More...
 
Spine *& spine_pt (const unsigned long &i)
 Return the i-th spine in the mesh. More...
 
const Spinespine_pt (const unsigned long &i) const
 Return the i-th spine in the mesh (const version) More...
 
unsigned long nspine () const
 Return the number of spines in the mesh. More...
 
void add_spine_pt (Spine *const &spine_pt)
 Add a spine to the mesh. More...
 
SpineNodenode_pt (const unsigned long &n)
 Return a pointer to the n-th global SpineNode. More...
 
SpineNodeelement_node_pt (const unsigned long &e, const unsigned &n)
 
unsigned long assign_global_spine_eqn_numbers (Vector< double * > &Dof_pt)
 Assign spines to Spine_pt vector of element. More...
 
void describe_spine_dofs (std::ostream &out, const std::string &current_string) const
 
void set_mesh_level_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 
void set_spine_time_stepper (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data)
 Assign time stepper to spines data. More...
 
void set_consistent_pinned_spine_values_for_continuation (ContinuationStorageScheme *const &continuation_stepper_pt)
 
bool does_pointer_correspond_to_spine_data (double *const &parameter_pt)
 
void node_update (const bool &update_all_solid_nodes=false)
 
void dump (std::ofstream &dump_file) const
 Overload the dump function so that the spine data is dumped. More...
 
void read (std::ifstream &restart_file)
 Overload the read function so that the spine data is also read. More...
 

Protected Member Functions

void spine_node_update_film_lower (SpineNode *spine_node_pt)
 
void spine_node_update_horizontal_transition_lower (SpineNode *spine_node_pt)
 
void spine_node_update_vertical_transition_lower (SpineNode *spine_node_pt)
 
void spine_node_update_vertical_transition_upper (SpineNode *spine_node_pt)
 
void spine_node_update_horizontal_transition_upper (SpineNode *spine_node_pt)
 
void spine_node_update_film_upper (SpineNode *spine_node_pt)
 
void spine_node_update_channel (SpineNode *spine_node_pt)
 
void initial_element_reorder ()
 
- Protected Member Functions inherited from oomph::SingleLayerSpineMesh< ELEMENT >
virtual void build_single_layer_mesh (TimeStepper *time_stepper_pt)
 
- Protected Member Functions inherited from oomph::RectangularQuadMesh< ELEMENT >
void build_mesh (TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 Generic mesh construction function: contains all the hard work. More...
 
 RectangularQuadMesh (const unsigned &nx, const unsigned &ny, const double &xmin, const double &xmax, const double &ymin, const double &ymax, const bool &periodic_in_x, const bool &build, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
 
- 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)
 

Protected Attributes

unsigned Nx1
 Number of elements along wall in deposited film region. More...
 
unsigned Nx2
 Number of elements along wall in horizontal transition region. More...
 
unsigned Nx3
 Number of elements along wall in channel region. More...
 
unsigned Nhalf
 
unsigned Nh
 Number of elements across the deposited film. More...
 
double H
 Thickness of deposited film. More...
 
GeomObjectUpper_wall_pt
 Pointer to geometric object that represents the upper wall. More...
 
GeomObjectLower_wall_pt
 Pointer to geometric object that represents the lower wall. More...
 
double Zeta_start
 Start coordinate on wall. More...
 
double Zeta_end
 Wall coordinate of end of liquid filled region (inflow) More...
 
double Zeta_transition_start
 Wall coordinate of start of the transition region. More...
 
double Zeta_transition_end
 Wall coordinate of end of transition region. More...
 
doubleSpine_centre_fraction_pt
 Pointer to vertical fraction of the spine centre. More...
 
double Default_spine_centre_fraction
 Default spine fraction. More...
 
ELEMENT * Control_element_pt
 
Vector< FiniteElement * > Bulk_element_pt
 Vector of pointers to element in the fluid layer. More...
 
Vector< FiniteElement * > Interface_element_pt
 Vector of pointers to interface elements. More...
 
- Protected Attributes inherited from oomph::RectangularQuadMesh< ELEMENT >
unsigned Nx
 Nx: number of elements in x-direction. More...
 
unsigned Ny
 Ny: number of elements in y-direction. More...
 
unsigned Np
 Np: number of (linear) points in the element. More...
 
double Xmin
 Minimum value of x coordinate. More...
 
double Xmax
 Maximum value of x coordinate. More...
 
double Ymin
 Minimum value of y coordinate. More...
 
double Ymax
 Maximum value of y coordinate. More...
 
bool Xperiodic
 
- 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
 
- Protected Attributes inherited from oomph::SpineMesh
Vector< Spine * > Spine_pt
 A Spine mesh contains a Vector of pointers to spines. More...
 

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...
 

Detailed Description

template<class ELEMENT, class INTERFACE_ELEMENT>
class oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >

Mesh for 2D Bretherton problem – based on single layer mesh. Templated by spine-ified Navier-Stokes element type (e.g. SpineElement<QCrouzeixRaviartElement<2> > and the corresponding interface element (e.g. SpineLineFluidInterfaceElement<SpineElement<QCrouzeixRaviartElement<2> > >

Constructor & Destructor Documentation

◆ BrethertonSpineMesh()

template<class ELEMENT , class INTERFACE_ELEMENT >
oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::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:

  • nx1: Number of elements along wall in deposited film region
  • nx2: Number of elements along wall in horizontal transition region
  • nx3: Number of elements along wall in channel region
  • nhalf: Number of elements in vertical transition region (there are twice as many elements across the channel)
  • nh: Number of elements across the deposited film
  • h: Thickness of deposited film
  • zeta0: Start coordinate on wall
  • zeta1: Wall coordinate of start of transition region
  • zeta2: Wall coordinate of end of liquid filled region (inflow)
  • lower_wall_pt: Pointer to geometric object that represents the lower wall
  • upper_wall_pt: Pointer to geometric object that represents the upper wall
  • time_stepper_pt: Pointer to timestepper; defaults to Steady

Constructor. Arguments:

  • nx1: Number of elements along wall in deposited film region
  • nx2: Number of elements along wall in horizontal transition region
  • nx3: Number of elements along wall in channel region
  • nhalf: Number of elements in vertical transition region (there are twice as many elements across the channel)
  • nh: Number of elements across the deposited film
  • h: Thickness of deposited film
  • zeta0: Start coordinate on wall
  • zeta1: Wall coordinate of start of transition region
  • zeta2: Wall coordinate of end of liquid filled region (inflow)
  • lower_wall_pt: Pointer to geometric object that represents the lower wall
  • upper_wall_pt: Pointer to geometric object that represents the upper wall
  • time_stepper_pt: Pointer to timestepper; defaults to Static
72  : SingleLayerSpineMesh<ELEMENT>(
73  2 * (nx1 + nx2 + nhalf), nh, 1.0, h, time_stepper_pt),
74  Nx1(nx1),
75  Nx2(nx2),
76  Nx3(nx3),
77  Nhalf(nhalf),
78  Nh(nh),
79  H(h),
80  Upper_wall_pt(upper_wall_pt),
81  Lower_wall_pt(lower_wall_pt),
82  Zeta_start(zeta_start),
83  Zeta_end(zeta_end),
84  Zeta_transition_start(zeta_transition_start),
85  Zeta_transition_end(zeta_transition_end),
88  {
89  // Add the created elements to the bulk domain
90  unsigned n_bulk = this->nelement();
91  Bulk_element_pt.resize(n_bulk);
92  for (unsigned e = 0; e < n_bulk; e++)
93  {
95  }
96 
97  // Mesh can only be built with 2D Qelements.
98  MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
99 
100  // Mesh can only be built with spine elements
101  MeshChecker::assert_geometric_element<SpineFiniteElement, ELEMENT>(2);
102 
103  // Initialise start of transition region to zero
104  // Zeta_transition_start = 0.0;
105 
106  // Length of deposited film region
107  double llayer = Zeta_transition_start - Zeta_start;
108 
109  // Length of transition region
111 
112  // Work out radius of circular cap from lower and upper wall
113  Vector<double> r_wall_lo(2), r_wall_up(2);
114  Vector<double> zeta(1), s_lo(1), s_up(1);
115  GeomObject *lower_sub_geom_object_pt = 0, *upper_sub_geom_object_pt = 0;
116 
117  GeomObject* lower_transition_geom_object_pt = 0;
118  GeomObject* upper_transition_geom_object_pt = 0;
119  Vector<double> s_transition_lo(1), s_transition_up(1);
120  Vector<double> spine_centre(2);
121 
122  // Find position of lower and upper walls at start of transition region
124  Lower_wall_pt->position(zeta, r_wall_lo);
125  Upper_wall_pt->position(zeta, r_wall_up);
126  // Radius is the difference between the film thickness and the distance
127  // to the lower wall
128  double radius = -r_wall_lo[1] - H;
129 
130  // Check to non-symmetric mesh
131  if (std::fabs(r_wall_lo[1] + r_wall_up[1]) > 1.0e-4)
132  {
133  oomph_info << "\n\n=================================================== "
134  << std::endl;
135  oomph_info << "Warning: " << std::endl;
136  oomph_info << "-------- " << std::endl;
137  oomph_info << " " << std::endl;
138  oomph_info << "Upper and lower walls are not symmetric at zeta=0"
139  << std::endl;
140  oomph_info << "Your initial mesh will look very odd." << std::endl;
141  oomph_info << "y-coordinates of walls at zeta=0 are: " << r_wall_lo[1]
142  << " and " << r_wall_up[1] << std::endl
143  << std::endl;
144  oomph_info << "===================================================\n\n "
145  << std::endl;
146  }
147 
148 
149  // Add the interface elements
150  // Loop over the horizontal elements
151  {
152  unsigned n_x = 2 * (nx1 + nx2 + nhalf);
153  unsigned n_y = nh;
154  for (unsigned i = 0; i < n_x; i++)
155  {
156  // Construct a new 1D line element on the face on which the local
157  // coordinate 1 is fixed at its max. value (1) --- This is face 2
158  FiniteElement* interface_element_element_pt = new INTERFACE_ELEMENT(
159  this->finite_element_pt(n_x * (n_y - 1) + i), 2);
160 
161  // Push it back onto the stack
162  this->Element_pt.push_back(interface_element_element_pt);
163 
164  // Push it back onto the stack of interface elements
165  this->Interface_element_pt.push_back(interface_element_element_pt);
166  }
167  }
168 
169  // Reorder elements: Vertical stacks of elements, each topped by
170  // their interface element -- this is (currently) identical to the
171  // version in the SingleLayerSpineMesh but it's important
172  // that element reordering is maintained in exactly this form
173  // so to be on the safe side, we move the function in here.
175 
176  // Store pointer to control element
177  Control_element_pt = dynamic_cast<ELEMENT*>(
178  this->element_pt((nx1 + nx2 + nhalf) * (nh + 1) - 2));
179 
180  // Temporary storage for boundary lookup scheme
181  Vector<std::set<Node*>> set_boundary_node_pt(6);
182 
183  // Boundary 1 -> 3; 2 -> 4; 3 -> 5
184  for (unsigned ibound = 1; ibound <= 3; ibound++)
185  {
186  unsigned numnod = this->nboundary_node(ibound);
187  for (unsigned j = 0; j < numnod; j++)
188  {
189  set_boundary_node_pt[ibound + 2].insert(
190  this->boundary_node_pt(ibound, j));
191  }
192  }
193 
194  // Get number of nodes per element
195  unsigned nnod = this->finite_element_pt(0)->nnode();
196 
197  // Get number of nodes along element edge
198  unsigned np = this->finite_element_pt(0)->nnode_1d();
199 
200  // Initialise number of elements in previous regions:
201  unsigned n_prev_elements = 0;
202 
203  // We've now built the straight single-layer mesh and need to change the
204  // the update functions for all nodes so that the domain
205  // deforms into the Bretherton shape
206 
207  // Loop over elements in lower deposited film region
208  // -------------------------------------------------
209  {
210  // Increments in wall coordinate
211  double dzeta_el = llayer / double(nx1);
212  double dzeta_node = llayer / double(nx1 * (np - 1));
213 
214  // Loop over elements horizontally
215  for (unsigned i = 0; i < nx1; i++)
216  {
217  // Start of wall coordinate
218  double zeta_lo = Zeta_start + double(i) * dzeta_el;
219 
220  // Loop over elements vertically
221  for (unsigned j = 0; j < nh; j++)
222  {
223  // Work out element number in overall mesh
224  unsigned e = n_prev_elements + i * (nh + 1) + j;
225 
226  // Get pointer to element
227  FiniteElement* el_pt = this->finite_element_pt(e);
228 
229  // Loop over its nodes
230  for (unsigned i0 = 0; i0 < np; i0++)
231  {
232  for (unsigned i1 = 0; i1 < np; i1++)
233  {
234  // Node number:
235  unsigned n = i0 * np + i1;
236 
237  // Get spine node
238  SpineNode* nod_pt = dynamic_cast<SpineNode*>(el_pt->node_pt(n));
239 
240  // Set update fct id
241  nod_pt->node_update_fct_id() = 0;
242 
243  // Provide spine with additional storage for wall coordinate
244  // and wall geom object:
245  if (i0 == 0)
246  {
247  // Get the Lagrangian coordinate in the Lower Wall
248  zeta[0] = zeta_lo + double(i1) * dzeta_node;
249  // Get the geometric object and local coordinate
251  zeta, lower_sub_geom_object_pt, s_lo);
252 
253  // The local coordinate is a geometric parameter
254  // This needs to be set (rather than added) because the
255  // same spine may be visited more than once
256  Vector<double> parameters(1, s_lo[0]);
257  nod_pt->spine_pt()->set_geom_parameter(parameters);
258 
259  // Adjust spine height
260  nod_pt->spine_pt()->height() = H;
261 
262  // The sub geom object is one (and only) geom object
263  // for spine:
264  Vector<GeomObject*> geom_object_pt(1);
265  geom_object_pt[0] = lower_sub_geom_object_pt;
266 
267  // Pass geom object(s) to spine
268  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
269 
270  // Push the node back onto boundaries
271  if (j == 0) set_boundary_node_pt[0].insert(nod_pt);
272  }
273  }
274  }
275  }
276  }
277 
278  // Increment number of previous elements
279  n_prev_elements += nx1 * (nh + 1);
280  }
281 
282  {
283  // Calculate the centre for the spine nodes in the transition region
285  // Get the geometric objects on the walls at the start of the transition
286  // region
288  zeta, lower_transition_geom_object_pt, s_transition_lo);
290  zeta, upper_transition_geom_object_pt, s_transition_up);
291 
292  // Find the Eulerian coordinates of the walls at the transition region
293  lower_transition_geom_object_pt->position(s_transition_lo, r_wall_lo);
294  upper_transition_geom_object_pt->position(s_transition_up, r_wall_up);
295 
296  // Take the average of these positions to define the origin of the spines
297  // in the transition region Horizontal position is always halfway
298  spine_centre[0] = 0.5 * (r_wall_lo[0] + r_wall_up[0]);
299 
300  // Vertical Position is given by a specified fraction
301  // between the upper and lower walls
302  spine_centre[1] =
303  r_wall_lo[1] + spine_centre_fraction() * (r_wall_up[1] - r_wall_lo[1]);
304  }
305 
306 
307  // Loop over elements in lower horizontal transition region
308  // --------------------------------------------------------
309  {
310  // Increments in wall coordinate
311  double dzeta_el = d / double(nx2);
312  double dzeta_node = d / double(nx2 * (np - 1));
313 
314  // Loop over elements horizontally
315  for (unsigned i = 0; i < nx2; i++)
316  {
317  // Start of wall coordinate
318  double zeta_lo = Zeta_transition_start + double(i) * dzeta_el;
319 
320  // Loop over elements vertically
321  for (unsigned j = 0; j < nh; j++)
322  {
323  // Work out element number in overall mesh
324  unsigned e = n_prev_elements + i * (nh + 1) + j;
325 
326  // Get pointer to element
327  FiniteElement* el_pt = this->finite_element_pt(e);
328 
329  // Loop over its nodes
330  for (unsigned i0 = 0; i0 < np; i0++)
331  {
332  for (unsigned i1 = 0; i1 < np; i1++)
333  {
334  // Node number:
335  unsigned n = i0 * np + i1;
336 
337  // Get spine node
338  SpineNode* nod_pt = dynamic_cast<SpineNode*>(el_pt->node_pt(n));
339 
340  // Set update id
341  nod_pt->node_update_fct_id() = 1;
342 
343  // Provide spine with additional storage for wall coordinate
344  if (i0 == 0)
345  {
346  // Get the Lagrangian coordinate in the Lower Wall
347  zeta[0] = zeta_lo + double(i1) * dzeta_node;
348  // Get the sub geometric object and local coordinate
350  zeta, lower_sub_geom_object_pt, s_lo);
351 
352  // Pass geometric parameter to the spine
353  Vector<double> parameters(3);
354  parameters[0] = s_lo[0];
355  parameters[1] = s_transition_lo[0];
356  parameters[2] = s_transition_up[0];
357  nod_pt->spine_pt()->set_geom_parameter(parameters);
358 
359  // Get position vector to wall
360  lower_sub_geom_object_pt->position(s_lo, r_wall_lo);
361 
362  // Get normal vector towards origin
363  Vector<double> N(2);
364  N[0] = spine_centre[0] - r_wall_lo[0];
365  N[1] = spine_centre[1] - r_wall_lo[1];
366  double length = sqrt(N[0] * N[0] + N[1] * N[1]);
367  nod_pt->spine_pt()->height() = length - radius;
368 
369  // Lower sub geom object is one (and only) geom object
370  // for spine:
371  Vector<GeomObject*> geom_object_pt(3);
372  geom_object_pt[0] = lower_sub_geom_object_pt;
373  geom_object_pt[1] = lower_transition_geom_object_pt;
374  geom_object_pt[2] = upper_transition_geom_object_pt;
375 
376  // Pass geom object(s) to spine
377  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
378 
379  // Push the node back onto boundaries
380  if (j == 0) set_boundary_node_pt[0].insert(nod_pt);
381  }
382  }
383  }
384  }
385  }
386 
387  // Increment number of previous elements
388  n_prev_elements += nx2 * (nh + 1);
389  }
390 
391  // Loop over elements in lower vertical transition region
392  // --------------------------------------------------------
393  {
394  for (unsigned i = 0; i < nhalf; i++)
395  {
396  // Loop over elements vertically
397  for (unsigned j = 0; j < nh; j++)
398  {
399  // Work out element number in overall mesh
400  unsigned e = n_prev_elements + i * (nh + 1) + j;
401 
402  // Get pointer to element
403  FiniteElement* el_pt = this->finite_element_pt(e);
404 
405  // Loop over its nodes
406  for (unsigned i0 = 0; i0 < np; i0++)
407  {
408  for (unsigned i1 = 0; i1 < np; i1++)
409  {
410  // Node number:
411  unsigned n = i0 * np + i1;
412 
413  // Get spine node
414  SpineNode* nod_pt = dynamic_cast<SpineNode*>(el_pt->node_pt(n));
415 
416  // Set update id
417  nod_pt->node_update_fct_id() = 2;
418 
419  // Provide spine with additional storage for fraction along
420  // vertical line
421  if (i0 == 0)
422  {
423  // Get position vectors to wall
425  // Get the sub geometric objects
427  zeta, lower_sub_geom_object_pt, s_lo);
429  zeta, upper_sub_geom_object_pt, s_up);
430 
431  lower_sub_geom_object_pt->position(s_lo, r_wall_lo);
432  upper_sub_geom_object_pt->position(s_up, r_wall_up);
433 
434  // Set vertical fraction
435  double vertical_fraction =
436  (double(i) + double(i1) / double(np - 1)) /
437  double(2.0 * nhalf);
438 
439  // Add the geometric parameters in order
440  Vector<double> parameters(5);
441  parameters[0] = s_lo[0];
442  parameters[1] = s_up[0];
443  parameters[2] = vertical_fraction;
444  parameters[3] = s_transition_lo[0];
445  parameters[4] = s_transition_up[0];
446  nod_pt->spine_pt()->set_geom_parameter(parameters);
447 
448  // Origin of spine
449  Vector<double> S0(2);
450  S0[0] = r_wall_lo[0] +
451  vertical_fraction * (r_wall_up[0] - r_wall_lo[0]);
452  S0[1] = r_wall_lo[1] +
453  vertical_fraction * (r_wall_up[1] - r_wall_lo[1]);
454 
455  // Get normal vector towards origin
456  Vector<double> N(2);
457  N[0] = spine_centre[0] - S0[0];
458  N[1] = spine_centre[1] - S0[1];
459 
460  double length = sqrt(N[0] * N[0] + N[1] * N[1]);
461  nod_pt->spine_pt()->height() = length - radius;
462 
463  // Lower and Upper wall sub geom objects affect spine:
464  Vector<GeomObject*> geom_object_pt(4);
465  geom_object_pt[0] = lower_sub_geom_object_pt;
466  geom_object_pt[1] = upper_sub_geom_object_pt;
467  geom_object_pt[2] = lower_transition_geom_object_pt;
468  geom_object_pt[3] = upper_transition_geom_object_pt;
469 
470  // Pass geom object(s) to spine
471  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
472 
473  // Push the node back onto boundaries
474  if (j == 0) set_boundary_node_pt[1].insert(nod_pt);
475  }
476  }
477  }
478  }
479  }
480 
481  // Increment number of previous elements
482  n_prev_elements += nhalf * (nh + 1);
483  }
484 
485 
486  // Loop over elements in upper vertical transition region
487  // ------------------------------------------------------
488  {
489  for (unsigned i = 0; i < nhalf; i++)
490  {
491  // Loop over elements vertically
492  for (unsigned j = 0; j < nh; j++)
493  {
494  // Work out element number in overall mesh
495  unsigned e = n_prev_elements + i * (nh + 1) + j;
496 
497  // Get pointer to element
498  FiniteElement* el_pt = this->finite_element_pt(e);
499 
500  // Loop over its nodes
501  for (unsigned i0 = 0; i0 < np; i0++)
502  {
503  for (unsigned i1 = 0; i1 < np; i1++)
504  {
505  // Node number:
506  unsigned n = i0 * np + i1;
507 
508  // Get spine node
509  SpineNode* nod_pt = dynamic_cast<SpineNode*>(el_pt->node_pt(n));
510 
511  // Set update id
512  nod_pt->node_update_fct_id() = 3;
513 
514  // Provide spine with additional storage for fraction along
515  // vertical line
516  if (i0 == 0)
517  {
518  // Get position vectors to wall
520  // Get the sub geometric objects
522  zeta, lower_sub_geom_object_pt, s_lo);
524  zeta, upper_sub_geom_object_pt, s_up);
525 
526  lower_sub_geom_object_pt->position(s_lo, r_wall_lo);
527  upper_sub_geom_object_pt->position(s_up, r_wall_up);
528 
529  // Set vertical fraction
530  double vertical_fraction =
531  0.5 + (double(i) + double(i1) / double(np - 1)) /
532  double(2.0 * nhalf);
533 
534  // Add the geometric parameters in order
535  Vector<double> parameters(5);
536  parameters[0] = s_lo[0];
537  parameters[1] = s_up[0];
538  parameters[2] = vertical_fraction;
539  parameters[3] = s_transition_lo[0];
540  parameters[4] = s_transition_up[0];
541  nod_pt->spine_pt()->set_geom_parameter(parameters);
542 
543  // Origin of spine
544  Vector<double> S0(2);
545  S0[0] = r_wall_lo[0] +
546  vertical_fraction * (r_wall_up[0] - r_wall_lo[0]);
547  S0[1] = r_wall_lo[1] +
548  vertical_fraction * (r_wall_up[1] - r_wall_lo[1]);
549 
550  // Get normal vector towards origin
551  Vector<double> N(2);
552  N[0] = spine_centre[0] - S0[0];
553  N[1] = spine_centre[1] - S0[1];
554 
555  double length = sqrt(N[0] * N[0] + N[1] * N[1]);
556  nod_pt->spine_pt()->height() = length - radius;
557 
558  // Upper and Lower wall geom objects affect spine
559  Vector<GeomObject*> geom_object_pt(4);
560  geom_object_pt[0] = lower_sub_geom_object_pt;
561  geom_object_pt[1] = upper_sub_geom_object_pt;
562  geom_object_pt[2] = lower_transition_geom_object_pt;
563  geom_object_pt[3] = upper_transition_geom_object_pt;
564 
565  // Pass geom object(s) to spine
566  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
567 
568  // Push the node back onto boundaries
569  if (j == 0) set_boundary_node_pt[1].insert(nod_pt);
570  }
571  }
572  }
573  }
574  }
575  // Increment number of previous elements
576  n_prev_elements += nhalf * (nh + 1);
577  }
578 
579 
580  // Loop over elements in upper horizontal transition region
581  // --------------------------------------------------------
582  {
583  // Increments in wall coordinate
584  double dzeta_el = d / double(nx2);
585  double dzeta_node = d / double(nx2 * (np - 1));
586 
587  // Loop over elements horizontally
588  for (unsigned i = 0; i < nx2; i++)
589  {
590  // Start of wall coordinate
591  double zeta_lo = Zeta_transition_end - double(i) * dzeta_el;
592 
593  // Loop over elements vertically
594  for (unsigned j = 0; j < nh; j++)
595  {
596  // Work out element number in overall mesh
597  unsigned e = n_prev_elements + i * (nh + 1) + j;
598 
599  // Get pointer to element
600  FiniteElement* el_pt = this->finite_element_pt(e);
601 
602  // Loop over its nodes
603  for (unsigned i0 = 0; i0 < np; i0++)
604  {
605  for (unsigned i1 = 0; i1 < np; i1++)
606  {
607  // Node number:
608  unsigned n = i0 * np + i1;
609 
610  // Get spine node
611  SpineNode* nod_pt = dynamic_cast<SpineNode*>(el_pt->node_pt(n));
612 
613  // Set update id
614  nod_pt->node_update_fct_id() = 4;
615 
616  // Provide spine with additional storage for wall coordinate
617  if (i0 == 0)
618  {
619  // Get the Lagrangian coordinate in the Upper wall
620  zeta[0] = zeta_lo - double(i1) * dzeta_node;
621  // Get the sub geometric object and local coordinate
623  zeta, upper_sub_geom_object_pt, s_up);
624 
625  // Pass geometric parameter to spine
626  Vector<double> parameters(3);
627  parameters[0] = s_up[0];
628  parameters[1] = s_transition_lo[0];
629  parameters[2] = s_transition_up[0];
630  nod_pt->spine_pt()->set_geom_parameter(parameters);
631 
632  // Get position vector to wall
633  upper_sub_geom_object_pt->position(s_up, r_wall_up);
634 
635  // Get normal vector towards origin
636  Vector<double> N(2);
637  N[0] = spine_centre[0] - r_wall_up[0];
638  N[1] = spine_centre[1] - r_wall_up[1];
639  double length = sqrt(N[0] * N[0] + N[1] * N[1]);
640  nod_pt->spine_pt()->height() = length - radius;
641 
642  // upper wall sub geom object is one (and only) geom object
643  // for spine:
644  Vector<GeomObject*> geom_object_pt(3);
645  geom_object_pt[0] = upper_sub_geom_object_pt;
646  geom_object_pt[1] = lower_transition_geom_object_pt;
647  geom_object_pt[2] = upper_transition_geom_object_pt;
648 
649  // Pass geom object(s) to spine
650  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
651 
652  // Push the node back onto boundaries
653  if (j == 0) set_boundary_node_pt[2].insert(nod_pt);
654  }
655  }
656  }
657  }
658  }
659 
660  // Increment number of previous elements
661  n_prev_elements += nx2 * (nh + 1);
662  }
663 
664 
665  // Loop over elements in upper deposited film region
666  // -------------------------------------------------
667  {
668  // Increments in wall coordinate
669  double dzeta_el = llayer / double(nx1);
670  double dzeta_node = llayer / double(nx1 * (np - 1));
671 
672  // Loop over elements horizontally
673  for (unsigned i = 0; i < nx1; i++)
674  {
675  // Start of wall coordinate
676  double zeta_lo = Zeta_transition_start - double(i) * dzeta_el;
677 
678  // Loop over elements vertically
679  for (unsigned j = 0; j < nh; j++)
680  {
681  // Work out element number in overall mesh
682  unsigned e = n_prev_elements + i * (nh + 1) + j;
683 
684  // Get pointer to element
685  FiniteElement* el_pt = this->finite_element_pt(e);
686 
687  // Loop over its nodes
688  for (unsigned i0 = 0; i0 < np; i0++)
689  {
690  for (unsigned i1 = 0; i1 < np; i1++)
691  {
692  // Node number:
693  unsigned n = i0 * np + i1;
694 
695  // Get spine node
696  SpineNode* nod_pt = dynamic_cast<SpineNode*>(el_pt->node_pt(n));
697 
698  // Set update id
699  nod_pt->node_update_fct_id() = 5;
700 
701  // Provide spine with additional storage for wall coordinate
702  if (i0 == 0)
703  {
704  // Get the Lagrangian coordinate in the Upper wall
705  zeta[0] = zeta_lo - double(i1) * dzeta_node;
706  // Get the geometric object and local coordinate
708  zeta, upper_sub_geom_object_pt, s_up);
709 
710  // The local coordinate is a geometric parameter
711  Vector<double> parameters(1, s_up[0]);
712  nod_pt->spine_pt()->set_geom_parameter(parameters);
713 
714  // Adjust spine height
715  nod_pt->spine_pt()->height() = H;
716 
717  // upper sub geom object is one (and only) geom object
718  // for spine:
719  Vector<GeomObject*> geom_object_pt(1);
720  geom_object_pt[0] = upper_sub_geom_object_pt;
721 
722  // Pass geom object(s) to spine
723  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
724 
725  // Push the node back onto boundaries
726  if (j == 0) set_boundary_node_pt[2].insert(nod_pt);
727  }
728  }
729  }
730  }
731  }
732  }
733 
734  // Wipe the boundary lookup schemes
735  this->remove_boundary_nodes();
736  this->set_nboundary(6);
737 
738  // Copy from sets to vectors
739  for (unsigned ibound = 0; ibound < 6; ibound++)
740  {
741  typedef std::set<Node*>::iterator IT;
742  for (IT it = set_boundary_node_pt[ibound].begin();
743  it != set_boundary_node_pt[ibound].end();
744  it++)
745  {
746  this->add_boundary_node(ibound, *it);
747  }
748  }
749 
750 
751  // Loop over the free surface boundary (4) and set a boundary coordinate
752  {
753  // Boundary coordinate
754  Vector<double> zeta(1);
755  unsigned n_boundary_node = this->nboundary_node(4);
756  for (unsigned n = 0; n < n_boundary_node; ++n)
757  {
758  zeta[0] = this->boundary_node_pt(4, n)->x(0);
760  }
761  }
762 
763 
764  // Now add the rectangular mesh in the channel ahead of the finger tip
765  //--------------------------------------------------------------------
766 
767  // Build a temporary version of a SimpleRectangularQuadMesh as
768  // a unit square
769  SimpleRectangularQuadMesh<ELEMENT>* aux_mesh_pt =
770  new SimpleRectangularQuadMesh<ELEMENT>(
771  Nx3, 2 * nhalf, 1.0, 1.0, time_stepper_pt);
772 
773  // Wipe the boundary information in the auxilliary mesh
774  aux_mesh_pt->remove_boundary_nodes();
775 
776  // Copy all nodes in the auxiliary mesh into a set (from where they
777  // can easily be removed)
778  nnod = aux_mesh_pt->nnode();
779  std::set<Node*> aux_node_pt;
780  for (unsigned i = 0; i < nnod; i++)
781  {
782  aux_node_pt.insert(aux_mesh_pt->node_pt(i));
783  }
784 
785  // Loop over elements in first column and set pointers
786  // to the nodes in their first column to the ones that already exist
787 
788  // Boundary node number for first node in element
789  unsigned first_bound_node = 0;
790 
791  // Loop over elements
792  for (unsigned e = 0; e < 2 * nhalf; e++)
793  {
794  FiniteElement* el_pt = aux_mesh_pt->finite_element_pt(e * Nx3);
795  // Loop over first column of nodes
796  for (unsigned i = 0; i < np; i++)
797  {
798  // Node number in element
799  unsigned n = i * np;
800  // Remove node from set and kill it
801  if ((e < 1) || (i > 0))
802  {
803  aux_node_pt.erase(el_pt->node_pt(n));
804  delete el_pt->node_pt(n);
805  }
806  // Set pointer to existing node
807  el_pt->node_pt(n) = this->boundary_node_pt(1, first_bound_node + i);
808  }
809 
810  // Increment first node number
811  first_bound_node += np - 1;
812  }
813 
814  // Now add all the remaining nodes in the auxiliary mesh
815  // to the actual one
816  typedef std::set<Node*>::iterator IT;
817  for (IT it = aux_node_pt.begin(); it != aux_node_pt.end(); it++)
818  {
819  this->Node_pt.push_back(*it);
820  }
821 
822  // Store number of elements before the new bit gets added:
823  unsigned nelement_orig = this->Element_pt.size();
824 
825  // Add the elements to the actual mesh
826  unsigned nelem = aux_mesh_pt->nelement();
827  for (unsigned e = 0; e < nelem; e++)
828  {
829  this->Element_pt.push_back(aux_mesh_pt->element_pt(e));
830  // Don't forget to add them to the bulk
831  this->Bulk_element_pt.push_back(aux_mesh_pt->finite_element_pt(e));
832  }
833 
834  // Now wipe the boundary node storage scheme for the
835  // nodes that used to be at the end of the domain:
836  this->remove_boundary_nodes(1);
837 
838 
839  // FIRST SPINE
840  //-----------
841 
842  // Element 0
843  // Node 0
844  // Assign the new spine with unit height (pinned dummy -- never used)
845  Spine* new_spine_pt = new Spine(1.0);
846  this->Spine_pt.push_back(new_spine_pt);
847  new_spine_pt->spine_height_pt()->pin(0);
848 
849  // Get pointer to node
850  SpineNode* nod_pt = this->element_node_pt(nelement_orig + 0, 0);
851  // Set the pointer to node
852  nod_pt->spine_pt() = new_spine_pt;
853  // Set the fraction
854  nod_pt->fraction() = 0.0;
855  // Pointer to the mesh that implements the update fct
856  nod_pt->spine_mesh_pt() = this;
857  // ID for the update function
858  nod_pt->node_update_fct_id() = 6;
859 
860  // Need to get the local coordinates for the upper and lower wall
862  // Get the sub geometric objects
863  Lower_wall_pt->locate_zeta(zeta, lower_sub_geom_object_pt, s_lo);
864  Upper_wall_pt->locate_zeta(zeta, upper_sub_geom_object_pt, s_up);
865 
866  lower_sub_geom_object_pt->position(s_lo, r_wall_lo);
867  upper_sub_geom_object_pt->position(s_up, r_wall_up);
868 
869  // Pass additional data to spine
870  Vector<double> parameters(2);
871  parameters[0] = s_lo[0];
872  parameters[1] = s_up[0];
873  new_spine_pt->set_geom_parameter(parameters);
874 
875  // Lower and upper wall sub geom objects affect update
876  // for spine:
877  Vector<GeomObject*> geom_object_pt(2);
878  geom_object_pt[0] = lower_sub_geom_object_pt;
879  geom_object_pt[1] = upper_sub_geom_object_pt;
880 
881  // Pass geom object(s) to spine
882  new_spine_pt->set_geom_object_pt(geom_object_pt);
883 
884  // Loop vertically along the spine
885  // Loop over the elements
886  for (unsigned long i = 0; i < 2 * nhalf; i++)
887  {
888  // Loop over the vertical nodes, apart from the first
889  for (unsigned l1 = 1; l1 < np; l1++)
890  {
891  // Get pointer to node
892  SpineNode* nod_pt =
893  this->element_node_pt(nelement_orig + i * Nx3, l1 * np);
894  // Set the pointer to the spine
895  nod_pt->spine_pt() = new_spine_pt;
896  // Set the fraction
897  nod_pt->fraction() =
898  (double(i) + double(l1) / double(np - 1)) / double(2 * nhalf);
899  // Pointer to the mesh that implements the update fct
900  nod_pt->spine_mesh_pt() = this;
901  // ID for the update function
902  nod_pt->node_update_fct_id() = 6;
903  }
904  }
905 
906 
907  // LOOP OVER OTHER SPINES
908  //----------------------
909 
910  // Now loop over the elements horizontally
911  for (unsigned long j = 0; j < Nx3; j++)
912  {
913  // Loop over the nodes in the elements horizontally, ignoring
914  // the first column
915  for (unsigned l2 = 1; l2 < np; l2++)
916  {
917  // Assign the new spine with unit height (pinned dummy; never used)
918  new_spine_pt = new Spine(1.0);
919  this->Spine_pt.push_back(new_spine_pt);
920  new_spine_pt->spine_height_pt()->pin(0);
921 
922  // Get the node
923  SpineNode* nod_pt = this->element_node_pt(nelement_orig + j, l2);
924  // Set the pointer to the spine
925  nod_pt->spine_pt() = new_spine_pt;
926  // Set the fraction
927  nod_pt->fraction() = 0.0;
928  // Pointer to the mesh that implements the update fct
929  nod_pt->spine_mesh_pt() = this;
930  // ID for the update function
931  nod_pt->node_update_fct_id() = 6;
932 
933  // Add to boundary lookup scheme
934  this->add_boundary_node(0, nod_pt);
935  if ((j == Nx3 - 1) && (l2 == np - 1))
936  {
937  this->add_boundary_node(1, nod_pt);
938  }
939 
940  // Increment in wall coordinate
941  double dzeta_el = (Zeta_end - Zeta_transition_end) / double(Nx3);
942  double dzeta_nod = dzeta_el / double(np - 1);
943 
944  // Get wall coordinate
945  zeta[0] = Zeta_transition_end + j * dzeta_el + l2 * dzeta_nod;
946 
947  // Get the sub geometric objects
948  Lower_wall_pt->locate_zeta(zeta, lower_sub_geom_object_pt, s_lo);
949  Upper_wall_pt->locate_zeta(zeta, upper_sub_geom_object_pt, s_up);
950 
951  lower_sub_geom_object_pt->position(s_lo, r_wall_lo);
952  upper_sub_geom_object_pt->position(s_up, r_wall_up);
953 
954  // Add geometric parameters to spine
955  Vector<double> parameters(2);
956  parameters[0] = s_lo[0];
957  parameters[1] = s_up[0];
958  new_spine_pt->set_geom_parameter(parameters);
959 
960  // Lower and upper sub geom objects affect update
961  // for spine:
962  Vector<GeomObject*> geom_object_pt(2);
963  geom_object_pt[0] = lower_sub_geom_object_pt;
964  geom_object_pt[1] = upper_sub_geom_object_pt;
965 
966  // Pass geom object(s) to spine
967  new_spine_pt->set_geom_object_pt(geom_object_pt);
968 
969 
970  // Loop vertically along the spine
971  // Loop over the elements
972  for (unsigned long i = 0; i < 2 * nhalf; i++)
973  {
974  // Loop over the vertical nodes, apart from the first
975  for (unsigned l1 = 1; l1 < np; l1++)
976  {
977  // Get node
978  SpineNode* nod_pt =
979  this->element_node_pt(nelement_orig + i * Nx3 + j, l1 * np + l2);
980  // Set the pointer to the spine
981  nod_pt->spine_pt() = new_spine_pt;
982  // Set the fraction
983  nod_pt->fraction() =
984  (double(i) + double(l1) / double(np - 1)) / double(2 * nhalf);
985  // Pointer to the mesh that implements the update fct
986  nod_pt->spine_mesh_pt() = this;
987  // ID for the update function
988  nod_pt->node_update_fct_id() = 6;
989 
990  // Add to boundary lookup scheme
991  if ((j == Nx3 - 1) && (l2 == np - 1))
992  {
993  this->add_boundary_node(1, nod_pt);
994  }
995 
996  // Add to boundary lookup scheme
997  if ((i == 2 * nhalf - 1) && (l1 == np - 1))
998  {
999  this->add_boundary_node(2, nod_pt);
1000  }
1001  }
1002  }
1003  }
1004  }
1005 
1006  // (Re-)setup lookup scheme that establishes which elements are located
1007  // on the mesh boundaries
1009 
1010  // Flush the storage for elements and nodes in the auxiliary mesh
1011  // so it can be safely deleted
1012  aux_mesh_pt->flush_element_and_node_storage();
1013 
1014  // Kill the auxiliary mesh
1015  delete aux_mesh_pt;
1016  }
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
GeomObject * Lower_wall_pt
Pointer to geometric object that represents the lower wall.
Definition: bretherton_spine_mesh.template.h:517
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
double H
Thickness of deposited film.
Definition: bretherton_spine_mesh.template.h:511
unsigned Nh
Number of elements across the deposited film.
Definition: bretherton_spine_mesh.template.h:508
void initial_element_reorder()
Definition: bretherton_spine_mesh.template.cc:1028
double spine_centre_fraction() const
Read the value of the spine centre's vertical fraction.
Definition: bretherton_spine_mesh.template.h:194
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
double Zeta_end
Wall coordinate of end of liquid filled region (inflow)
Definition: bretherton_spine_mesh.template.h:523
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
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
virtual unsigned nnode_1d() const
Definition: elements.h:2218
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
virtual void locate_zeta(const Vector< double > &zeta, GeomObject *&sub_geom_object_pt, Vector< double > &s, const bool &use_coordinate_as_initial_guess=false)
Definition: geom_objects.h:381
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
unsigned long nboundary_node(const unsigned &ibound) const
Return number of nodes on a particular boundary.
Definition: mesh.h:833
Vector< Node * > Node_pt
Vector of pointers to nodes.
Definition: mesh.h:183
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
virtual void setup_boundary_element_info()
Definition: mesh.h:275
void remove_boundary_nodes()
Clear all pointers to boundary nodes.
Definition: mesh.cc:204
const Vector< GeneralisedElement * > & element_pt() const
Return reference to the Vector of elements.
Definition: mesh.h:460
Node *& boundary_node_pt(const unsigned &b, const unsigned &n)
Return pointer to node n on boundary b.
Definition: mesh.h:493
Vector< GeneralisedElement * > Element_pt
Vector of pointers to generalised elements.
Definition: mesh.h:186
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:1060
virtual void set_coordinates_on_boundary(const unsigned &b, const unsigned &k, const Vector< double > &boundary_zeta)
Definition: nodes.cc:2394
Vector< Spine * > Spine_pt
A Spine mesh contains a Vector of pointers to spines.
Definition: spines.h:616
SpineNode * element_node_pt(const unsigned long &e, const unsigned &n)
Definition: spines.h:669
@ N
Definition: constructor.cpp:22
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
double S0
Strength of source function in inner region.
Definition: stefan_boltzmann.cc:148
radius
Definition: UniformPSDSelfTest.py:15
Real fabs(const Real &a)
Definition: boostmultiprec.cpp:117
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

Member Function Documentation

◆ bulk_element_pt()

template<class ELEMENT , class INTERFACE_ELEMENT >
FiniteElement*& oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::bulk_element_pt ( const unsigned long &  i)
inline

Access functions for pointers to elements in bulk.

94  {
95  return Bulk_element_pt[i];
96  }

References oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Bulk_element_pt, and i.

◆ control_element_pt()

template<class ELEMENT , class INTERFACE_ELEMENT >
ELEMENT* oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::control_element_pt ( )
inline

Pointer to control element (just under the symmetry line near the bubble tip, so the bubble tip is located at s=[1.0,1.0] in this element.

188  {
189  return Control_element_pt;
190  }

References oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Control_element_pt.

◆ find_distance_to_free_surface()

template<class ELEMENT , class INTERFACE_ELEMENT >
double oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::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.

Calculate the distance from the spine base to the free surface, i.e. the spine height.

1070  {
1071  // Now we need to find the intersection points
1072  double lambda = 0.5;
1073 
1074  Vector<double> dx(2);
1075  Vector<double> new_free_x(2);
1076  DenseDoubleMatrix jacobian(2, 2, 0.0);
1077  Vector<double> spine_x(2);
1078  Vector<double> free_x(2);
1079 
1080  double maxres = 100.0;
1081 
1082  unsigned count = 0;
1083  // Let's Newton method it
1084  do
1085  {
1086  count++;
1087  // Find the spine's location
1088  for (unsigned i = 0; i < 2; ++i)
1089  {
1090  spine_x[i] = spine_base[i] + lambda * (spine_end[i] - spine_base[i]);
1091  }
1092 
1093  // Find the free_surface location
1094  fs_geom_object_pt->position(initial_zeta, free_x);
1095 
1096  for (unsigned i = 0; i < 2; ++i)
1097  {
1098  dx[i] = spine_x[i] - free_x[i];
1099  }
1100 
1101  // Calculate the entries of the jacobian matrix
1102  jacobian(0, 0) = (spine_end[0] - spine_base[0]);
1103  jacobian(1, 0) = (spine_end[1] - spine_base[1]);
1104 
1105  // Calculate the others by finite differences
1106  double FD_Jstep = 1.0e-6;
1107  double old_zeta = initial_zeta[0];
1108  initial_zeta[0] += FD_Jstep;
1109  fs_geom_object_pt->position(initial_zeta, new_free_x);
1110 
1111  for (unsigned i = 0; i < 2; ++i)
1112  {
1113  jacobian(i, 1) = (free_x[i] - new_free_x[i]) / FD_Jstep;
1114  }
1115 
1116  // Now let's solve the damn thing
1117  jacobian.solve(dx);
1118 
1119  lambda -= dx[0];
1120  initial_zeta[0] = old_zeta - dx[1];
1121 
1122  // How are we doing
1123 
1124  for (unsigned i = 0; i < 2; ++i)
1125  {
1126  spine_x[i] = spine_base[i] + lambda * (spine_end[i] - spine_base[i]);
1127  }
1128  fs_geom_object_pt->position(initial_zeta, free_x);
1129 
1130  for (unsigned i = 0; i < 2; ++i)
1131  {
1132  dx[i] = spine_x[i] - free_x[i];
1133  }
1134  maxres = std::fabs(dx[0]) > std::fabs(dx[1]) ? std::fabs(dx[0]) :
1135  std::fabs(dx[1]);
1136 
1137  if (count > 100)
1138  {
1139  throw OomphLibError("Failed to converge after 100 steps",
1142  }
1143 
1144  } while (maxres > 1.0e-8);
1145 
1146 
1147  oomph_info << "DONE " << initial_zeta[0] << std::endl;
1148  double spine_length = sqrt(pow((spine_base[0] - spine_end[0]), 2.0) +
1149  pow((spine_base[1] - spine_end[1]), 2.0));
1150 
1151  return (lambda * spine_length); // Divided by spine length
1152  }
cout<< "The eigenvalues of A are:"<< endl<< ces.eigenvalues()<< endl;cout<< "The matrix of eigenvectors, V, is:"<< endl<< ces.eigenvectors()<< endl<< endl;complex< float > lambda
Definition: ComplexEigenSolver_compute.cpp:9
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References boost::multiprecision::fabs(), i, lambda, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, oomph::GeomObject::position(), Eigen::ArrayBase< Derived >::pow(), oomph::DoubleMatrixBase::solve(), and sqrt().

◆ initial_element_reorder()

template<class ELEMENT , class INTERFACE_ELEMENT >
void oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::initial_element_reorder
protected

Initial reordering elements of the elements – before the channel mesh is added. Vertical stacks of elements, each topped by their interface element – this is (currently) identical to the version in the SingleLayerSpineMesh but it's important that the element reordering is maintained in exactly this form for the rest of the mesh generation process to work properly. Therefore we keep a copy of the function in here.

Reorder elements: Vertical stacks of elements, each topped by their interface element – this is (currently) identical to the version in the SingleLayerSpineMesh but it's important that element reordering is maintained in exactly this form so to be on the safe side, we move the function in here.

1029  {
1030  unsigned Nx = this->Nx;
1031  unsigned Ny = this->Ny;
1032  // Find out how many elements there are
1033  unsigned long Nelement = this->nelement();
1034  // Find out how many fluid elements there are
1035  unsigned long Nfluid = Nx * Ny;
1036  // Create a dummy array of elements
1037  Vector<FiniteElement*> dummy;
1038 
1039  // Loop over the elements in horizontal order
1040  for (unsigned long j = 0; j < Nx; j++)
1041  {
1042  // Loop over the elements in lower layer vertically
1043  for (unsigned long i = 0; i < Ny; i++)
1044  {
1045  // Push back onto the new stack
1046  dummy.push_back(this->finite_element_pt(Nx * i + j));
1047  }
1048 
1049  // Push back the line element onto the stack
1050  dummy.push_back(this->finite_element_pt(Nfluid + j));
1051  }
1052 
1053  // Now copy the reordered elements into the element_pt
1054  for (unsigned long e = 0; e < Nelement; e++)
1055  {
1056  this->Element_pt[e] = dummy[e];
1057  }
1058  }
unsigned Nx
Nx: number of elements in x-direction.
Definition: rectangular_quadmesh.template.h:63
unsigned Ny
Ny: number of elements in y-direction.
Definition: rectangular_quadmesh.template.h:65

References e(), i, j, GlobalParameters::Nx, and GlobalParameters::Ny.

◆ interface_element_pt()

template<class ELEMENT , class INTERFACE_ELEMENT >
FiniteElement*& oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::interface_element_pt ( const unsigned long &  i)
inline

Access functions for pointers to interface elements.

82  {
83  return Interface_element_pt[i];
84  }

References i, and oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Interface_element_pt.

◆ nbulk()

template<class ELEMENT , class INTERFACE_ELEMENT >
unsigned long oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::nbulk ( ) const
inline

Number of elements in bulk.

100  {
101  return Bulk_element_pt.size();
102  }

References oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Bulk_element_pt.

◆ nfree_surface_spines()

template<class ELEMENT , class INTERFACE_ELEMENT >
unsigned oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::nfree_surface_spines ( )
inline

Number of free-surface spines (i.e. excluding the dummy spines in the channel region)

108  {
109  unsigned np = this->finite_element_pt(0)->nnode_1d();
110  return 2 * (Nx1 + Nx2 + Nhalf) * (np - 1);
111  }

References oomph::Mesh::finite_element_pt(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Nhalf, oomph::FiniteElement::nnode_1d(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Nx1, and oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Nx2.

◆ ninterface_element()

template<class ELEMENT , class INTERFACE_ELEMENT >
unsigned long oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::ninterface_element ( ) const
inline

Number of elements on interface.

88  {
89  return Interface_element_pt.size();
90  }

References oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Interface_element_pt.

◆ pin_all_spines()

template<class ELEMENT , class INTERFACE_ELEMENT >
void oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::pin_all_spines ( )
inline

Pin all spines so the mesh can be used for computation without free surfaces

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  }
void pin(const unsigned &i)
Pin the i-th stored variable.
Definition: nodes.h:385
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
Data *& spine_height_pt()
Access function to Data object that stores the spine height.
Definition: spines.h:156

References i, oomph::SpineMesh::nspine(), oomph::Data::pin(), oomph::Spine::spine_height_pt(), and oomph::SpineMesh::spine_pt().

◆ reposition_spines()

template<class ELEMENT , class INTERFACE_ELEMENT >
void oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::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.

Reposition the spines that emenate from the lower wall.

1163  {
1164  // Firstly create a geometric object of the free surface
1165  Mesh* fs_mesh_pt = new Mesh;
1166  this->template build_face_mesh<ELEMENT, FaceElementAsGeomObject>(
1167  4, fs_mesh_pt);
1168 
1169  // Loop over these new face elements and set the boundary number
1170  // of the bulk mesh
1171  unsigned n_face_element = fs_mesh_pt->nelement();
1172  // Loop over the elements
1173  for (unsigned e = 0; e < n_face_element; e++)
1174  {
1175  // Cast the element pointer to the correct thing!
1176  dynamic_cast<FaceElementAsGeomObject<ELEMENT>*>(fs_mesh_pt->element_pt(e))
1177  ->set_boundary_number_in_bulk_mesh(4);
1178  }
1179 
1180  // Now make a single geometric object that represents the collection of
1181  // geometric objects that form the boundary of the bulk mesh. Two
1182  // Eulerian coordinates, one intrinsic coordinate.
1183  MeshAsGeomObject* fs_geom_object_pt = new MeshAsGeomObject(fs_mesh_pt);
1184 
1185 
1186  // Length of deposited film region
1187  double llayer_lower = zeta_lo_transition_start - Zeta_start;
1188  double llayer_upper = zeta_up_transition_start - Zeta_start;
1189 
1190  // Length of transition region
1191  double d_lower = zeta_lo_transition_end - zeta_lo_transition_start;
1192  double d_upper = zeta_up_transition_end - zeta_up_transition_start;
1193 
1194  // Work out radius of circular cap from lower and upper wall
1195  Vector<double> r_wall_lo(2), r_wall_up(2);
1196  Vector<double> zeta(1), s_lo(1), s_up(1);
1197  GeomObject *lower_sub_geom_object_pt = 0, *upper_sub_geom_object_pt = 0;
1198 
1199  GeomObject* lower_transition_geom_object_pt = 0;
1200  GeomObject* upper_transition_geom_object_pt = 0;
1201  Vector<double> s_transition_lo(1), s_transition_up(1);
1202  Vector<double> spine_centre(2);
1203 
1204  // Get number of nodes along element edge
1205  unsigned np = this->finite_element_pt(0)->nnode_1d();
1206 
1207  // Calculate the centre for the spine nodes in the transition region
1208  {
1209  // Get the geometric objects on the walls at the start of the transition
1210  // region
1211  // Lower wall
1212  zeta[0] = zeta_lo_transition_start;
1214  zeta, lower_transition_geom_object_pt, s_transition_lo);
1215  // Upper wall
1216  zeta[0] = zeta_up_transition_start;
1218  zeta, upper_transition_geom_object_pt, s_transition_up);
1219 
1220  // Find the Eulerian coordinates of the walls at the transition region
1221  lower_transition_geom_object_pt->position(s_transition_lo, r_wall_lo);
1222  upper_transition_geom_object_pt->position(s_transition_up, r_wall_up);
1223 
1224  // Take the average of these positions to define the origin of the spines
1225  // in the transition region Horizontal position is always halfway
1226  spine_centre[0] = 0.5 * (r_wall_lo[0] + r_wall_up[0]);
1227 
1228  // Vertical Position is given by a specified fraction
1229  // between the upper and lower walls
1230  spine_centre[1] =
1231  r_wall_lo[1] + spine_centre_fraction() * (r_wall_up[1] - r_wall_lo[1]);
1232  }
1233 
1234 
1235  // Initialise number of elements in previous regions:
1236  unsigned n_prev_elements = 0;
1237 
1238  // Storage for the end of the spines
1239  Vector<double> spine_end(2);
1240  Vector<double> fs_zeta(1, 0.0);
1241 
1242  // Loop over elements in lower deposited film region
1243  // -------------------------------------------------
1244  {
1245  oomph_info << "LOWER FILM " << std::endl;
1246  // Increments in wall coordinate
1247  double dzeta_el = llayer_lower / double(Nx1);
1248  double dzeta_node = llayer_lower / double(Nx1 * (np - 1));
1249 
1250  // Loop over elements horizontally
1251  for (unsigned i = 0; i < Nx1; i++)
1252  {
1253  // Start of wall coordinate
1254  double zeta_lo = Zeta_start + double(i) * dzeta_el;
1255 
1256  // Work out element number in overall mesh
1257  unsigned e = n_prev_elements + i * (Nh + 1);
1258 
1259  // Get pointer to lower element
1260  FiniteElement* el_pt = this->finite_element_pt(e);
1261 
1262  // Loop over its nodes "horizontally"
1263  for (unsigned i1 = 0; i1 < (np - 1); i1++)
1264  {
1265  // Get spine node
1266  SpineNode* nod_pt = dynamic_cast<SpineNode*>(el_pt->node_pt(i1));
1267 
1268  // Get the Lagrangian coordinate in the Lower Wall
1269  zeta[0] = zeta_lo + double(i1) * dzeta_node;
1270  // Reset the boundary coordinate
1271  nod_pt->set_coordinates_on_boundary(0, zeta);
1272  // Get the geometric object and local coordinate
1273  Lower_wall_pt->locate_zeta(zeta, lower_sub_geom_object_pt, s_lo);
1274 
1275  // The local coordinate is a geometric parameter
1276  // This needs to be set (rather than added) because the
1277  // same spine may be visited more than once
1278  Vector<double> parameters(1, s_lo[0]);
1279  nod_pt->spine_pt()->set_geom_parameter(parameters);
1280 
1281  // The sub geom object is one (and only) geom object
1282  // for spine:
1283  Vector<GeomObject*> geom_object_pt(1);
1284  geom_object_pt[0] = lower_sub_geom_object_pt;
1285 
1286  // Pass geom object(s) to spine
1287  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
1288 
1289  // Get the wall position at the bottom of the spine
1290  lower_sub_geom_object_pt->position(s_lo, r_wall_lo);
1291  // The end of the spine is vertically above the base
1292  spine_end[0] = r_wall_lo[0];
1293  spine_end[1] = spine_centre[1];
1294  nod_pt->spine_pt()->height() = find_distance_to_free_surface(
1295  fs_geom_object_pt, fs_zeta, r_wall_lo, spine_end);
1296  }
1297  }
1298 
1299  // Increment number of previous elements
1300  n_prev_elements += Nx1 * (Nh + 1);
1301  }
1302 
1303 
1304  // Loop over elements in lower horizontal transition region
1305  // --------------------------------------------------------
1306  {
1307  oomph_info << "LOWER HORIZONTAL TRANSITION " << std::endl;
1308  // Increments in wall coordinate
1309  double dzeta_el = d_lower / double(Nx2);
1310  double dzeta_node = d_lower / double(Nx2 * (np - 1));
1311 
1312  // Loop over elements horizontally
1313  for (unsigned i = 0; i < Nx2; i++)
1314  {
1315  // Start of wall coordinate
1316  double zeta_lo = zeta_lo_transition_start + double(i) * dzeta_el;
1317 
1318  // Work out element number in overall mesh
1319  unsigned e = n_prev_elements + i * (Nh + 1);
1320 
1321  // Get pointer to element
1322  FiniteElement* el_pt = this->finite_element_pt(e);
1323 
1324  // Loop over its nodes
1325  for (unsigned i1 = 0; i1 < (np - 1); i1++)
1326  {
1327  // Get spine node
1328  SpineNode* nod_pt = dynamic_cast<SpineNode*>(el_pt->node_pt(i1));
1329 
1330  // Get the Lagrangian coordinate in the Lower Wall
1331  zeta[0] = zeta_lo + double(i1) * dzeta_node;
1332  // Reset the boundary coordinate
1333  nod_pt->set_coordinates_on_boundary(0, zeta);
1334  // Get the sub geometric object and local coordinate
1335  Lower_wall_pt->locate_zeta(zeta, lower_sub_geom_object_pt, s_lo);
1336 
1337  // Pass geometric parameter to the spine
1338  Vector<double> parameters(3);
1339  parameters[0] = s_lo[0];
1340  parameters[1] = s_transition_lo[0];
1341  parameters[2] = s_transition_up[0];
1342  nod_pt->spine_pt()->set_geom_parameter(parameters);
1343 
1344  // Lower sub geom object is one (and only) geom object
1345  // for spine:
1346  Vector<GeomObject*> geom_object_pt(3);
1347  geom_object_pt[0] = lower_sub_geom_object_pt;
1348  geom_object_pt[1] = lower_transition_geom_object_pt;
1349  geom_object_pt[2] = upper_transition_geom_object_pt;
1350 
1351  // Pass geom object(s) to spine
1352  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
1353 
1354  // Get position vector to wall
1355  lower_sub_geom_object_pt->position(s_lo, r_wall_lo);
1356  // The end of the spine is the spine centre,so the height is easy(ish)
1357  nod_pt->spine_pt()->height() = find_distance_to_free_surface(
1358  fs_geom_object_pt, fs_zeta, r_wall_lo, spine_centre);
1359  }
1360  }
1361 
1362  // Increment number of previous elements
1363  n_prev_elements += Nx2 * (Nh + 1);
1364  }
1365 
1366  // Loop over elements in lower vertical transition region
1367  // --------------------------------------------------------
1368  {
1369  oomph_info << "LOWER VERTICAL TRANSITION " << std::endl;
1370  for (unsigned i = 0; i < Nhalf; i++)
1371  {
1372  // Work out element number in overall mesh
1373  unsigned e = n_prev_elements + i * (Nh + 1);
1374 
1375  // Get pointer to element
1376  FiniteElement* el_pt = this->finite_element_pt(e);
1377 
1378  // Loop over its nodes
1379  for (unsigned i1 = 0; i1 < (np - 1); i1++)
1380  {
1381  // Get spine node
1382  // Note that I have to loop over the second row of nodes
1383  // because the first row are updated in region 6 and so
1384  // you get the wrong spines from them (doh!)
1385  SpineNode* nod_pt = dynamic_cast<SpineNode*>(el_pt->node_pt(np + i1));
1386 
1387  // Get position vectors to wall
1388  zeta[0] = zeta_lo_transition_end;
1389  // Get the sub geometric objects
1390  Lower_wall_pt->locate_zeta(zeta, lower_sub_geom_object_pt, s_lo);
1391  zeta[0] = zeta_up_transition_end;
1392  Upper_wall_pt->locate_zeta(zeta, upper_sub_geom_object_pt, s_up);
1393 
1394  lower_sub_geom_object_pt->position(s_lo, r_wall_lo);
1395  upper_sub_geom_object_pt->position(s_up, r_wall_up);
1396 
1397  // Set vertical fraction
1398  double vertical_fraction =
1399  (double(i) + double(i1) / double(np - 1)) / double(2.0 * Nhalf);
1400 
1401  // Add the geometric parameters in order
1402  Vector<double> parameters(5);
1403  parameters[0] = s_lo[0];
1404  parameters[1] = s_up[0];
1405  parameters[2] = vertical_fraction;
1406  parameters[3] = s_transition_lo[0];
1407  parameters[4] = s_transition_up[0];
1408  nod_pt->spine_pt()->set_geom_parameter(parameters);
1409 
1410  // Origin of spine
1411  Vector<double> S0(2);
1412  S0[0] =
1413  r_wall_lo[0] + vertical_fraction * (r_wall_up[0] - r_wall_lo[0]);
1414  S0[1] =
1415  r_wall_lo[1] + vertical_fraction * (r_wall_up[1] - r_wall_lo[1]);
1416 
1417  // Lower and Upper wall sub geom objects affect spine:
1418  Vector<GeomObject*> geom_object_pt(4);
1419  geom_object_pt[0] = lower_sub_geom_object_pt;
1420  geom_object_pt[1] = upper_sub_geom_object_pt;
1421  geom_object_pt[2] = lower_transition_geom_object_pt;
1422  geom_object_pt[3] = upper_transition_geom_object_pt;
1423 
1424  // Pass geom object(s) to spine
1425  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
1426 
1427  // Calculate the spine height
1428  nod_pt->spine_pt()->height() = find_distance_to_free_surface(
1429  fs_geom_object_pt, fs_zeta, S0, spine_centre);
1430  }
1431  }
1432 
1433  // Increment number of previous elements
1434  n_prev_elements += Nhalf * (Nh + 1);
1435  }
1436 
1437 
1438  // Loop over elements in upper vertical transition region
1439  // --------------------------------------------------------
1440  {
1441  oomph_info << "UPPER VERTICAL TRANSITION" << std::endl;
1442  for (unsigned i = 0; i < Nhalf; i++)
1443  {
1444  // Work out element number in overall mesh
1445  unsigned e = n_prev_elements + i * (Nh + 1);
1446 
1447  // Get pointer to element
1448  FiniteElement* el_pt = this->finite_element_pt(e);
1449 
1450  // Loop over its nodes
1451  for (unsigned i1 = 0; i1 < (np - 1); i1++)
1452  {
1453  // Get spine node
1454  // Note that I have to loop over the second row of nodes
1455  // because the first row are updated in region 6 and so
1456  // you get the wrong spines from them (doh!)
1457  SpineNode* nod_pt = dynamic_cast<SpineNode*>(el_pt->node_pt(np + i1));
1458 
1459  // Get position vectors to wall
1460  zeta[0] = zeta_lo_transition_end;
1461  // Get the sub geometric objects
1462  Lower_wall_pt->locate_zeta(zeta, lower_sub_geom_object_pt, s_lo);
1463  zeta[0] = zeta_up_transition_end;
1464  Upper_wall_pt->locate_zeta(zeta, upper_sub_geom_object_pt, s_up);
1465 
1466  lower_sub_geom_object_pt->position(s_lo, r_wall_lo);
1467  upper_sub_geom_object_pt->position(s_up, r_wall_up);
1468 
1469 
1470  // Set vertical fraction
1471  double vertical_fraction =
1472  0.5 +
1473  (double(i) + double(i1) / double(np - 1)) / double(2.0 * Nhalf);
1474 
1475  // Add the geometric parameters in order
1476  Vector<double> parameters(5);
1477  parameters[0] = s_lo[0];
1478  parameters[1] = s_up[0];
1479  parameters[2] = vertical_fraction;
1480  parameters[3] = s_transition_lo[0];
1481  parameters[4] = s_transition_up[0];
1482  nod_pt->spine_pt()->set_geom_parameter(parameters);
1483 
1484  // Origin of spine
1485  Vector<double> S0(2);
1486  S0[0] =
1487  r_wall_lo[0] + vertical_fraction * (r_wall_up[0] - r_wall_lo[0]);
1488  S0[1] =
1489  r_wall_lo[1] + vertical_fraction * (r_wall_up[1] - r_wall_lo[1]);
1490 
1491  // Lower and Upper wall sub geom objects affect spine:
1492  Vector<GeomObject*> geom_object_pt(4);
1493  geom_object_pt[0] = lower_sub_geom_object_pt;
1494  geom_object_pt[1] = upper_sub_geom_object_pt;
1495  geom_object_pt[2] = lower_transition_geom_object_pt;
1496  geom_object_pt[3] = upper_transition_geom_object_pt;
1497 
1498  // Pass geom object(s) to spine
1499  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
1500 
1501  // Calculate the spine height
1502  nod_pt->spine_pt()->height() = find_distance_to_free_surface(
1503  fs_geom_object_pt, fs_zeta, S0, spine_centre);
1504  }
1505  }
1506 
1507  // Increment number of previous elements
1508  n_prev_elements += Nhalf * (Nh + 1);
1509  }
1510 
1511 
1512  // Loop over elements in upper horizontal transition region
1513  // --------------------------------------------------------
1514  {
1515  oomph_info << "UPPER HORIZONTAL TRANSITION " << std::endl;
1516  // Increments in wall coordinate
1517  double dzeta_el = d_upper / double(Nx2);
1518  double dzeta_node = d_upper / double(Nx2 * (np - 1));
1519 
1520  // Loop over elements horizontally
1521  for (unsigned i = 0; i < Nx2; i++)
1522  {
1523  // Start of wall coordinate
1524  double zeta_lo = zeta_up_transition_end - double(i) * dzeta_el;
1525 
1526  // Work out element number in overall mesh
1527  unsigned e = n_prev_elements + i * (Nh + 1);
1528 
1529  // Get pointer to element
1530  FiniteElement* el_pt = this->finite_element_pt(e);
1531 
1532  // Loop over its nodes
1533  for (unsigned i1 = 0; i1 < (np - 1); i1++)
1534  {
1535  // Get spine node (same comment)
1536  SpineNode* nod_pt = dynamic_cast<SpineNode*>(el_pt->node_pt(np + i1));
1537 
1538  // Get the Lagrangian coordinate in the Lower Wall
1539  zeta[0] = zeta_lo - double(i1) * dzeta_node;
1540  // Reset the boundary coordinate
1541  el_pt->node_pt(i1)->set_coordinates_on_boundary(2, zeta);
1542  // Get the sub geometric object and local coordinate
1543  Upper_wall_pt->locate_zeta(zeta, upper_sub_geom_object_pt, s_up);
1544 
1545  // Pass geometric parameter to the spine
1546  Vector<double> parameters(3);
1547  parameters[0] = s_up[0];
1548  parameters[1] = s_transition_lo[0];
1549  parameters[2] = s_transition_up[0];
1550  nod_pt->spine_pt()->set_geom_parameter(parameters);
1551 
1552  // Lower sub geom object is one (and only) geom object
1553  // for spine:
1554  Vector<GeomObject*> geom_object_pt(3);
1555  geom_object_pt[0] = upper_sub_geom_object_pt;
1556  geom_object_pt[1] = lower_transition_geom_object_pt;
1557  geom_object_pt[2] = upper_transition_geom_object_pt;
1558 
1559  // Pass geom object(s) to spine
1560  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
1561 
1562 
1563  // Get position vector to wall
1564  upper_sub_geom_object_pt->position(s_up, r_wall_up);
1565  // Find spine height
1566  nod_pt->spine_pt()->height() = find_distance_to_free_surface(
1567  fs_geom_object_pt, fs_zeta, r_wall_up, spine_centre);
1568  }
1569  }
1570 
1571  // Increment number of previous elements
1572  n_prev_elements += Nx2 * (Nh + 1);
1573  }
1574 
1575 
1576  // Loop over elements in upper deposited film region
1577  // -------------------------------------------------
1578  {
1579  oomph_info << "UPPER THIN FILM" << std::endl;
1580  // Increments in wall coordinate
1581  double dzeta_el = llayer_upper / double(Nx1);
1582  double dzeta_node = llayer_upper / double(Nx1 * (np - 1));
1583 
1584  // Loop over elements horizontally
1585  for (unsigned i = 0; i < Nx1; i++)
1586  {
1587  // Start of wall coordinate
1588  double zeta_lo = zeta_up_transition_start - double(i) * dzeta_el;
1589 
1590  // Work out element number in overall mesh
1591  unsigned e = n_prev_elements + i * (Nh + 1);
1592 
1593  // Get pointer to element
1594  FiniteElement* el_pt = this->finite_element_pt(e);
1595 
1596  // Loop over its nodes "horizontally"
1597  for (unsigned i1 = 0; i1 < (np - 1); i1++)
1598  {
1599  // Get spine node
1600  SpineNode* nod_pt = dynamic_cast<SpineNode*>(el_pt->node_pt(i1));
1601 
1602  // Get the Lagrangian coordinate in the Upper wall
1603  zeta[0] = zeta_lo - double(i1) * dzeta_node;
1604  // Reset coordinate on boundary
1605  nod_pt->set_coordinates_on_boundary(2, zeta);
1606  // Get the geometric object and local coordinate
1607  Upper_wall_pt->locate_zeta(zeta, upper_sub_geom_object_pt, s_up);
1608 
1609  // The local coordinate is a geometric parameter
1610  Vector<double> parameters(1, s_up[0]);
1611  nod_pt->spine_pt()->set_geom_parameter(parameters);
1612 
1613  // upper sub geom object is one (and only) geom object
1614  // for spine:
1615  Vector<GeomObject*> geom_object_pt(1);
1616  geom_object_pt[0] = upper_sub_geom_object_pt;
1617 
1618  // Pass geom object(s) to spine
1619  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
1620 
1621  // Get the wall position at the bottom of the spine
1622  upper_sub_geom_object_pt->position(s_up, r_wall_up);
1623  spine_end[0] = r_wall_up[0];
1624  spine_end[1] = spine_centre[1];
1625  // Find the new spine height
1626  nod_pt->spine_pt()->height() = find_distance_to_free_surface(
1627  fs_geom_object_pt, fs_zeta, r_wall_up, spine_end);
1628  }
1629  }
1630 
1631 
1632  // Increment number of previous elements
1633  n_prev_elements += Nx1 * (Nh + 1);
1634  }
1635 
1636 
1637  // Additional mesh
1638  {
1639  unsigned e = n_prev_elements;
1640 
1641  // Get pointer to node
1642  SpineNode* nod_pt = this->element_node_pt(e, 0);
1643 
1644  // Need to get the local coordinates for the upper and lower wall
1645  zeta[0] = zeta_lo_transition_end;
1646  // Get the sub geometric objects
1647  Lower_wall_pt->locate_zeta(zeta, lower_sub_geom_object_pt, s_lo);
1648  zeta[0] = zeta_up_transition_end;
1649  Upper_wall_pt->locate_zeta(zeta, upper_sub_geom_object_pt, s_up);
1650 
1651  lower_sub_geom_object_pt->position(s_lo, r_wall_lo);
1652  upper_sub_geom_object_pt->position(s_up, r_wall_up);
1653 
1654  // Pass additional data to spine
1655  Vector<double> parameters(2);
1656  parameters[0] = s_lo[0];
1657  parameters[1] = s_up[0];
1658  nod_pt->spine_pt()->set_geom_parameter(parameters);
1659 
1660  // Lower and upper wall sub geom objects affect update
1661  // for spine:
1662  Vector<GeomObject*> geom_object_pt(2);
1663  geom_object_pt[0] = lower_sub_geom_object_pt;
1664  geom_object_pt[1] = upper_sub_geom_object_pt;
1665 
1666  // Pass geom object(s) to spine
1667  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
1668 
1669  // LOOP OVER OTHER SPINES
1670  //----------------------
1671 
1672  // Now loop over the elements horizontally
1673  for (unsigned long j = 0; j < Nx3; j++)
1674  {
1675  unsigned e = n_prev_elements + j;
1676 
1677  // Loop over the nodes in the elements horizontally, ignoring
1678  // the first column
1679  for (unsigned l2 = 0; l2 < np; l2++)
1680  {
1681  // Get pointer to node at the base of the spine
1682  SpineNode* nod_pt = this->element_node_pt(e, l2);
1683 
1684  // Increment in wall coordinate
1685  double dzeta_el_lower =
1686  (Zeta_end - zeta_lo_transition_end) / double(Nx3);
1687  double dzeta_nod_lower = dzeta_el_lower / double(np - 1);
1688 
1689  double dzeta_el_upper =
1690  (Zeta_end - zeta_up_transition_end) / double(Nx3);
1691  double dzeta_nod_upper = dzeta_el_upper / double(np - 1);
1692 
1693  // Get wall coordinate
1694  zeta[0] =
1695  zeta_lo_transition_end + j * dzeta_el_lower + l2 * dzeta_nod_lower;
1696  // Reset the boundary coordinate
1697  nod_pt->set_coordinates_on_boundary(0, zeta);
1698 
1699  // Get the sub geometric objects
1700  Lower_wall_pt->locate_zeta(zeta, lower_sub_geom_object_pt, s_lo);
1701 
1702  zeta[0] =
1703  zeta_up_transition_end + j * dzeta_el_upper + l2 * dzeta_nod_upper;
1704  // Reset the upper boundary coordinate
1705  this->element_node_pt(e + Nx3 * (2 * Nhalf - 1), np * (np - 1) + l2)
1707  Upper_wall_pt->locate_zeta(zeta, upper_sub_geom_object_pt, s_up);
1708 
1709  lower_sub_geom_object_pt->position(s_lo, r_wall_lo);
1710  upper_sub_geom_object_pt->position(s_up, r_wall_up);
1711 
1712  // Add geometric parameters to spine
1713  Vector<double> parameters(2);
1714  parameters[0] = s_lo[0];
1715  parameters[1] = s_up[0];
1716  nod_pt->spine_pt()->set_geom_parameter(parameters);
1717 
1718  // Lower and upper sub geom objects affect update
1719  // for spine:
1720  Vector<GeomObject*> geom_object_pt(2);
1721  geom_object_pt[0] = lower_sub_geom_object_pt;
1722  geom_object_pt[1] = upper_sub_geom_object_pt;
1723 
1724  // Pass geom object(s) to spine
1725  nod_pt->spine_pt()->set_geom_object_pt(geom_object_pt);
1726  }
1727  }
1728  }
1729 
1730 
1731  // Clean up all the memory
1732  // Can delete the Geometric object
1733  delete fs_geom_object_pt;
1734  // Need to be careful with the FaceMesh, because we can't delete the nodes
1735  // Loop
1736  for (unsigned e = n_face_element; e > 0; e--)
1737  {
1738  delete fs_mesh_pt->element_pt(e - 1);
1739  fs_mesh_pt->element_pt(e - 1) = 0;
1740  }
1741  // Now clear all element and node storage (should maybe fine-grain this)
1742  fs_mesh_pt->flush_element_and_node_storage();
1743  // Finally delete the mesh
1744  delete fs_mesh_pt;
1745  }
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
Mesh()
Default constructor.
Definition: mesh.h:236

References e(), oomph::Mesh::element_pt(), oomph::Mesh::flush_element_and_node_storage(), oomph::Spine::height(), i, j, Global_Physical_Variables::Lower_wall_pt, oomph::Mesh::nelement(), oomph::oomph_info, oomph::GeomObject::position(), GlobalParameters::S0, oomph::Node::set_coordinates_on_boundary(), oomph::Spine::set_geom_object_pt(), oomph::Spine::set_geom_parameter(), oomph::SpineNode::spine_pt(), Global_Physical_Variables::Upper_wall_pt, and Eigen::zeta().

◆ set_spine_centre_fraction_pt()

template<class ELEMENT , class INTERFACE_ELEMENT >
void oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::set_spine_centre_fraction_pt ( double *const &  fraction_pt)
inline

Set the pointer to the spine centre's vertial fraction.

201  {
202  Spine_centre_fraction_pt = fraction_pt;
203  }

References oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Spine_centre_fraction_pt.

◆ spine_centre_fraction()

◆ spine_node_update()

template<class ELEMENT , class INTERFACE_ELEMENT >
void oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update ( SpineNode spine_node_pt)
inlinevirtual

General node update function implements pure virtual function defined in SpineMesh base class and performs specific update actions, depending on the node update fct id stored for each node.

Reimplemented from oomph::SingleLayerSpineMesh< ELEMENT >.

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  }
void spine_node_update_film_lower(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:208
void spine_node_update_horizontal_transition_lower(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:231
void spine_node_update_film_upper(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:440
void spine_node_update_channel(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:464
void spine_node_update_vertical_transition_upper(SpineNode *spine_node_pt)
Definition: bretherton_spine_mesh.template.h:335
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

References oomph::SpineNode::node_update_fct_id(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_channel(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_film_lower(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_film_upper(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_horizontal_transition_lower(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_horizontal_transition_upper(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_vertical_transition_lower(), and oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_vertical_transition_upper().

◆ spine_node_update_channel()

template<class ELEMENT , class INTERFACE_ELEMENT >
void oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_channel ( SpineNode spine_node_pt)
inlineprotected

Update function for the nodes in the channel region ahead of the finger tip: Nodes are evenly distributed along vertical lines between the top and bottom walls

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  }
RowVector3d w
Definition: Matrix_resize_int.cpp:3

References oomph::SpineNode::fraction(), oomph::Spine::geom_object_pt(), oomph::Spine::geom_parameter(), oomph::GeomObject::position(), oomph::SpineNode::spine_pt(), w, and oomph::Node::x().

Referenced by oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update().

◆ spine_node_update_film_lower()

template<class ELEMENT , class INTERFACE_ELEMENT >
void oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_film_lower ( SpineNode spine_node_pt)
inlineprotected

Update function for the deposited film region in the lower part of the domain: Vertical spines

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  }

References oomph::SpineNode::fraction(), oomph::Spine::geom_object_pt(), oomph::Spine::geom_parameter(), oomph::SpineNode::h(), oomph::GeomObject::position(), oomph::SpineNode::spine_pt(), w, and oomph::Node::x().

Referenced by oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update().

◆ spine_node_update_film_upper()

template<class ELEMENT , class INTERFACE_ELEMENT >
void oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_film_upper ( SpineNode spine_node_pt)
inlineprotected

Update function for the deposited film region in the upper part of the domain: Vertical spines

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  }

References oomph::SpineNode::fraction(), oomph::Spine::geom_object_pt(), oomph::Spine::geom_parameter(), oomph::SpineNode::h(), oomph::GeomObject::position(), oomph::SpineNode::spine_pt(), w, and oomph::Node::x().

Referenced by oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update().

◆ spine_node_update_horizontal_transition_lower()

template<class ELEMENT , class INTERFACE_ELEMENT >
void oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_horizontal_transition_lower ( SpineNode spine_node_pt)
inlineprotected

Update function for the horizontal transitition region in the lower part of the domain: Spine points from wall to origin

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  }

References oomph::SpineNode::fraction(), oomph::Spine::geom_object_pt(), oomph::Spine::geom_parameter(), oomph::SpineNode::h(), N, oomph::GeomObject::position(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_centre_fraction(), oomph::SpineNode::spine_pt(), sqrt(), w, and oomph::Node::x().

Referenced by oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update().

◆ spine_node_update_horizontal_transition_upper()

template<class ELEMENT , class INTERFACE_ELEMENT >
void oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_horizontal_transition_upper ( SpineNode spine_node_pt)
inlineprotected

Update function for the horizontal transitition region in the upper part of the domain: Spine points towards origin

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  }

References oomph::SpineNode::fraction(), oomph::Spine::geom_object_pt(), oomph::Spine::geom_parameter(), oomph::SpineNode::h(), N, oomph::GeomObject::position(), oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_centre_fraction(), oomph::SpineNode::spine_pt(), sqrt(), w, and oomph::Node::x().

Referenced by oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update().

◆ spine_node_update_vertical_transition_lower()

template<class ELEMENT , class INTERFACE_ELEMENT >
void oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_vertical_transition_lower ( SpineNode spine_node_pt)
inlineprotected

Update function for the vertical transitition region in the lower part of the domain: Spine points to origin

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  }

References oomph::SpineNode::fraction(), oomph::Spine::geom_object_pt(), oomph::Spine::geom_parameter(), oomph::SpineNode::h(), N, oomph::GeomObject::position(), GlobalParameters::S0, oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_centre_fraction(), oomph::SpineNode::spine_pt(), sqrt(), w, and oomph::Node::x().

Referenced by oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update().

◆ spine_node_update_vertical_transition_upper()

template<class ELEMENT , class INTERFACE_ELEMENT >
void oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update_vertical_transition_upper ( SpineNode spine_node_pt)
inlineprotected

Update function for the vertical transitition region in the upper part of the domain: Spine points to origin

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  }

References oomph::SpineNode::fraction(), oomph::Spine::geom_object_pt(), oomph::Spine::geom_parameter(), oomph::SpineNode::h(), N, oomph::GeomObject::position(), GlobalParameters::S0, oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_centre_fraction(), oomph::SpineNode::spine_pt(), sqrt(), w, and oomph::Node::x().

Referenced by oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::spine_node_update().

Member Data Documentation

◆ Bulk_element_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
Vector<FiniteElement*> oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Bulk_element_pt
protected

◆ Control_element_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
ELEMENT* oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Control_element_pt
protected

Pointer to control element (just under the symmetry line near the bubble tip; the bubble tip is located at s=[1.0,1.0] in this element

Referenced by oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::control_element_pt().

◆ Default_spine_centre_fraction

template<class ELEMENT , class INTERFACE_ELEMENT >
double oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Default_spine_centre_fraction
protected

Default spine fraction.

◆ H

template<class ELEMENT , class INTERFACE_ELEMENT >
double oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::H
protected

Thickness of deposited film.

◆ Interface_element_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
Vector<FiniteElement*> oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Interface_element_pt
protected

◆ Lower_wall_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
GeomObject* oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Lower_wall_pt
protected

Pointer to geometric object that represents the lower wall.

◆ Nh

template<class ELEMENT , class INTERFACE_ELEMENT >
unsigned oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Nh
protected

Number of elements across the deposited film.

◆ Nhalf

template<class ELEMENT , class INTERFACE_ELEMENT >
unsigned oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Nhalf
protected

Number of elements in vertical transition region (there are twice as many elements across the channel)

Referenced by oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::nfree_surface_spines().

◆ Nx1

template<class ELEMENT , class INTERFACE_ELEMENT >
unsigned oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Nx1
protected

Number of elements along wall in deposited film region.

Referenced by oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::nfree_surface_spines().

◆ Nx2

template<class ELEMENT , class INTERFACE_ELEMENT >
unsigned oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Nx2
protected

Number of elements along wall in horizontal transition region.

Referenced by oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::nfree_surface_spines().

◆ Nx3

template<class ELEMENT , class INTERFACE_ELEMENT >
unsigned oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Nx3
protected

Number of elements along wall in channel region.

◆ Spine_centre_fraction_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
double* oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Spine_centre_fraction_pt
protected

◆ Upper_wall_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
GeomObject* oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Upper_wall_pt
protected

Pointer to geometric object that represents the upper wall.

◆ Zeta_end

template<class ELEMENT , class INTERFACE_ELEMENT >
double oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Zeta_end
protected

Wall coordinate of end of liquid filled region (inflow)

◆ Zeta_start

template<class ELEMENT , class INTERFACE_ELEMENT >
double oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Zeta_start
protected

Start coordinate on wall.

◆ Zeta_transition_end

template<class ELEMENT , class INTERFACE_ELEMENT >
double oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Zeta_transition_end
protected

Wall coordinate of end of transition region.

◆ Zeta_transition_start

template<class ELEMENT , class INTERFACE_ELEMENT >
double oomph::BrethertonSpineMesh< ELEMENT, INTERFACE_ELEMENT >::Zeta_transition_start
protected

Wall coordinate of start of the transition region.


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