young_laplace_elements.cc
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$
7 //LIC//
8 //LIC// $LastChangedDate$
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 
31 //Non-inline functions for YoungLaplace elements
32 #include "young_laplace_elements.h"
33 
34 namespace oomph
35 {
36 
37 //======================================================================
38 // Set the data for the number of Variables at each node
39 //======================================================================
40 template<>
42 ={1,1,1,1,1,1,1,1,
43  1,1,1,1,1,1,1,1};
44 template<>
45 const unsigned QYoungLaplaceElement<3>::Initial_Nvalue[9]={1,1,1,1,1,1,1,1,1};
46 template<>
47 const unsigned QYoungLaplaceElement<2>::Initial_Nvalue[4]={1,1,1,1};
48 
49 
50 //======================================================================
51 /// Get exact position vector to meniscus
52 //======================================================================
54  Vector<double>& r,
56 {
57  // Get global coordinates
58  Vector<double> x(2);
59  interpolated_x(s,x);
60 
61  // Exact solution Vector (here a scalar)
62  Vector<double> exact_soln(1);
63 
64  // Get exact solution at this point
65  (*exact_soln_pt)(x,exact_soln);
66 
67  if (!use_spines())
68  {
69  r[0]=x[0];
70  r[1]=x[1];
71  r[2]=exact_soln[0];
72  }
73  else
74  {
75  /// Get spines values
76  Vector<double> spine_base(3,0.0);
77  Vector<double> spine(3,0.0);
78  Vector< Vector<double> > dspine_base;
79  allocate_vector_of_vectors(2,3,dspine_base);
80  Vector< Vector<double> > dspine;
81  allocate_vector_of_vectors(2,3,dspine);
82 
83  get_spine_base(x,spine_base,dspine_base);
84  get_spine(x,spine,dspine);
85 
86  /// Global Eulerian cooordinates
87  for (unsigned j=0; j<3; j++)
88  {
89  r[j]=spine_base[j]+exact_soln[0]*spine[j];
90  }
91  }
92 
93 }
94 
95 //======================================================================
96 /// Get position vector to meniscus
97 //======================================================================
99  Vector<double>& r) const
100  {
101 
102  // Get global coordinates
103  Vector<double> x(2);
104  interpolated_x(s,x);
105 
106  //Displacement along spine (or cartesian displacement)
107  double u=interpolated_u(s);
108 
109  // cartesian calculation case
110  if (!use_spines())
111  {
112  r[0]=x[0];
113  r[1]=x[1];
114  r[2]=u;
115  }
116  // spine case
117  else
118  {
119  /// Get spines values
120  Vector<double> spine_base(3,0.0);
121  Vector<double> spine(3,0.0);
122  Vector< Vector<double> > dspine_base;
123  allocate_vector_of_vectors(2,3,dspine_base);
124  Vector< Vector<double> > dspine;
125  allocate_vector_of_vectors(2,3,dspine);
126 
127  get_spine_base(x,spine_base,dspine_base);
128  get_spine(x,spine,dspine);
129 
130  /// Global Eulerian cooordinates
131  for (unsigned j=0; j<3; j++)
132  {
133  r[j]=spine_base[j]+u*spine[j];
134  }
135  }
136 
137  }
138 
139 
140 
141 //======================================================================
142 /// Compute element residual vector. Pure version without hanging nodes
143 //======================================================================
145  Vector<double> &residuals)
146  {
147 
148  //Find out how many nodes there are
149  unsigned n_node = nnode();
150 
151  //Set up memory for the shape functions
152  Shape psi(n_node);
153  DShape dpsidzeta(n_node,2);
154 
155  //Set the value of n_intpt
156  unsigned n_intpt = integral_pt()->nweight();
157 
158  //Integers to store the local equation numbers
159  int local_eqn=0;
160 
161  //Loop over the integration points
162  for(unsigned ipt=0;ipt<n_intpt;ipt++)
163  {
164  //Get the integral weight
165  double w = integral_pt()->weight(ipt);
166 
167  //Call the derivatives of the shape and test functions
168  double J = dshape_eulerian_at_knot(ipt,psi,dpsidzeta);
169 
170  //Premultiply the weights and the Jacobian
171  double W = w*J;
172 
173  //Calculate local values of displacement along spine and its derivatives
174  //Allocate and initialise to zero
175  double interpolated_u=0.0;
177  Vector<double> interpolated_dudzeta(2,0.0);
178 
179  //Calculate function value and derivatives:
180  //-----------------------------------------
181  // Loop over nodes
182  for(unsigned l=0;l<n_node;l++)
183  {
184  interpolated_u += u(l)*psi(l);
185  // Loop over directions
186  for(unsigned j=0;j<2;j++)
187  {
188  interpolated_zeta[j] += nodal_position(l,j)*psi(l);
189  interpolated_dudzeta[j] += u(l)*dpsidzeta(l,j);
190  }
191  }
192 
193 
194 
195  // Allocation and definition of variables necessary for
196  // further calculations
197 
198  /// "Simple" case
199  ///--------------
200  double nonlinearterm=1.0;
201  double sqnorm=0.0;
202 
203  /// Spine case
204  ///-----------
205 
206  // Derivs of position vector w.r.t. global intrinsic coords
207  Vector<Vector<double> > dRdzeta;
208  allocate_vector_of_vectors(2,3,dRdzeta);
209 
210  // Unnormalised normal
211  Vector<double> N_unnormalised(3,0.0);
212 
213  // Spine and spine basis vectors, entries initialised to zero
214  Vector<double> spine_base(3,0.0), spine(3,0.0);
215 
216  // Derivative of spine basis vector w.r.t to the intrinsic
217  // coordinates: dspine_base[i,j] = j-th component of the deriv.
218  // of the spine basis vector w.r.t. to the i-th global intrinsic
219  // coordinate
220  Vector< Vector<double> > dspine_base;
221  allocate_vector_of_vectors(2,3,dspine_base);
222 
223  // Derivative of spine vector w.r.t to the intrinsic
224  // coordinates: dspine[i,j] = j-th component of the deriv.
225  // of the spine vector w.r.t. to the i-th global intrinsic
226  // coordinate
227  Vector< Vector<double> > dspine;
228  allocate_vector_of_vectors(2,3,dspine);
229 
230  // Vector v_\alpha contains the numerator of the variations of the
231  // area element {\cal A}^{1/2} w.r.t. the components of dR/d\zeta_\alpha
232  Vector<double> area_variation_numerator_0(3,0.0);
233  Vector<double> area_variation_numerator_1(3,0.0);
234 
235  // Vector position
236  Vector<double> r(3,0.0);
237 
238  //No spines
239  //---------
240  if (!use_spines())
241  {
242  for (unsigned j=0; j<2; j++)
243  {
244  sqnorm += interpolated_dudzeta[j]*interpolated_dudzeta[j];
245  }
246  nonlinearterm=1.0/sqrt(1.0+sqnorm);
247  }
248 
249  //Spines
250  //------
251  else
252  {
253  // Get the spines
254  get_spine_base(interpolated_zeta, spine_base, dspine_base);
255  get_spine(interpolated_zeta, spine, dspine);
256 
257  // calculation of dR/d\zeta_\alpha
258  for (unsigned alpha=0;alpha<2;alpha++)
259  {
260  // Product rule for d(u {\bf S} ) / d \zeta_\alpha
261  Vector<double> dudzeta_times_spine(3,0.0);
262  scalar_times_vector(interpolated_dudzeta[alpha],
263  spine,dudzeta_times_spine);
264 
265  Vector<double> u_times_dspinedzeta(3,0.0);
266  scalar_times_vector(interpolated_u,dspine[alpha],u_times_dspinedzeta);
267 
268  Vector<double> d_u_times_spine_dzeta(3,0.0);
269  vector_sum(dudzeta_times_spine,
270  u_times_dspinedzeta,
271  d_u_times_spine_dzeta);
272 
273  // Add derivative of spine base
274  vector_sum(d_u_times_spine_dzeta,dspine_base[alpha],dRdzeta[alpha]);
275  }
276 
277  /// Get the unnormalized normal
278  cross_product(dRdzeta[0],dRdzeta[1],N_unnormalised);
279 
280  // Tmp storage
281  Vector<double> v_tmp_1(3,0.0);
282  Vector<double> v_tmp_2(3,0.0);
283 
284  // Calculation of
285  // |dR/d\zeta_1|^2 dR/d\zeta_0 - <dR/d\zeta_0,dR/d\zeta_1>dR/d\zeta_1
286  scalar_times_vector(pow(two_norm(dRdzeta[1]),2), dRdzeta[0], v_tmp_1);
287  scalar_times_vector(-1*scalar_product(dRdzeta[0],dRdzeta[1]),
288  dRdzeta[1], v_tmp_2);
289  vector_sum(v_tmp_1,v_tmp_2,area_variation_numerator_0);
290 
291  // Calculation of
292  // |dR/d\zeta_0|^2 dR/d\zeta_1 - <dR/d\zeta_0,dR/d\zeta_1>dR/d\zeta_0
293  scalar_times_vector(pow(two_norm(dRdzeta[0]),2), dRdzeta[1], v_tmp_1);
294  scalar_times_vector(-1*scalar_product(dRdzeta[0],dRdzeta[1]),
295  dRdzeta[0], v_tmp_2);
296  vector_sum(v_tmp_1,v_tmp_2,area_variation_numerator_1);
297 
298  // Global Eulerian cooordinates
299  for (unsigned j=0; j<3; j++)
300  {
301  r[j]=spine_base[j]+interpolated_u*spine[j];
302  }
303 
304  }
305 
306 
307  // Assemble residuals
308  //-------------------
309 
310  // Loop over the test (shape) functions
311  for(unsigned l=0;l<n_node;l++)
312  {
313  //Get the local equation
314  local_eqn = u_local_eqn(l);
315 
316  /*IF it's not a boundary condition*/
317  if(local_eqn >= 0)
318  {
319 
320  // "simple" calculation case
321  if (!use_spines())
322  {
323  // Add source term: The curvature
324  residuals[local_eqn] += get_kappa()*psi(l)*W;
325 
326  // The YoungLaplace bit itself
327  for(unsigned k=0;k<2;k++)
328  {
329  residuals[local_eqn] += nonlinearterm*
330  interpolated_dudzeta[k]*dpsidzeta(l,k)*W;
331  }
332  }
333 
334  // Spine calculation case
335  else
336  {
337  // Calculation of d(u S)/d\zeta_0
338  //-------------------------------
339  Vector<double> v_tmp_1(3,0.0);
340  scalar_times_vector(dpsidzeta(l,0), spine, v_tmp_1);
341 
342  Vector<double> v_tmp_2(3,0.0);
343  scalar_times_vector(psi(l),dspine[0], v_tmp_2);
344 
345  Vector<double> d_uS_dzeta0(3,0.0);
346  vector_sum(v_tmp_1,v_tmp_2,d_uS_dzeta0);
347 
348  // Add contribution to residual
349  residuals[local_eqn] +=
350  W*scalar_product(area_variation_numerator_0,d_uS_dzeta0)
351  /two_norm(N_unnormalised);
352 
353  // Calculation of d(u S)/d\zeta_1
354  scalar_times_vector(dpsidzeta(l,1), spine, v_tmp_1);
355  scalar_times_vector(psi(l),dspine[1], v_tmp_2);
356  Vector<double> d_uS_dzeta1(3,0.0);
357  vector_sum(v_tmp_1,v_tmp_2,d_uS_dzeta1);
358 
359  // Add contribution to residual
360  residuals[local_eqn] +=
361  W*scalar_product(area_variation_numerator_1,d_uS_dzeta1)
362  /two_norm(N_unnormalised);
363 
364  // Curvature contribution to the residual : kappa N S test
365  residuals[local_eqn] += W*(get_kappa())*
366  scalar_product(N_unnormalised,spine)*psi(l);
367  }
368  }
369  }
370 
371  } // End of loop over integration points
372 
373  }
374 
375 
376 
377 //======================================================================
378 /// Self-test: Return 0 for OK
379 //======================================================================
381  {
382 
383  bool passed=true;
384 
385  // Check lower-level stuff
386  if (FiniteElement::self_test()!=0)
387  {
388  passed=false;
389  }
390 
391  // Return verdict
392  if (passed)
393  {
394  return 0;
395  }
396  else
397  {
398  return 1;
399  }
400 
401  }
402 
403 
404 
405 //======================================================================
406 /// Output solution at nplot points in each coordinate direction
407 //======================================================================
408  void YoungLaplaceEquations::output(std::ostream &outfile,
409  const unsigned &nplot)
410  {
411 
412 
413  //Vector of local coordinates
414  Vector<double> s(2);
415 
416  // Tecplot header info
417  outfile << tecplot_zone_string(nplot);
418 
419  // Loop over plot points
420  unsigned num_plot_points=nplot_points(nplot);
421  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
422  {
423 
424  // Get local coordinates of plot point
425  get_s_plot(iplot,nplot,s);
426 
427  // Compute intrinsic coordinates
428  Vector<double> xx(2,0.0);
429  for(unsigned i=0;i<2;i++)
430  {
431  xx[i]=interpolated_x(s,i) ;
432  }
433 
434  // Calculate the cartesian coordinates of point on meniscus
435  Vector<double> r(3,0.0);
436 
437  // Position
438  if (use_spines())
439  {
440  position(s,r);
441  }
442  else
443  {
444  r[0]=xx[0];
445  r[1]=xx[1];
446  r[2]=interpolated_u(s);
447  }
448 
449  // Output positon on meniscus
450  for(unsigned i=0;i<3;i++)
451  {
452  outfile << r[i] << " ";
453  }
454 
455  // Get spine stuff
456  Vector<double> spine_base(3,0.0), spine(3,0.0);
457  Vector< Vector<double> > dspine_base;
458  allocate_vector_of_vectors(2,3,dspine_base);
459  Vector< Vector<double> > dspine;
460  allocate_vector_of_vectors(2,3,dspine);
461 
462  // Get the spines
463  if (use_spines())
464  {
465  get_spine_base(xx, spine_base, dspine_base);
466  get_spine(xx, spine, dspine);
467  }
468 
469 
470  // Output spine base
471  for(unsigned i=0;i<3;i++)
472  {
473  outfile << spine_base[i] << " ";
474  }
475 
476  // Output spines
477  for(unsigned i=0;i<3;i++)
478  {
479  outfile << spine[i] << " ";
480  }
481 
482 
483  // Output intrinsic coordinates
484  for(unsigned i=0;i<2;i++)
485  {
486  outfile << xx[i] << " ";
487  }
488 
489  // Output unknown
490  outfile << interpolated_u(s) << " ";
491 
492 
493 
494  // Done
495  outfile << std::endl;
496 
497  }
498 
499  // Write tecplot footer (e.g. FE connectivity lists)
500  write_tecplot_zone_footer(outfile,nplot);
501 
502 }
503 
504 
505  //======================================================================
506  /// Output exact solution
507  ///
508  /// Solution is provided via function pointer.
509  /// Plot at a given number of plot points.
510  //======================================================================
511  void YoungLaplaceEquations::output_fct(std::ostream &outfile,
512  const unsigned &nplot,
514  {
515 
516  //Vector of local coordinates
517  Vector<double> s(2);
518 
519  // Vector for coordinates
520  Vector<double> x(2);
521 
522  // Tecplot header info
523  outfile << tecplot_zone_string(nplot);
524 
525  // Exact solution Vector (here a scalar)
526  Vector<double> exact_soln(1);
527 
528  // Loop over plot points
529  unsigned num_plot_points=nplot_points(nplot);
530  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
531  {
532 
533  // Get local coordinates of plot point
534  get_s_plot(iplot,nplot,s);
535 
536  // Get x position as Vector
537  interpolated_x(s,x);
538 
539  /// Calculate the cartesian coordinates of point on meniscus
540  Vector<double> r_exact(3,0.0);
541  exact_position(s,r_exact,exact_soln_pt);
542 
543  //Output x_exact,y_exact,z_exact
544  for(unsigned i=0;i<3;i++)
545  {
546  outfile << r_exact[i] << " ";
547  }
548 
549  // Done
550  outfile << std::endl;
551 
552  }
553 
554  // Write tecplot footer (e.g. FE connectivity lists)
555  write_tecplot_zone_footer(outfile,nplot);
556 
557  }
558 
559 
560  //======================================================================
561  /// Validate against exact solution
562  ///
563  /// Solution is provided via function pointer.
564  /// Plot error at a given number of plot points.
565  ///
566  //======================================================================
567  void YoungLaplaceEquations::compute_error(std::ostream &outfile,
569  double& error, double& norm)
570  {
571 
572  // Initialise
573  error=0.0;
574  norm=0.0;
575 
576  //Vector of local coordinates
577  Vector<double> s(2);
578 
579  // Vector for coordinates
580  Vector<double> x(2);
581 
582  //Set the value of n_intpt
583  unsigned n_intpt = integral_pt()->nweight();
584 
585  // Tecplot
586  outfile << "ZONE" << std::endl;
587 
588  // Exact solution Vector (here a scalar)
589  Vector<double> exact_soln(1);
590 
591  //Loop over the integration points
592  for(unsigned ipt=0;ipt<n_intpt;ipt++)
593  {
594 
595  //Assign values of s
596  for(unsigned i=0;i<2;i++)
597  {
598  s[i] = integral_pt()->knot(ipt,i);
599  }
600 
601  //Get the integral weight
602  double w = integral_pt()->weight(ipt);
603 
604  // Get jacobian of mapping
605  double J=J_eulerian(s);
606 
607  //Premultiply the weights and the Jacobian
608  double W = w*J;
609 
610  /// Calculate the cartesian coordinates of point on meniscus
611  Vector<double> r(3,0.0);
612  position(s,r);
613 
614  /// Calculate the exact position
615  Vector<double> r_exact(3,0.0);
616  exact_position(s,r_exact,exact_soln_pt);
617 
618  //Output x,y,...,error
619  for(unsigned i=0;i<2;i++)
620  {
621  outfile << r[i] << " ";
622  }
623 
624  for(unsigned i=0;i<2;i++)
625  {
626  outfile << r_exact[i] << " ";
627  }
628 
629  outfile << std::endl;
630 
631  // Add to error and norm
632  norm+=0.0;
633  for(unsigned i=0;i<2;i++)
634  {
635  error+=(r[i]-r_exact[i])*(r[i]-r_exact[i])*W;
636  }
637  }
638 
639  }
640 
641 
642 
643 //====================================================================
644 // Force build of templates
645 //====================================================================
646 template class QYoungLaplaceElement<2>;
647 template class QYoungLaplaceElement<3>;
648 template class QYoungLaplaceElement<4>;
649 
650 }
651 
652 
653 
654 
virtual std::string tecplot_zone_string(const unsigned &nplot) const
Return string for tecplot zone header (when plotting nplot points in each "coordinate direction") ...
Definition: elements.h:2990
virtual void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &shifted_to_interior=false) const
Get cector of local coordinates of plot point i (when plotting nplot points in each "coordinate direc...
Definition: elements.h:2978
virtual double dshape_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsidx) const
Return the geometric shape functions and also first derivatives w.r.t. global coordinates at the ipt-...
Definition: elements.cc:3254
double nodal_position(const unsigned &n, const unsigned &i) const
Return the i-th coordinate at local node n. If the node is hanging, the appropriate interpolation is ...
Definition: elements.h:2227
cstr elem_len * i
Definition: cfortran.h:607
virtual unsigned self_test()
Self-test: Check inversion of element & do self-test for GeneralisedElement. Return 0 if OK...
Definition: elements.cc:4333
unsigned self_test()
Self-test: Return 0 for OK.
virtual double weight(const unsigned &i) const =0
Return weight of i-th integration point.
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Get error against and norm of exact solution.
virtual unsigned nplot_points(const unsigned &nplot) const
Return total number of plot points (when plotting nplot points in each "coordinate direction") ...
Definition: elements.h:3017
void get_spine(const Vector< double > &x, Vector< double > &spine, Vector< Vector< double > > &dspine) const
Get spine vector field: Defaults to standard cartesian representation if no spine base fct pointers h...
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as ...
Definition: elements.h:1723
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
Definition: elements.cc:3881
static void allocate_vector_of_vectors(unsigned n_rows, unsigned n_cols, Vector< Vector< double > > &v)
Helper fct: Allocate storage for a vector of vectors of doubles to v(n_rows,n_cols) and initialise ea...
void output(std::ostream &outfile)
Output with default number of plot points.
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output exact soln at n_plot^2 plot points.
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
Definition: elements.h:1908
void interpolated_zeta(const Vector< double > &s, Vector< double > &zeta) const
Calculate the interpolated value of zeta, the intrinsic coordinate of the element when viewed as a co...
Definition: elements.cc:4564
static void scalar_times_vector(const double &lambda, const Vector< double > &v, Vector< double > &lambda_times_v)
Multiply a vector by a scalar.
static char t char * s
Definition: cfortran.h:572
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
virtual void write_tecplot_zone_footer(std::ostream &outfile, const unsigned &nplot) const
Add tecplot zone "footer" to output stream (when plotting nplot points in each "coordinate direction"...
Definition: elements.h:3003
static void cross_product(const Vector< double > &v1, const Vector< double > &v2, Vector< double > &v_cross)
Cross-product: v_cross= v1 x v2.
static double scalar_product(const Vector< double > &v1, const Vector< double > &v2)
Scalar product between two vectors.
virtual double u(const unsigned &n) const
static void vector_sum(const Vector< double > &v1, const Vector< double > &v2, Vector< double > &vs)
Vectorial sum of two vectors.
double interpolated_u(const Vector< double > &s) const
Return FE representation of function value u(s) at local coordinate s.
bool use_spines() const
Use spines or not? (Based on availability of function pointers to to spine and spine base vector fiel...
double get_kappa() const
Get curvature.
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
virtual int u_local_eqn(const unsigned &n)
Get the local equation number of the (one and only) unknown stored at local node n (returns -1 if val...
static double two_norm(const Vector< double > &v)
2-norm of a vector
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element&#39;s contribution to its residual vector.
void exact_position(const Vector< double > &s, Vector< double > &r, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Get exact position vector to meniscus at local coordinate s.
virtual void get_spine_base(const Vector< double > &x, Vector< double > &spine_base, Vector< Vector< double > > &dspine_base) const
Get spine base vector field: Defaults to standard cartesian representation if no spine base fct point...
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2146
virtual double J_eulerian(const Vector< double > &s) const
Return the Jacobian of mapping from local to global coordinates at local position s...
Definition: elements.cc:4022
void position(const Vector< double > &s, Vector< double > &r) const
Get position vector to meniscus at local coordinate s.