interface_elements.h
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Version 1.0; svn revision $LastChangedRevision: 1097 $
7 //LIC//
8 //LIC// $LastChangedDate: 2015-12-17 11:53:17 +0000 (Thu, 17 Dec 2015) $
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 //Header file for (one-dimensional) free surface elements
31 //Include guards, to prevent multiple includes
32 #ifndef OOMPH_INTERFACE_ELEMENTS_HEADER
33 #define OOMPH_INTERFACE_ELEMENTS_HEADER
34 
35 // Config header generated by autoconfig
36 #ifdef HAVE_CONFIG_H
37 #include <oomph-lib-config.h>
38 #endif
39 
40 #include "../generic/elements.h"
41 #include "../generic/spines.h"
42 #include "../generic/shape.h"
43 #include "../generic/hijacked_elements.h"
44 
45 namespace oomph
46 {
47 
48 //========================================================================
49 /// Base class for elements at the boundary of free surfaces or interfaces,
50 /// used typically to impose contact angle boundary conditions.
51 /// The elemental dimensions are one less than those of the
52 /// surface elements, or two less than those of the original bulk elements.
53 /// Thus in two-dimensional and axi-symmetric problems, are points,
54 /// but in three-dimensional problems, they are lines.
55 /// These boundaries may be in contact with a solid surface, in which case
56 /// the normal to that surface must be provided.
57 //=========================================================================
58  class FluidInterfaceBoundingElement : public virtual FaceElement
59  {
60  private:
61 
62  /// \short Function pointer to a wall unit normal function. Returns the
63  /// unit normal on the wall, at the specified Eulerian coordinate.
64  typedef void (*WallUnitNormalFctPt)(const Vector<double> &x,
65  Vector<double> &unit_normal);
66 
67  /// \short Pointer to a wall normal function that returns
68  /// the wall unit normal as a function of position in global
69  /// Eulerian coordinates.
71 
72  /// Pointer to the desired value of the contact angle (if any)
74 
75  /// Pointer to the desired value of the capillary number
76  double *Ca_pt;
77 
78  protected:
79 
80  /// \short Flag used to determine whether the contact angle is to be
81  /// used (0 if not), and whether it will be applied weakly as a force term
82  /// in the momentum equations (1) or by hijacking the kinematic
83  /// condition (2).
85 
86  /// \short Index at which the i-th velocity component is stored in the
87  /// element's nodes
88  Vector<unsigned> U_index_interface_boundary;
89 
90  /// \short Function that is used to determine the local equation number of
91  /// the kinematic equation associated with the nodes of the element
92  /// This must be overloaded depending on the node update scheme
93  virtual int kinematic_local_eqn(const unsigned &n)=0;
94 
95  /// \short Function that returns the unit normal of the bounding wall
96  /// directed out of the fluid
97  void wall_unit_normal(const Vector<double> &x, Vector<double> &normal)
98  {
99 #ifdef PARANOID
101  {
102 #endif
103  (*Wall_unit_normal_fct_pt)(x,normal);
104 #ifdef PARANOID
105  }
106  else
107  {
108  throw
109  OomphLibError("Wall unit normal fct has not been set",
110  "FluidInterfaceBoundingElement::wall_unit_normal()",
111  OOMPH_EXCEPTION_LOCATION);
112  }
113 #endif
114  }
115 
116  ///\short The geometric data of the parent element is included as
117  ///external data and so a (bulk) node update must take place after
118  ///the variation of any of this external data
119  inline void update_in_external_fd(const unsigned &i)
120  {
121  //Update the bulk element
122  bulk_element_pt()->node_update();
123  }
124 
125  ///\short The only external data are these geometric data so
126  ///We can omit the reset function (relying on the next update
127  //function to take care of the remesh)
128  inline void reset_in_external_fd(const unsigned &i) {}
129 
130  /// \short We require a final node update in the bulk element
131  /// after all finite differencing
132  inline void reset_after_external_fd()
133  {
134  //Update the bulk element
135  bulk_element_pt()->node_update();
136  }
137 
138  public:
139 
140  ///Constructor
143  Ca_pt(0), Contact_angle_flag(0) { }
144 
145  /// Access function: Pointer to wall unit normal function
147  {return Wall_unit_normal_fct_pt;}
148 
149  /// Access function: Pointer to wall unit normal function. Const version
151  {return Wall_unit_normal_fct_pt;}
152 
153  ///Access for nodal index at which the velocity components are stored
154  Vector<unsigned> &u_index_interface_boundary()
155  {
157  }
158 
159  /// \short Set a pointer to the desired contact angle. Optional boolean
160  /// (defaults to true)
161  /// chooses strong imposition via hijacking (true) or weak imposition
162  /// via addition to momentum equation (false). The default strong imposition
163  /// is appropriate for static contact angle problems.
164  void set_contact_angle(double* const &angle_pt,
165  const bool &strong=true);
166 
167  /// Access function to the pointer specifying the prescribed contact angle
168  double*& contact_angle_pt() {return Contact_angle_pt;}
169 
170  /// Access function to the pointer specifying the capillary number
171  double* &ca_pt() {return Ca_pt;}
172 
173  /// Return the value of the capillary number
174  double ca()
175  {
176 #ifdef PARANOID
177  if(Ca_pt!=0)
178  {
179 #endif
180  return *Ca_pt;
181 #ifdef PARANOID
182  }
183  else
184  {
185  throw
186  OomphLibError("Capillary number has not been set",
187  "FluidInterfaceBoundingElement::ca()",
188  OOMPH_EXCEPTION_LOCATION);
189  }
190 #endif
191  }
192 
193 
194  /// Return value of the contact angle
195  double &contact_angle()
196  {
197 #ifdef PARANOID
198  if(Contact_angle_pt==0)
199  {
200  std::string error_message = "Contact angle not set\n";
201  error_message +=
202  "Please use FluidInterfaceBoundingElement::set_contact_angle()\n";
203  throw OomphLibError(error_message,
204  OOMPH_CURRENT_FUNCTION,
205  OOMPH_EXCEPTION_LOCATION);
206  }
207 #endif
208  return *Contact_angle_pt;
209  }
210 
211  /// Calculate the residuals
212  void fill_in_contribution_to_residuals(Vector<double> &residuals)
213  {
214  //Add the residual contributions using a dummy matrix
216  residuals,GeneralisedElement::Dummy_matrix,0);
217  }
218 
219  /// Calculate the generic residuals contribution
221  Vector<double> &residuals, DenseMatrix<double> &jacobian,
222  unsigned flag)=0;
223 
224 
225  /// \short Empty helper function to calculate the additional contributions
226  /// arising from the node update strategy to the Jacobian within the
227  /// integration loop. This will be overloaded by elements that require
228  /// contributions to their underlying equations from boundary integrals.
229  /// The shape functions, their derivatives w.r.t. to the local coordinates,
230  /// the unit normal and integral weight are passed in so that they do not
231  /// have to be recalculated.
233  Vector<double> &residuals,
234  DenseMatrix<double> &jacobian,
235  const unsigned &flag,
236  const Shape &psif,
237  const DShape &dpsifds,
238  const Vector<double> &interpolated_n,
239  const double &W) {}
240 
241  ///Overload the output function
242  void output(std::ostream &outfile) {FiniteElement::output(outfile);}
243 
244  ///Output function
245  void output(std::ostream &outfile, const unsigned &n_plot)
246  {FiniteElement::output(outfile,n_plot);}
247 
248  ///Overload the C-style output function
249  void output(FILE* file_pt) {FiniteElement::output(file_pt);}
250 
251  ///C-style Output function
252  void output(FILE* file_pt, const unsigned &n_plot)
253  {FiniteElement::output(file_pt,n_plot);}
254 
255  };
256 
257 
258 
259 //==========================================================================
260 ///Specialisation of the interface boundary constraint to a point
261 //==========================================================================
264  {
265  protected:
266 
267  /// \short Overload the helper function to calculate the residuals and
268  /// (if flag==1) the Jacobian -- this function only deals with
269  /// the part of the Jacobian that can be handled generically.
270  /// Specific additional contributions may be provided in
271  /// add_additional_residual_contributions_interface_boundary(...)
273  Vector<double> &residuals,
274  DenseMatrix<double> &jacobian,
275  unsigned flag);
276 
277  public:
278 
279  /// Constructor
282 
283  };
284 
285 
286 //==========================================================================
287 ///Specialisation of the interface boundary constraint to a line
288 //==========================================================================
291  {
292  protected:
293 
294  /// \short Overload the helper function to calculate the residuals and
295  /// (if flag==true) the Jacobian -- this function only deals with
296  /// the part of the Jacobian that can be handled generically.
297  /// Specific additional contributions may be provided in
298  /// add_additional_residual_contributions_interface_boundary()
300  Vector<double> &residuals,
301  DenseMatrix<double> &jacobian,
302  unsigned flag);
303 
304  public:
305 
306  /// Constructor
309 
310  };
311 
312 
313 
314 
315 //=======================================================================
316 /// Base class establishing common interfaces and functions for all
317 /// Navier-Stokes-like fluid
318 /// interface elements. Namely, elements that represent either a free
319 /// surface or an interface between two fluids that have distinct
320 /// momentum-like equation for each velocity component.
321 //======================================================================
322  class FluidInterfaceElement : public virtual FaceElement
323  {
324  //Make the bounding element class a friend
326 
327  private:
328 
329  /// Pointer to the Capillary number
330  double *Ca_pt;
331 
332  /// Pointer to the Strouhal number
333  double *St_pt;
334 
335  /// Default value for physical constants
337 
338 
339  protected:
340 
341  /// Nodal index at which the i-th velocity component is stored.
342  Vector<unsigned> U_index_interface;
343 
344  /// \short The Data that contains the external pressure is stored
345  /// as external Data for the element. Which external Data item is it?
346  /// (int so it can be initialised to -1, indicating that external
347  /// pressure hasn't been set).
349 
350  /// \short Pointer to the Data item that stores the external pressure
352 
353  /// \short Which of the values in Pext_data_pt stores the external pressure
355 
356  /// \short Access function that returns the local equation number
357  /// for the (scalar) kinematic equation associated with the j-th local
358  /// node. This must be overloaded by specific interface elements
359  /// and depends on the method for handing the free-surface deformation.
360  virtual int kinematic_local_eqn(const unsigned &n)=0;
361 
362  /// \short Access function for the local equation number that
363  /// corresponds to the external pressure.
365  {
366 #ifdef PARANOID
368  {
369  throw OomphLibError("No external pressure has been set\n",
370  OOMPH_CURRENT_FUNCTION,
371  OOMPH_EXCEPTION_LOCATION);
372  }
373 #endif
374  return external_local_eqn(External_data_number_of_external_pressure,
376  }
377 
378  /// \short Helper function to calculate the residuals and
379  /// (if flag==1) the Jacobian of the equations.
380  /// This is implemented generically using the surface
381  /// divergence information that is overloaded in each element
382  /// i.e. axisymmetric, two- or three-dimensional.
384  Vector<double> &residuals,
385  DenseMatrix<double> &jacobian,
386  unsigned flag);
387 
388  /// \short Compute the surface gradient and surface divergence
389  /// operators given the shape functions, derivatives,
390  /// tangent vectors and position. All derivatives and
391  /// tangent vectors should be formed
392  /// with respect to the local coordinates.
393  ///
394  /// Return the jacobian of the surface, as well
395  /// as the dpsidS, and dpsidS_div objects.
396  ///
397  /// This is the only
398  /// function that needs to be overloaded to specify
399  /// different geometries.
400  ///
401  /// In order to compute the surface gradient of a scalar
402  /// function one needs only compute the sum over the nodes
403  /// of dpsidS(l,i) * nodal_value(l,scalar_index)
404  /// To compute the surface divergence of a vector quantity
405  /// one computes a sum over nodes and coordinate directions
406  /// dpsidS_div(l,i) * nodal_value(l,vector_index[i])
407  /// In Cartesian cordinates the two surface derivatives are the
408  /// same, but in Axisymmetric coordinates they are not!
409  virtual double compute_surface_derivatives(const Shape &psi, const DShape &dpsids,
410  const DenseMatrix<double> &interpolated_t,
411  const Vector<double> &interpolated_x,
412  DShape &dpsidS,
413  DShape &dpsidS_div)=0;
414 
415  /// \short Helper function to calculate the additional contributions
416  /// to the resisuals and Jacobian that arise from specific node update
417  /// strategies. This is called within the integration loop over the
418  /// element (for efficiency) and therefore requires a fairly large
419  /// number of input parameters:
420  /// - the velocity shape functions and their derivatives w.r.t.
421  /// the local coordinates
422  /// - the surface gradient and divergence of the velocity shape
423  /// functions
424  /// - The local and Eulerian coordinates,
425  /// - the outer unit normal,
426  /// - the integration weight from the integration scheme
427  /// - the Jacobian of the mapping between the local and global coordinates
428  /// along the element. (Note that in the axisymmmetric case this
429  /// includes the r term)!
431  Vector<double> &residuals,
432  DenseMatrix<double> &jacobian,
433  const unsigned &flag,
434  const Shape &psif,
435  const DShape &dpsifds,
436  const DShape &dpsifdS,
437  const DShape &dpsifdS_div,
438  const Vector<double> &s,
439  const Vector<double> &interpolated_x,
440  const Vector<double> &interpolated_n,
441  const double &W,
442  const double &J) {}
443 
444  public:
445 
446 
447  /// Constructor, set the default values of the booleans and pointers (null)
449  {
450  // Initialise pointer to capillary number
451  Ca_pt = 0;
452 
453  //Set the Strouhal number to the default value
455  }
456 
457  /// \short Virtual function that specifies the non-dimensional
458  /// surface tension as a function of local position within the element.
459  /// The default behaviour is a constant surface tension of value 1.0
460  /// This function can be overloaded in more specialised elements to
461  /// incorporate variations in surface tension.
462  virtual double sigma(const Vector<double> &s_local) { return 1.0; }
463 
464  /// Calculate the residuals by calling the generic residual contribution.
465  void fill_in_contribution_to_residuals(Vector<double> &residuals)
466  {
467  //Add the residual contributions
469  residuals,GeneralisedElement::Dummy_matrix,0);
470  }
471 
472 
473 
474  /// The value of the Capillary number
475  const double& ca() const {
476 #ifdef PARANOID
477  if(Ca_pt!=0)
478  {
479 #endif
480  return *Ca_pt;
481 #ifdef PARANOID
482  }
483  else
484  {
485  throw
486  OomphLibError("Capillary number has not been set",
487  "FluidInterfaceElement::ca()",
488  OOMPH_EXCEPTION_LOCATION);
489  }
490 #endif
491  }
492 
493  /// Pointer to the Capillary number
494  double*& ca_pt() {return Ca_pt;}
495 
496  /// The value of the Strouhal number
497  const double &st() const {return *St_pt;}
498 
499  /// The pointer to the Strouhal number
500  double* &st_pt() {return St_pt;}
501 
502  /// \short Return the i-th velocity component at local node j.
503  double u(const unsigned &j, const unsigned &i)
504  {return node_pt(j)->value(U_index_interface[i]);}
505 
506  /// \short Calculate the i-th velocity component at the local coordinate s.
507  double interpolated_u(const Vector<double> &s, const unsigned &i);
508 
509  /// Return the value of the external pressure
510  double pext() const
511  {
512  //If the external pressure has not been set, then return a
513  //default value of zero.
514  if(Pext_data_pt==0)
515  {
516  return 0.0;
517  }
518  //Otherwise return the appropriate value
519  else
520  {
522  }
523  }
524 
525  /// \short Set the Data that contains the single pressure value
526  /// that specifies the "external pressure" for the
527  /// interface/free-surface. Setting this only makes sense
528  /// if the interface is, in fact, a free surface (well,
529  /// an interface to another inviscid fluid if you want to be picky).
530  void set_external_pressure_data(Data* external_pressure_data_pt)
531  {
532 #ifdef PARANOID
533  if (external_pressure_data_pt->nvalue()!=1)
534  {
535  std::ostringstream error_message;
536  error_message
537  << "External pressure Data must only contain a single value!\n"
538  << "This one contains "
539  << external_pressure_data_pt->nvalue() << std::endl;
540 
541  throw OomphLibError(error_message.str(),
542  OOMPH_CURRENT_FUNCTION,
543  OOMPH_EXCEPTION_LOCATION);
544  }
545 #endif
546 
547  // Store pointer explicitly
548  Pext_data_pt=external_pressure_data_pt;
549 
550  // Add the external pressure to the element's external Data?
551  // But do not finite-difference with respect to it
552  this->add_external_data(Pext_data_pt,false);
553 
554  // The external pressure has just been promoted to become
555  // external Data of this element -- what is its number?
556  External_data_number_of_external_pressure=this->nexternal_data()-1;
557 
558  // Index of pressure value in Data object
560  }
561 
562  /// \short Set the Data that contains the pressure value
563  /// that specifies the "external pressure" for the
564  /// interface/free-surface. Setting this only makes sense
565  /// if the interface is, in fact, a free surface (well,
566  /// an interface to another inviscid fluid if you want to be picky).
567  /// Second argument specifies the index of the pressure
568  /// value within the Data object.
569  void set_external_pressure_data(Data* external_pressure_data_pt,
570  const unsigned&
571  index_of_external_pressure_value)
572  {
573  // Index of pressure value in Data object
574  Index_of_external_pressure_value=index_of_external_pressure_value;
575 
576 #ifdef PARANOID
577  if (index_of_external_pressure_value>=external_pressure_data_pt->nvalue())
578  {
579  std::ostringstream error_message;
580  error_message
581  << "External pressure Data only contains "
582  << external_pressure_data_pt->nvalue() << " values\n"
583  << "You have declared value " << index_of_external_pressure_value
584  << " to be the value representing the pressure\n" << std::endl;
585  throw OomphLibError(error_message.str(),
586  OOMPH_CURRENT_FUNCTION,
587  OOMPH_EXCEPTION_LOCATION);
588  }
589 #endif
590 
591  // Store pointer explicitly
592  Pext_data_pt=external_pressure_data_pt;
593 
594  // Add the external pressure to the element's external Data?
595  // But do not finite-difference with respect to it
596  this->add_external_data(Pext_data_pt,false);
597 
598  // The external pressure has just been promoted to become
599  // external Data of this element -- what is its number?
600  External_data_number_of_external_pressure=this->nexternal_data()-1;
601  }
602 
603 
604  /// \short Create a bounding element e.g. to apply a contact angle boundary
605  /// condition
607  const int &face_index)
608  {
609  throw OomphLibError("Virtual function not yet implemented",
610  OOMPH_CURRENT_FUNCTION,
611  OOMPH_EXCEPTION_LOCATION);
612  return 0;
613  }
614 
615 
616  /// \short Hijack the kinematic condition at the node numbers passed in
617  /// the vector. The node numbers correspond to the local numbers of
618  /// nodes in the associated bulk element.
619  /// This is required so that contact-angle conditions can be applied
620  /// by the FluidInterfaceBoundingElements.
621  virtual void hijack_kinematic_conditions(const Vector<unsigned>
622  &bulk_node_number)=0;
623 
624  ///Overload the output function
625  void output(std::ostream &outfile) {FiniteElement::output(outfile);}
626 
627  ///Output function
628  void output(std::ostream &outfile, const unsigned &n_plot);
629 
630  ///Overload the C-style output function
631  void output(FILE* file_pt) {FiniteElement::output(file_pt);}
632 
633  ///C-style Output function
634  void output(FILE* file_pt, const unsigned &n_plot);
635 
636  };
637 
638 
639 //=============================================================
640 /// Class that establishes the surface derivative functions for
641 /// LineElements. These are defined in a separate class so that
642 /// they can be used by other interface equation-type classes.
643 //=============================================================
645  {
646  public:
647  //Empty Constructor
649 
650  protected:
651 
652 
653  ///Fill in the specific surface derivative calculations
654  double compute_surface_derivatives(const Shape &psi, const DShape &dpsids,
655  const DenseMatrix<double> &interpolated_t,
656  const Vector<double> &interpolated_x,
657  DShape &surface_gradient,
658  DShape &surface_divergence);
659 
660  };
661 
662 
663 //=============================================================
664 /// Class that establishes the surface derivative functions for
665 /// AxisymmetricInterfaceElements.
666 /// These are defined in a separate class so that
667 /// they can be used by other interface equation-type classes.
668 //=============================================================
670  {
671  public:
672  //Empty Constructor
674 
675  protected:
676 
677 
678  ///Fill in the specific surface derivative calculations
679  double compute_surface_derivatives(const Shape &psi, const DShape &dpsids,
680  const DenseMatrix<double> &interpolated_t,
681  const Vector<double> &interpolated_x,
682  DShape &surface_gradient,
683  DShape &surface_divergence);
684 
685  };
686 
687 
688 //=============================================================
689 /// Class that establishes the surface derivative functions for
690 /// SurfaceInterfaceElements (2D surfaces in 3D space)
691 /// These are defined in a separate class so that
692 /// they can be used by other interface equation-type classes.
693 //=============================================================
695  {
696  public:
697  //Empty Constructor
699 
700  protected:
701 
702 
703  ///Fill in the specific surface derivative calculations
704  double compute_surface_derivatives(const Shape &psi, const DShape &dpsids,
705  const DenseMatrix<double> &interpolated_t,
706  const Vector<double> &interpolated_x,
707  DShape &surface_gradient,
708  DShape &surface_divergence);
709 
710  };
711 
712 
713 }
714 
715 #endif
716 
717 
718 
719 
720 
721 
void(* WallUnitNormalFctPt)(const Vector< double > &x, Vector< double > &unit_normal)
Function pointer to a wall unit normal function. Returns the unit normal on the wall, at the specified Eulerian coordinate.
static double Default_Physical_Constant_Value
Default value for physical constants.
Specialisation of the interface boundary constraint to a line.
void output(FILE *file_pt)
Overload the C-style output function.
virtual void hijack_kinematic_conditions(const Vector< unsigned > &bulk_node_number)=0
Hijack the kinematic condition at the node numbers passed in the vector. The node numbers correspond ...
double ca()
Return the value of the capillary number.
Data * Pext_data_pt
Pointer to the Data item that stores the external pressure.
double *& ca_pt()
Access function to the pointer specifying the capillary number.
virtual void fill_in_generic_residual_contribution_interface_boundary(Vector< double > &residuals, DenseMatrix< double > &jacobian, unsigned flag)=0
Calculate the generic residuals contribution.
void fill_in_generic_residual_contribution_interface_boundary(Vector< double > &residuals, DenseMatrix< double > &jacobian, unsigned flag)
Overload the helper function to calculate the residuals and (if flag==1) the Jacobian – this function...
unsigned Contact_angle_flag
Flag used to determine whether the contact angle is to be used (0 if not), and whether it will be app...
double * Contact_angle_pt
Pointer to the desired value of the contact angle (if any)
double pext() const
Return the value of the external pressure.
void set_external_pressure_data(Data *external_pressure_data_pt)
Set the Data that contains the single pressure value that specifies the "external pressure" for the i...
Specialisation of the interface boundary constraint to a point.
void output(std::ostream &outfile, const unsigned &n_plot)
Output function.
unsigned Index_of_external_pressure_value
Which of the values in Pext_data_pt stores the external pressure.
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Calculate the residuals by calling the generic residual contribution.
double compute_surface_derivatives(const Shape &psi, const DShape &dpsids, const DenseMatrix< double > &interpolated_t, const Vector< double > &interpolated_x, DShape &surface_gradient, DShape &surface_divergence)
Fill in the specific surface derivative calculations.
void output(FILE *file_pt)
Overload the C-style output function.
void reset_in_external_fd(const unsigned &i)
The only external data are these geometric data so We can omit the reset function (relying on the nex...
double u(const unsigned &j, const unsigned &i)
Return the i-th velocity component at local node j.
const double & ca() const
The value of the Capillary number.
virtual void add_additional_residual_contributions_interface_boundary(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag, const Shape &psif, const DShape &dpsifds, const Vector< double > &interpolated_n, const double &W)
Empty helper function to calculate the additional contributions arising from the node update strategy...
double * St_pt
Pointer to the Strouhal number.
void wall_unit_normal(const Vector< double > &x, Vector< double > &normal)
Function that returns the unit normal of the bounding wall directed out of the fluid.
double * Ca_pt
Pointer to the Capillary number.
void output(std::ostream &outfile)
Overload the output function.
Vector< unsigned > U_index_interface_boundary
Index at which the i-th velocity component is stored in the element's nodes.
void output(std::ostream &outfile)
Overload the output function.
void reset_after_external_fd()
We require a final node update in the bulk element after all finite differencing. ...
void update_in_external_fd(const unsigned &i)
The geometric data of the parent element is included as external data and so a (bulk) node update mus...
WallUnitNormalFctPt & wall_unit_normal_fct_pt()
Access function: Pointer to wall unit normal function.
const double & st() const
The value of the Strouhal number.
void fill_in_generic_residual_contribution_interface_boundary(Vector< double > &residuals, DenseMatrix< double > &jacobian, unsigned flag)
Overload the helper function to calculate the residuals and (if flag==true) the Jacobian – this funct...
FluidInterfaceElement()
Constructor, set the default values of the booleans and pointers (null)
double compute_surface_derivatives(const Shape &psi, const DShape &dpsids, const DenseMatrix< double > &interpolated_t, const Vector< double > &interpolated_x, DShape &surface_gradient, DShape &surface_divergence)
Fill in the specific surface derivative calculations.
double *& contact_angle_pt()
Access function to the pointer specifying the prescribed contact angle.
virtual int kinematic_local_eqn(const unsigned &n)=0
Function that is used to determine the local equation number of the kinematic equation associated wit...
double compute_surface_derivatives(const Shape &psi, const DShape &dpsids, const DenseMatrix< double > &interpolated_t, const Vector< double > &interpolated_x, DShape &surface_gradient, DShape &surface_divergence)
Fill in the specific surface derivative calculations.
virtual int kinematic_local_eqn(const unsigned &n)=0
Access function that returns the local equation number for the (scalar) kinematic equation associated...
Vector< unsigned > & u_index_interface_boundary()
Access for nodal index at which the velocity components are stored.
WallUnitNormalFctPt Wall_unit_normal_fct_pt
Pointer to a wall normal function that returns the wall unit normal as a function of position in glob...
double interpolated_u(const Vector< double > &s, const unsigned &i)
Calculate the i-th velocity component at the local coordinate s.
virtual double sigma(const Vector< double > &s_local)
Virtual function that specifies the non-dimensional surface tension as a function of local position w...
WallUnitNormalFctPt wall_unit_normal_fct_pt() const
Access function: Pointer to wall unit normal function. Const version.
double * Ca_pt
Pointer to the desired value of the capillary number.
virtual double compute_surface_derivatives(const Shape &psi, const DShape &dpsids, const DenseMatrix< double > &interpolated_t, const Vector< double > &interpolated_x, DShape &dpsidS, DShape &dpsidS_div)=0
Compute the surface gradient and surface divergence operators given the shape functions, derivatives, tangent vectors and position. All derivatives and tangent vectors should be formed with respect to the local coordinates.
void output(FILE *file_pt, const unsigned &n_plot)
C-style Output function.
double *& st_pt()
The pointer to the Strouhal number.
int pext_local_eqn()
Access function for the local equation number that corresponds to the external pressure.
Vector< unsigned > U_index_interface
Nodal index at which the i-th velocity component is stored.
virtual void fill_in_generic_residual_contribution_interface(Vector< double > &residuals, DenseMatrix< double > &jacobian, unsigned flag)
Helper function to calculate the residuals and (if flag==1) the Jacobian of the equations. This is implemented generically using the surface divergence information that is overloaded in each element i.e. axisymmetric, two- or three-dimensional.
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Calculate the residuals.
virtual FluidInterfaceBoundingElement * make_bounding_element(const int &face_index)
Create a bounding element e.g. to apply a contact angle boundary condition.
int External_data_number_of_external_pressure
The Data that contains the external pressure is stored as external Data for the element. Which external Data item is it? (int so it can be initialised to -1, indicating that external pressure hasn't been set).
virtual void add_additional_residual_contributions_interface(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag, const Shape &psif, const DShape &dpsifds, const DShape &dpsifdS, const DShape &dpsifdS_div, const Vector< double > &s, const Vector< double > &interpolated_x, const Vector< double > &interpolated_n, const double &W, const double &J)
Helper function to calculate the additional contributions to the resisuals and Jacobian that arise fr...
void set_external_pressure_data(Data *external_pressure_data_pt, const unsigned &index_of_external_pressure_value)
Set the Data that contains the pressure value that specifies the "external pressure" for the interfac...
double & contact_angle()
Return value of the contact angle.
void set_contact_angle(double *const &angle_pt, const bool &strong=true)
Set a pointer to the desired contact angle. Optional boolean (defaults to true) chooses strong imposi...
double *& ca_pt()
Pointer to the Capillary number.