young_laplace_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// Copyright (C) 2006-2022 Matthias Heil and Andrew Hazel
7 // LIC//
8 // LIC// This library is free software; you can redistribute it and/or
9 // LIC// modify it under the terms of the GNU Lesser General Public
10 // LIC// License as published by the Free Software Foundation; either
11 // LIC// version 2.1 of the License, or (at your option) any later version.
12 // LIC//
13 // LIC// This library is distributed in the hope that it will be useful,
14 // LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // LIC// Lesser General Public License for more details.
17 // LIC//
18 // LIC// You should have received a copy of the GNU Lesser General Public
19 // LIC// License along with this library; if not, write to the Free Software
20 // LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 // LIC// 02110-1301 USA.
22 // LIC//
23 // LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 // LIC//
25 // LIC//====================================================================
26 // Header file for YoungLaplace elements
27 #ifndef OOMPH_YOUNGLAPLACE_ELEMENTS_HEADER
28 #define OOMPH_YOUNGLAPLACE_ELEMENTS_HEADER
29 
30 
31 // Config header generated by autoconfig
32 #ifdef HAVE_CONFIG_H
33 #include <oomph-lib-config.h>
34 #endif
35 
36 
37 // OOMPH-LIB headers
38 #include "../generic/nodes.h"
39 #include "../generic/Qelements.h"
40 
41 
42 namespace oomph
43 {
44  //=============================================================
56  //=============================================================
57  class YoungLaplaceEquations : public virtual FiniteElement
58  {
59  public:
61  typedef void (*SpineBaseFctPt)(const Vector<double>& x,
62  Vector<double>& spine_base,
63  Vector<Vector<double>>& dspine_base);
64 
66  typedef void (*SpineFctPt)(const Vector<double>& x,
67  Vector<double>& spine,
68  Vector<Vector<double>>& dspine);
69 
73  {
74  }
75 
78 
80  void operator=(const YoungLaplaceEquations&) = delete;
81 
84  virtual inline double u(const unsigned& n) const
85  {
86  return nodal_value(n, 0);
87  }
88 
90  void output(std::ostream& outfile)
91  {
92  unsigned n_plot = 5;
93  output(outfile, n_plot);
94  }
95 
98  void output(std::ostream& outfile, const unsigned& n_plot);
99 
100 
102  void output_fct(std::ostream& outfile,
103  const unsigned& n_plot,
105 
106 
110  virtual void output_fct(
111  std::ostream& outfile,
112  const unsigned& n_plot,
113  const double& time,
115  {
116  throw OomphLibError("These equations are steady => no time dependence",
119  }
120 
121 
123  void compute_error(std::ostream& outfile,
125  double& error,
126  double& norm);
127 
129  void compute_error(std::ostream& outfile,
131  const double& time,
132  double& error,
133  double& norm)
134  {
135  throw OomphLibError("These equations are steady => no time dependence",
138  }
139 
140 
145  {
146  return Kappa_pt;
147  }
148 
151  bool use_spines() const
152  {
153  return (Spine_fct_pt != 0);
154  }
155 
159  {
160  return Spine_base_fct_pt;
161  }
162 
163 
167  {
168  return Spine_fct_pt;
169  }
170 
173  {
174 #ifdef PARANOID
175  if (kappa_pt->nvalue() != 1)
176  {
177  throw OomphLibError("kappa must only store a single value!",
180  }
181 #endif
182 
183  // Make a local copy
184  Kappa_pt = kappa_pt;
185 
186  // Add to external data and store index in this storage scheme
188  }
189 
190 
192  double get_kappa() const
193  {
195  if (Kappa_pt == 0)
196  {
197  return 0.0;
198  }
199  else
200  {
201  // Get prescribed kappa value
202  return Kappa_pt->value(0);
203  }
204  }
205 
206 
209  {
210  // Find out how many nodes there are in the element
211  unsigned n_node = nnode();
212 
213  // Set up memory for the shape (same as test functions)
214  Shape psi(n_node);
215  DShape dpsidx(n_node, 2);
216 
217  // Call the derivatives of the shape (same as test functions)
218  dshape_eulerian(s, psi, dpsidx);
219 
220  // Initialise to zero
221  for (unsigned j = 0; j < 2; j++)
222  {
223  flux[j] = 0.0;
224  }
225 
226  // Loop over nodes
227  for (unsigned l = 0; l < n_node; l++)
228  {
229  // Loop over derivative directions
230  for (unsigned j = 0; j < 2; j++)
231  {
232  flux[j] += u(l) * dpsidx(l, j);
233  }
234  }
235  }
236 
237 
241  inline virtual void get_spine_base(
242  const Vector<double>& x,
243  Vector<double>& spine_base,
244  Vector<Vector<double>>& dspine_base) const
245  {
246  // If no spine function has been set, default to vertical spines
247  // emanating from x[0](,x[1])
248  if (Spine_base_fct_pt == 0)
249  {
250  for (unsigned i = 0; i < 3; i++)
251  {
252  spine_base[i] = x[i];
253  for (unsigned j = 0; j < 2; j++)
254  {
255  dspine_base[i][j] = 0.0;
256  }
257  }
258  }
259  else
260  {
261  // Get spine
262  (*Spine_base_fct_pt)(x, spine_base, dspine_base);
263  }
264  }
265 
269  inline void get_spine(const Vector<double>& x,
270  Vector<double>& spine,
271  Vector<Vector<double>>& dspine) const
272  {
273  // If no spine function has been set, default to vertical spines
274  // emanating from x[0](,x[1])
275  if (Spine_fct_pt == 0)
276  {
277  // Initialise all to zero
278  for (unsigned i = 0; i < 3; i++)
279  {
280  spine[i] = 0.0;
281  for (unsigned j = 0; j < 2; j++)
282  {
283  dspine[i][j] = 0.0;
284  }
285  }
286  // Overwrite vertical component
287  spine[2] = 1.0;
288  }
289  else
290  {
291  // Get spine
292  (*Spine_fct_pt)(x, spine, dspine);
293  }
294  }
295 
297  void position(const Vector<double>& s, Vector<double>& r) const;
298 
300  void exact_position(const Vector<double>& s,
301  Vector<double>& r,
303 
306 
307 
309  inline double interpolated_u(const Vector<double>& s) const
310  {
311  // Find number of nodes
312  unsigned n_node = nnode();
313 
314  // Local shape function
315  Shape psi(n_node);
316 
317  // Find values of shape function
318  shape(s, psi);
319 
320  // Initialise value of u
321  double interpolated_u = 0.0;
322 
323  // Loop over the local nodes and sum
324  for (unsigned l = 0; l < n_node; l++)
325  {
326  interpolated_u += u(l) * psi[l];
327  }
328 
329  return (interpolated_u);
330  }
331 
332 
334  unsigned self_test();
335 
336 
339  static void allocate_vector_of_vectors(unsigned n_rows,
340  unsigned n_cols,
342  {
343  v.resize(n_rows);
344  for (unsigned i = 0; i < n_rows; i++)
345  {
346  v[i].resize(n_cols);
347  for (unsigned j = 0; j < n_cols; j++)
348  {
349  v[i][j] = 0.0;
350  }
351  }
352  }
353 
355  static void scalar_times_vector(const double& lambda,
356  const Vector<double>& v,
357  Vector<double>& lambda_times_v)
358  {
359  unsigned n = v.size();
360  for (unsigned i = 0; i < n; i++)
361  {
362  lambda_times_v[i] = lambda * v[i];
363  }
364  }
365 
366 
368  static double two_norm(const Vector<double>& v)
369  {
370  double norm = 0.0;
371  unsigned n = v.size();
372  for (unsigned i = 0; i < n; i++)
373  {
374  norm += v[i] * v[i];
375  }
376  return sqrt(norm);
377  }
378 
379 
381  static double scalar_product(const Vector<double>& v1,
382  const Vector<double>& v2)
383  {
384  double scalar = 0.0;
385  unsigned n = v1.size();
386  for (unsigned i = 0; i < n; i++)
387  {
388  scalar += v1[i] * v2[i];
389  }
390  return scalar;
391  }
392 
394  static void cross_product(const Vector<double>& v1,
395  const Vector<double>& v2,
396  Vector<double>& v_cross)
397  {
398 #ifdef PARANOID
399  if ((v1.size() != v2.size()) || (v1.size() != 3))
400  {
401  throw OomphLibError("Vectors must be of dimension 3 for cross-product!",
404  }
405 #endif
406  v_cross[0] = v1[1] * v2[2] - v1[2] * v2[1];
407  v_cross[1] = v1[2] * v2[0] - v1[0] * v2[2];
408  v_cross[2] = v1[0] * v2[1] - v1[1] * v2[0];
409  }
410 
412  static void vector_sum(const Vector<double>& v1,
413  const Vector<double>& v2,
414  Vector<double>& vs)
415  {
416  unsigned n = v1.size();
417  for (unsigned i = 0; i < n; i++)
418  {
419  vs[i] = v1[i] + v2[i];
420  }
421  }
422 
423  protected:
427  virtual inline int u_local_eqn(const unsigned& n)
428  {
429  return nodal_local_eqn(n, 0);
430  }
431 
433  unsigned Kappa_index;
434 
437 
440 
441  private:
447  };
448 
449 
453 
454 
455  //======================================================================
458  //======================================================================
459  template<unsigned NNODE_1D>
460  class QYoungLaplaceElement : public virtual QElement<2, NNODE_1D>,
461  public virtual YoungLaplaceEquations
462  {
463  private:
466  static const unsigned Initial_Nvalue[];
467 
468  public:
472 
475 
478 
481  inline unsigned required_nvalue(const unsigned& n) const
482  {
483  return Initial_Nvalue[n];
484  }
485 
487  void output(std::ostream& outfile)
488  {
490  }
491 
492 
494  void output(std::ostream& outfile, const unsigned& n_plot)
495  {
496  YoungLaplaceEquations::output(outfile, n_plot);
497  }
498 
499 
501  void output_fct(std::ostream& outfile,
502  const unsigned& n_plot,
504  {
505  YoungLaplaceEquations::output_fct(outfile, n_plot, exact_soln_pt);
506  }
507 
508 
511  void output_fct(std::ostream& outfile,
512  const unsigned& n_plot,
513  const double& time,
515  {
516  YoungLaplaceEquations::output_fct(outfile, n_plot, time, exact_soln_pt);
517  }
518  };
519 
520 
524 
525 
526  //=======================================================================
531  //=======================================================================
532  template<unsigned NNODE_1D>
534  : public virtual QElement<1, NNODE_1D>
535  {
536  public:
539  FaceGeometry() : QElement<1, NNODE_1D>() {}
540  };
541 
542 
546 
547 
548  //========================================================================
554  //========================================================================
556  {
557  public:
561  HeightControlElement(Node* control_node_pt, double* prescribed_height_pt)
563  {
564  // Store pointer to prescribed height value
565  Prescribed_height_pt = prescribed_height_pt;
566 
567  // Store pointer to Node at which the height is controlled
568  Control_node_pt = control_node_pt;
569 
570  // Create curvature Data, add it as internal data, and store
571  // its number with the internal data storage scheme
572  // (i.e. internal_data_pt(Curvature_data_index) will return
573  // the pointer to it...).
575 
576  // Add control_node_pt as external data
577  add_external_data(static_cast<Data*>(control_node_pt));
578  }
579 
583  {
585  }
586 
589  {
590  // Get equation number from generic scheme: The height control
591  // equation is "the equation for the curvature" which is
592  // stored as internal data in the element and has been
593  // numbered as such...
595  }
596 
597 
602  {
603  residuals[Height_ctrl_local_eqn] =
604  Control_node_pt->value(0) - (*Prescribed_height_pt);
605  }
606 
607  private:
610 
613 
617 
620  };
621 
622 
623 } // namespace oomph
624 
625 
626 #endif
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
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
Map< RowVectorXf > v2(M2.data(), M2.size())
M1<< 1, 2, 3, 4, 5, 6, 7, 8, 9;Map< RowVectorXf > v1(M1.data(), M1.size())
Definition: shape.h:278
Definition: nodes.h:86
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
Definition: nodes.h:483
double value(const unsigned &i) const
Definition: nodes.h:293
FaceGeometry()
Definition: young_laplace_elements.h:539
Definition: elements.h:4998
Definition: elements.h:1313
double nodal_value(const unsigned &n, const unsigned &i) const
Definition: elements.h:2593
virtual void shape(const Vector< double > &s, Shape &psi) const =0
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Definition: elements.h:1432
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Definition: elements.h:1759
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Definition: elements.h:1765
double dshape_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsidx) const
Definition: elements.cc:3298
Definition: elements.h:73
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
Definition: elements.h:622
unsigned add_external_data(Data *const &data_pt, const bool &fd=true)
Definition: elements.cc:307
int internal_local_eqn(const unsigned &i, const unsigned &j) const
Definition: elements.h:267
unsigned add_internal_data(Data *const &data_pt, const bool &fd=true)
Definition: elements.cc:62
Definition: young_laplace_elements.h:556
void assign_additional_local_eqn_numbers()
Setup local equation number for the height-control equation.
Definition: young_laplace_elements.h:588
unsigned Curvature_data_index
Definition: young_laplace_elements.h:616
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Definition: young_laplace_elements.h:601
Node * Control_node_pt
Pointer to node at which the height is controlled.
Definition: young_laplace_elements.h:612
double * Prescribed_height_pt
Pointer to value that stores the controlled height.
Definition: young_laplace_elements.h:609
HeightControlElement(Node *control_node_pt, double *prescribed_height_pt)
Definition: young_laplace_elements.h:561
Data *& kappa_pt()
Definition: young_laplace_elements.h:582
unsigned Height_ctrl_local_eqn
Local equation number of the height-control equation.
Definition: young_laplace_elements.h:619
Definition: nodes.h:906
double value(const unsigned &i) const
Definition: nodes.cc:2408
Definition: oomph_definitions.h:222
Definition: Qelements.h:459
Definition: young_laplace_elements.h:462
QYoungLaplaceElement()
Definition: young_laplace_elements.h:471
QYoungLaplaceElement(const QYoungLaplaceElement< NNODE_1D > &dummy)=delete
Broken copy constructor.
void output(std::ostream &outfile, const unsigned &n_plot)
Output function at n_plot^2 plot points.
Definition: young_laplace_elements.h:494
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output function for an exact solutio at n_plot^2 plot points.
Definition: young_laplace_elements.h:501
static const unsigned Initial_Nvalue[]
Definition: young_laplace_elements.h:466
void operator=(const QYoungLaplaceElement< NNODE_1D > &)=delete
Broken assignment operator.
unsigned required_nvalue(const unsigned &n) const
Definition: young_laplace_elements.h:481
void output(std::ostream &outfile)
Output function.
Definition: young_laplace_elements.h:487
void output_fct(std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Definition: young_laplace_elements.h:511
Definition: shape.h:76
Definition: young_laplace_elements.h:58
SpineBaseFctPt & spine_base_fct_pt()
Definition: young_laplace_elements.h:158
static double two_norm(const Vector< double > &v)
2-norm of a vector
Definition: young_laplace_elements.h:368
static void scalar_times_vector(const double &lambda, const Vector< double > &v, Vector< double > &lambda_times_v)
Multiply a vector by a scalar.
Definition: young_laplace_elements.h:355
void(* SpineBaseFctPt)(const Vector< double > &x, Vector< double > &spine_base, Vector< Vector< double >> &dspine_base)
Function pointer to "spine base" function.
Definition: young_laplace_elements.h:61
void set_kappa(Data *kappa_pt)
Set curvature data (and add it to the element's external Data)
Definition: young_laplace_elements.h:172
static double scalar_product(const Vector< double > &v1, const Vector< double > &v2)
Scalar product between two vectors.
Definition: young_laplace_elements.h:381
double interpolated_u(const Vector< double > &s) const
Return FE representation of function value u(s) at local coordinate s.
Definition: young_laplace_elements.h:309
void compute_error(std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
Dummy, time dependent error checker.
Definition: young_laplace_elements.h:129
virtual void output_fct(std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Definition: young_laplace_elements.h:110
unsigned self_test()
Self-test: Return 0 for OK.
Definition: young_laplace_elements.cc:367
static void allocate_vector_of_vectors(unsigned n_rows, unsigned n_cols, Vector< Vector< double >> &v)
Definition: young_laplace_elements.h:339
virtual int u_local_eqn(const unsigned &n)
Definition: young_laplace_elements.h:427
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output exact soln at n_plot^2 plot points.
Definition: young_laplace_elements.cc:489
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Get error against and norm of exact solution.
Definition: young_laplace_elements.cc:542
SpineFctPt & spine_fct_pt()
Definition: young_laplace_elements.h:166
void output(std::ostream &outfile)
Output with default number of plot points.
Definition: young_laplace_elements.h:90
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.
Definition: young_laplace_elements.cc:48
void(* SpineFctPt)(const Vector< double > &x, Vector< double > &spine, Vector< Vector< double >> &dspine)
Function pointer to "spine" function.
Definition: young_laplace_elements.h:66
YoungLaplaceEquations()
Definition: young_laplace_elements.h:72
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector.
Definition: young_laplace_elements.cc:136
virtual void get_spine_base(const Vector< double > &x, Vector< double > &spine_base, Vector< Vector< double >> &dspine_base) const
Definition: young_laplace_elements.h:241
virtual double u(const unsigned &n) const
Definition: young_laplace_elements.h:84
double get_kappa() const
Get curvature.
Definition: young_laplace_elements.h:192
void get_spine(const Vector< double > &x, Vector< double > &spine, Vector< Vector< double >> &dspine) const
Definition: young_laplace_elements.h:269
bool use_spines() const
Definition: young_laplace_elements.h:151
void position(const Vector< double > &s, Vector< double > &r) const
Get position vector to meniscus at local coordinate s.
Definition: young_laplace_elements.cc:93
unsigned Kappa_index
Index of Kappa_pt in the element's storage of external Data.
Definition: young_laplace_elements.h:433
static void cross_product(const Vector< double > &v1, const Vector< double > &v2, Vector< double > &v_cross)
Cross-product: v_cross= v1 x v2.
Definition: young_laplace_elements.h:394
Data * Kappa_pt
Definition: young_laplace_elements.h:446
SpineFctPt Spine_fct_pt
Pointer to spine function:
Definition: young_laplace_elements.h:439
void operator=(const YoungLaplaceEquations &)=delete
Broken assignment operator.
void get_flux(const Vector< double > &s, Vector< double > &flux) const
Get flux: flux[i] = du/dx_i: Mainly used for error estimation.
Definition: young_laplace_elements.h:208
SpineBaseFctPt Spine_base_fct_pt
Pointer to spine base function:
Definition: young_laplace_elements.h:436
Data * kappa_pt()
Definition: young_laplace_elements.h:144
YoungLaplaceEquations(const YoungLaplaceEquations &dummy)=delete
Broken copy constructor.
static void vector_sum(const Vector< double > &v1, const Vector< double > &v2, Vector< double > &vs)
Vectorial sum of two vectors.
Definition: young_laplace_elements.h:412
RealScalar s
Definition: level1_cplx_impl.h:130
void flux(const double &time, const Vector< double > &x, double &flux)
Get flux applied along boundary x=0.
Definition: pretend_melt.cc:59
r
Definition: UniformPSDSelfTest.py:20
int error
Definition: calibrate.py:297
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
list x
Definition: plotDoE.py:28
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2