unstructured_clamped_curved_shell.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 //Driver for a 2D linearised shell problem: circular tube
31 
32 // Generic oomph-lib routines
33 #include "generic.h"
34 
35 // Include the mesh
36 #include "meshes/one_d_mesh.h"
37 #include "meshes/simple_rectangular_tri_mesh.h"
38 #include "meshes/simple_rectangular_quadmesh.h"
39 #include "generic/geom_objects.h"
40 #include "meshes/triangle_mesh.h"
41 
42 using namespace std;
43 
44 using namespace oomph;
45 
46 
47 //////////////////////////////////////////////////////////////////////
48 //////////////////////////////////////////////////////////////////////
49 //////////////////////////////////////////////////////////////////////
50 
51 
52 //Header file for 2d linear shell problem: circular-tube bending
53 #ifndef OOMPH_LINEAR_SHELL_ELEMENTS_HEADER
54 #define OOMPH_LINEAR_SHELL_ELEMENTS_HEADER
55 
56 namespace oomph
57 {
58 //=============================================================
59 /// A class for all subparametric elements that solve the
60 /// linear shell equations.
61 /// This contains the generic maths. Shape functions, geometric
62 /// mapping etc. must get implemented in derived class.
63 //=============================================================
64 template <unsigned DIM, unsigned NNODE_1D>
65 class MyShellEquations : public virtual BellElement<DIM,NNODE_1D>
66 {
67 
68 public:
69 
70  /// \short Function pointer to source function fct(x,f(x)) --
71  /// x is a Vector!
72  typedef void (*SourceFctPt)(const Vector<double>& x, const Vector<double>& unit_n, Vector<double>& f);
73 
74 
75  /// \short Function pointer to gradient of source function fct(x,g(x)) --
76  /// x is a Vector!
77  typedef void (*SourceFctGradientPt)(const Vector<double>& x,
78  Vector<double>& gradient);
79 
80 
81  /// Constructor (must initialise the Source_fct_pt to null)
82  MyShellEquations() : Source_fct_pt(0), Source_fct_gradient_pt(0)
83  {}
84 
85  /// Broken copy constructor
87  {
88  BrokenCopy::broken_copy("MyShellEquations");
89  }
90 
91  /// \short Return the index at which the unknown value
92  /// is stored.
93  /// In derived multi-physics elements, this function should be overloaded
94  /// to reflect the chosen storage scheme. Note that these equations require
95  /// that the unknown is always stored at the same index at each node.
96  virtual inline unsigned u_index_shell() const {return this->required_nvalue(0);}
97 
98  /// Output with default number of plot points
99  void output(std::ostream &outfile)
100  {
101  const unsigned n_plot=5;
102  output(outfile,n_plot);
103  }
104 
105  /// \short Output FE representation of soln: x,y,u or x,y,z,u at
106  /// n_plot^DIM plot points
107  void output(std::ostream &outfile, const unsigned &n_plot);
108 
109  /// C_style output with default number of plot points
110  void output(FILE* file_pt)
111  {
112  const unsigned n_plot=5;
113  output(file_pt,n_plot);
114  }
115 
116  /// \short C-style output FE representation of soln: x,y,u or x,y,z,u at
117  /// n_plot^DIM plot points
118  void output(FILE* file_pt, const unsigned &n_plot);
119 
120  /// Output exact soln: x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot points
121  void output_fct(std::ostream &outfile, const unsigned &n_plot,
122  FiniteElement::SteadyExactSolutionFctPt exact_soln_pt);
123 
124  /// \short Output exact soln: x,y,u_exact or x,y,z,u_exact at
125  /// n_plot^DIM plot points (dummy time-dependent version to
126  /// keep intel compiler happy)
127  virtual void output_fct(std::ostream &outfile, const unsigned &n_plot,
128  const double& time,
129  FiniteElement::UnsteadyExactSolutionFctPt
130  exact_soln_pt)
131  {
132  throw OomphLibError(
133  "There is no time-dependent output_fct() for shell elements ",
134  "MyShellEquations<DIM>::output_fct()",
135  OOMPH_EXCEPTION_LOCATION);
136  }
137 
138 
139  /// Get error against and norm of exact solution
140  void compute_error(std::ostream &outfile,
141  FiniteElement::SteadyExactSolutionFctPt exact_soln_pt,
142  double& error, double& norm);
143 
144 
145  /// Dummy, time dependent error checker
146  void compute_error(std::ostream &outfile,
147  FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt,
148  const double& time, double& error, double& norm)
149  {
150  throw OomphLibError(
151  "There is no time-dependent compute_error() for shell elements",
152  "MyShellEquations<DIM>::compute_error()",
153  OOMPH_EXCEPTION_LOCATION);
154  }
155 
156  /// Access function: Pointer to source function
157  SourceFctPt& source_fct_pt() {return Source_fct_pt;}
158 
159  /// Access function: Pointer to source function. Const version
160  SourceFctPt source_fct_pt() const {return Source_fct_pt;}
161 
162  /// Access function: Pointer to gradient of source function
163  SourceFctGradientPt& source_fct_gradient_pt()
164  {return Source_fct_gradient_pt;}
165 
166  /// Access function: Pointer to gradient source function. Const version
167  SourceFctGradientPt source_fct_gradient_pt() const
168  {return Source_fct_gradient_pt;}
169 
170  /// Access function: Undeformed shell
171  GeomObject*& undeformed_midplane_pt() {return Undeformed_midplane_pt;}
172 
173  /// Get source term at (Eulerian) position x. This function is
174  /// virtual to allow overloading in multi-physics problems where
175  /// the strength of the source function might be determined by
176  /// another system of equations.
177  inline virtual void get_source_function(const unsigned& ipt,
178  const Vector<double>& x,
179  const Vector<double>& unit_n,
180  Vector<double>& source) const
181  {
182  //If no source function has been set, return zero
183  if(Source_fct_pt==0)
184  {
185  for(unsigned i=0;i<(u_index_shell())/2;i++)
186  {
187  source[i] = 0.0;
188  }
189  }
190  else
191  {
192  // Get source strength
193  (*Source_fct_pt)(x,unit_n,source);
194  }
195  }
196 
197  /// Add the element's contribution to its residual vector (wrapper)
198  void fill_in_contribution_to_residuals(Vector<double> &residuals)
199  {
200  //Call the generic residuals function with flag set to 0
201  //using a dummy matrix argument
202  fill_in_generic_residual_contribution_shell(
203  residuals,GeneralisedElement::Dummy_matrix,0);
204  }
205 
206 
207  /// Add the element's contribution to its residual vector and
208  /// element Jacobian matrix (wrapper)
209  //void fill_in_contribution_to_jacobian(Vector<double> &residuals,
210  // DenseMatrix<double> &jacobian)
211  // {
212  //Call the generic routine with the flag set to 1
213  // fill_in_generic_residual_contribution_shell(residuals,jacobian,1);
214  //}
215 
216 
217 
218  /// \short Return FE representation of unknown value u(s)
219  /// at local coordinate s
220  inline Vector<double> interpolated_u_shell(const Vector<double> &s) const
221  {
222  //Find number of nodes
223  const unsigned n_node = this->nnode();
224 
225  // Find number of dimension for eulerian coordinates
226  const unsigned n_dim = Undeformed_midplane_pt->ndim();
227 
228  // Find number of dimension for eulerian coordinates
229  const unsigned n_lagrangian = Undeformed_midplane_pt->nlagrangian();
230 
231  //Find number of position dofs
232  const unsigned n_position_type = this->nnodal_position_type();
233 
234  //Get the index at which the unknown is stored
235  const unsigned u_nodal_index = u_index_shell();
236 
237  //Local shape function
238  Shape psi1(3,n_position_type),psi(n_node);
239  DShape dpsidxi1(3,n_position_type,DIM);
240  DShape d2psidxi1(3,n_position_type,3);
241 
242  Vector<double> interpolated_xi(DIM,0.0);
243 
244  //Initialise value of u
245  Vector<double> interpolated_u(u_nodal_index,0.0);
246 
247  //Get values of c0-shape function
248  this->basis_c0(s,psi);
249 
250  //Interpolated in tangential direction
251  for(unsigned l=0;l<n_node;l++)
252  {
253  interpolated_u[0] += this->nodal_value(l,0)*psi[l];
254  interpolated_u[1] += this->nodal_value(l,1)*psi[l];
255  }
256 
257  //Get values of c1-shape function
258  this->d2basis_local(s,psi1,dpsidxi1,d2psidxi1);
259 
260  //Interpolated in normal direction
261  for(unsigned l=0;l<3;l++)
262  {
263  for(unsigned k=0;k<n_position_type;k++)
264  {
265  interpolated_u[2] += this->nodal_value(l,2+k)*psi1(l,k);
266  interpolated_u[3] += this->nodal_value(l,2+k)*dpsidxi1(l,k,0);
267  interpolated_u[4] += this->nodal_value(l,2+k)*dpsidxi1(l,k,1);
268  interpolated_u[5] += this->nodal_value(l,2+k)*d2psidxi1(l,k,0);
269  interpolated_u[6] += this->nodal_value(l,2+k)*d2psidxi1(l,k,1);
270  interpolated_u[7] += this->nodal_value(l,2+k)*d2psidxi1(l,k,2);
271  }
272  } // End of varible loop
273 
274 
275  // setup position vector and derivatives of undeformed configuration
276  Vector<double> r(n_dim);
277  DenseMatrix<double> a(n_lagrangian,n_dim);
278  RankThreeTensor<double> dadxi(n_lagrangian,n_lagrangian,n_dim);
279 
280  this->my_interpolated_x(s,interpolated_xi) ;
281 
282  // get the undeformed geometry
283  Undeformed_midplane_pt->d2position(interpolated_xi,r,a,dadxi);
284 
285  // calculate the covariant metric tensors
286  double tensor_a[2][2];
287 
288  for(unsigned i=0;i<2;i++)
289  {
290  for(unsigned j=0;j<2;j++)
291  {
292  /// initialise tensors to zero
293  tensor_a[i][j]=0.0;
294  for(unsigned k=0;k<n_dim;k++)
295  {
296  tensor_a[i][j] += a(i,k)*a(j,k);
297  }
298  }
299  }
300 
301  // calculate the contravariant metric tensor
302  //Calculate determinant
303  double adet = tensor_a[0][0]*tensor_a[1][1] - tensor_a[0][1]*tensor_a[1][0];
304 
305  // calculate the unit normal vectors
306  Vector<double> unit_n(n_dim);
307  unit_n[0] = 1.0/sqrt(adet)*(a(0,1)*a(1,2) - a(0,2)*a(1,1));
308  unit_n[1] = 1.0/sqrt(adet)*(a(0,2)*a(1,0) - a(0,0)*a(1,2));
309  unit_n[2] = 1.0/sqrt(adet)*(a(0,0)*a(1,1) - a(0,1)*a(1,0));
310 
311  // calculate the non-unit tangential vectors
312  DenseMatrix<double> t(n_lagrangian,n_dim);
313  for(unsigned i=0;i<n_lagrangian;i++)
314  {
315  for(unsigned j=0;j<n_dim;j++)
316  {
317  t(i,j) = a(i,j);
318  }
319  }
320 
321  /// compute displacement u in cartesian coordinate
322  /// displacement component in y direction is identical with normal dirention
323  double x_dir;
324  double y_dir;
325  double z_dir;
326 
327  x_dir = interpolated_u[0]*t(0,0) + interpolated_u[1]*t(1,0) + interpolated_u[2]*unit_n[0];
328  y_dir = interpolated_u[0]*t(0,1) + interpolated_u[1]*t(1,1) + interpolated_u[2]*unit_n[1];
329  z_dir = interpolated_u[0]*t(0,2) + interpolated_u[1]*t(1,2) + interpolated_u[2]*unit_n[2];
330 
331  interpolated_u[0] = x_dir;
332  interpolated_u[1] = y_dir;
333  interpolated_u[2] = z_dir;
334 
335  return(interpolated_u);
336  }
337 
338  /// \short Self-test: Return 0 for OK
339  unsigned self_test();
340 
341 
342 protected:
343 
344  /// \short Shape/test functions and derivs w.r.t. to global coords at
345  /// local coord. s; return Jacobian of mapping
346  virtual double d2shape_and_d2test_eulerian_shell(const Vector<double> &s,
347  Shape &psi,
348  DShape &dpsidx, DShape &d2psidx, Shape &test,
349  DShape &dtestdx, DShape &d2testdx) const=0;
350  virtual double dshape_and_dtest_eulerian_shell(const Vector<double> &s,
351  Shape &psi,
352  DShape &dpsidx, Shape &test,
353  DShape &dtestdx) const=0;
354 
355  /// \short Shape/test functions and derivs w.r.t. to global coords at
356  /// integration point ipt; return Jacobian of mapping
357  virtual double d2shape_and_d2test_eulerian_at_knot_shell(const unsigned &ipt,
358  Shape &psi,
359  DShape &dpsidx,
360  DShape &d2psidx,
361  Shape &test,
362  DShape &dtestdx,
363  DShape &d2testdx)
364  const=0;
365 
366  virtual double dshape_and_dtest_eulerian_at_knot_shell(const unsigned &ipt,
367  Shape &psi,
368  DShape &dpsidx,
369  Shape &test,
370  DShape &dtestdx)
371  const=0;
372 
373  /// \short Compute element residual Vector only (if flag=and/or element
374  /// Jacobian matrix
375  virtual void fill_in_generic_residual_contribution_shell(
376  Vector<double> &residuals, DenseMatrix<double> &jacobian,
377  const unsigned& flag);
378 
379  /// Pointer to source function:
380  SourceFctPt Source_fct_pt;
381 
382  /// Pointer to gradient of source function
383  SourceFctGradientPt Source_fct_gradient_pt;
384 
385  /// Pointer to undeformed beam:
387 
388  /// Pointer to axial prestress
389  double* Sigma0_pt;
390 
391  /// Pointer to wall thickness
392  double* H_pt;
393 
394  /// Pointer to Timescale ratio
395  double* Lambda_sq_pt;
396 };
397 
398 ///////////////////////////////////////////////////////////////////////////
399 ///////////////////////////////////////////////////////////////////////////
400 ///////////////////////////////////////////////////////////////////////////
401 
402 
403 //======================================================================
404 /// BellShellElement elements are with subparametric interpolation for the function.
405 //======================================================================
406 template <unsigned DIM, unsigned NNODE_1D>
407 class BellShellElement : public virtual MyShellEquations<DIM,NNODE_1D>
408 {
409 
410 private:
411 
412  /// \short Static int that holds the number of variables at
413  /// nodes: always the same
414  static const unsigned Initial_Nvalue;
415 
416  public:
417 
418 
419  ///\short Constructor: Call constructors for BellElement and
420  /// Shell equations
421  BellShellElement() : MyShellEquations<DIM,NNODE_1D>()
422  {}
423 
424  /// Broken copy constructor
426  {
427  BrokenCopy::broken_copy("BellShellElement");
428  }
429 
430 
431  /// \short Required # of `values' (pinned or dofs)
432  /// at node n
433  inline unsigned required_nvalue(const unsigned &n) const
434  {return Initial_Nvalue;}
435 
436  /// \short Output function:
437  /// x,y,u or x,y,z,u
438  void output(std::ostream &outfile)
440 
441 
442  /// \short Output function:
443  /// x,y,u or x,y,z,u at n_plot^DIM plot points
444  void output(std::ostream &outfile, const unsigned &n_plot)
445  {MyShellEquations<DIM,NNODE_1D>::output(outfile,n_plot);}
446 
447 
448  /// \short C-style output function:
449  /// x,y,u or x,y,z,u
450  void output(FILE* file_pt)
452 
453 
454  /// \short C-style output function:
455  /// x,y,u or x,y,z,u at n_plot^DIM plot points
456  void output(FILE* file_pt, const unsigned &n_plot)
457  {MyShellEquations<DIM,NNODE_1D>::output(file_pt,n_plot);}
458 
459 
460  /// \short Output function for an exact solution:
461  /// x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot points
462  void output_fct(std::ostream &outfile, const unsigned &n_plot,
463  FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
464  {MyShellEquations<DIM,NNODE_1D>::output_fct(outfile,n_plot,exact_soln_pt);}
465 
466 
467 
468  /// \short Output function for a time-dependent exact solution.
469  /// x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot points
470  /// (Calls the steady version)
471  void output_fct(std::ostream &outfile, const unsigned &n_plot,
472  const double& time,
473  FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
474  {MyShellEquations<DIM,NNODE_1D>::output_fct(outfile,n_plot,time,exact_soln_pt);}
475 
476 
477 protected:
478 
479 /// Shape, test functions & derivs. w.r.t. to global coords. Return Jacobian.
480  inline double d2shape_and_d2test_eulerian_shell(
481  const Vector<double> &s, Shape &psi, DShape &dpsidx, DShape &d2psidx,
482  Shape &test, DShape &dtestdx, DShape &d2testdx) const;
483 
484  inline double dshape_and_dtest_eulerian_shell(
485  const Vector<double> &s, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const;
486 
487 
488  /// \short Shape, test functions & derivs. w.r.t. to global coords. at
489  /// integration point ipt. Return Jacobian.
490  inline double d2shape_and_d2test_eulerian_at_knot_shell(const unsigned& ipt,
491  Shape &psi,
492  DShape &dpsidx,
493  DShape &d2psidx,
494  Shape &test,
495  DShape &dtestdx,
496  DShape &d2testdx)
497  const;
498 
499  inline double dshape_and_dtest_eulerian_at_knot_shell(const unsigned &ipt,
500  Shape &psi,
501  DShape &dpsidx,
502  Shape &test,
503  DShape &dtestdx)
504  const;
505 
506 };
507 
508 
509 ////////////////////////////////////////////////////////////////////
510 ////////////////////////////////////////////////////////////////////
511 ////////////////////////////////////////////////////////////////////
512 
513 
514 //=======================================================================
515 /// Face geometry for the BellShellElement elements: The spatial
516 /// dimension of the face elements is one lower than that of the
517 /// bulk element but they have the same number of points
518 /// along their 1D edges.
519 //=======================================================================
520 template<unsigned DIM, unsigned NNODE_1D>
521 class FaceGeometry<BellShellElement<DIM,NNODE_1D> >:
522  public virtual TElement<DIM-1,NNODE_1D>
523 {
524 
525  public:
526 
527  /// \short Constructor: Call the constructor for the
528  /// appropriate lower-dimensional TElement
529  FaceGeometry() : TElement<DIM-1,NNODE_1D>() {}
530 
531 };
532 
533 
534 //Inline functions:
535 
536 
537 //======================================================================
538 /// Define the shape functions and test functions and derivatives
539 /// w.r.t. global coordinates and return Jacobian of mapping.
540 ///
541 /// Galerkin: Test functions = shape functions
542 //======================================================================
543 template<unsigned DIM, unsigned NNODE_1D>
545  const Vector<double> &s,
546  Shape &psi,
547  DShape &dpsidx,
548  Shape &test,
549  DShape &dtestdx) const
550 {
551  const double J = this->dshape_eulerian(s,psi,dpsidx);
552  test = psi;
553  dtestdx = dpsidx;
554  return J;
555 }
556 
557 template<unsigned DIM, unsigned NNODE_1D>
559  const Vector<double> &s,
560  Shape &psi,
561  DShape &dpsidx,
562  DShape &d2psidx,
563  Shape &test,
564  DShape &dtestdx,
565  DShape &d2testdx) const
566 {
567  //Call the geometrical shape functions and derivatives
568  const double J = this->d2shape_eulerian(s,psi,dpsidx,d2psidx);
569 
570  //Set the test functions equal to the shape functions
571  test = psi;
572  dtestdx= dpsidx;
573  d2testdx = d2psidx;
574  //Return the jacobian
575  return J;
576 }
577 
578 
579 
580 
581 //======================================================================
582 /// Define the shape functions and test functions and derivatives
583 /// w.r.t. global coordinates and return Jacobian of mapping.
584 ///
585 /// Galerkin: Test functions = shape functions
586 //======================================================================
587 template<unsigned DIM, unsigned NNODE_1D>
590  const unsigned &ipt,
591  Shape &psi,
592  DShape &dpsidx,
593  Shape &test,
594  DShape &dtestdx) const
595 {
596  const double J = this->dshape_and_dtest_eulerian_at_knot(ipt,psi,dpsidx,test,dtestdx);
597 
598  return J;
599 }
600 
601 template<unsigned DIM, unsigned NNODE_1D>
604  const unsigned &ipt,
605  Shape &psi,
606  DShape &dpsidx,
607  DShape &d2psidx,
608  Shape &test,
609  DShape &dtestdx,
610  DShape &d2testdx) const
611 {
612  //Call the geometrical shape functions and derivatives
613  const double J = this->d2shape_and_d2test_eulerian_at_knot(ipt,psi,dpsidx,d2psidx,test,dtestdx,d2testdx);
614 
615  //Return the jacobian
616  return J;
617 }
618 
619 ////////////////////////////////////////////////////////////////////////
620 ////////////////////////////////////////////////////////////////////////
621 ////////////////////////////////////////////////////////////////////////
622 
623 
624 }
625 
626 #endif
627 
628 
629 
630 
631 namespace oomph
632 {
633 //======================================================================
634 /// Set the data for the number of Variables at each node
635 //======================================================================
636  template<unsigned DIM, unsigned NNODE_1D>
638 
639 //======================================================================
640 template <unsigned DIM, unsigned NNODE_1D>
643  DenseMatrix<double> &jacobian,
644  const unsigned& flag)
645 {
646  //Find out how many nodes there are
647  const unsigned n_node = this->nnode();
648 
649  //Find out how many nodes positional dofs there are
650  unsigned n_position_type = this->nnodal_position_type();
651 
652  //Set the dimension of the global coordinates
653  unsigned n_dim = Undeformed_midplane_pt->ndim();
654 
655  //Set the number of lagrangian coordinates
656  unsigned n_lagrangian = Undeformed_midplane_pt->nlagrangian();
657 
658  //Set up memory for the shape and test functions
659  Shape psi1(3,n_position_type), test1(3,n_position_type), test(n_node), psi(n_node);
660  DShape dpsidxi1(3,n_position_type,DIM), dtestdxi1(3,n_position_type,DIM), dtestdxi(n_node,DIM), dpsidxi(n_node,DIM);
661  DShape d2psidxi1(3,n_position_type,3), d2testdxi1(3,n_position_type,3), d2testdxi(n_node,3), d2psidxi(n_node,3);
662 
663  //Set the value of n_intpt
664  const unsigned n_intpt = this->integral_pt()->nweight();
665 
666  //Integers to store the local equation and unknown numbers
667  int local_eqn=0;//, local_unknown=0;
668 
669  //Loop over the integration points
670  for(unsigned ipt=0;ipt<n_intpt;ipt++)
671  {
672  //Get the integral weight
673  double w = this->integral_pt()->weight(ipt);
674 
675 
676  //Call the derivatives of the c0-shape and test functions for tangential direcion
677  double J = dshape_and_dtest_eulerian_at_knot_shell(ipt,psi,dpsidxi,test,dtestdxi);
678 
679  //Call the derivatives of the c1-shape and test functions for normal direction
680  double J1 = d2shape_and_d2test_eulerian_at_knot_shell(ipt,psi1,dpsidxi1,d2psidxi1,test,dtestdxi,d2testdxi);
681 
682  //Premultiply the weights and the Jacobian
683  double W1 = w*J1;
684  double W = w*J;
685 
686  double H = 0.01;
687 
688  //Calculate local values of unknown
689  Vector<double> u_value(n_position_type,0.0);
690  Vector<double> interpolated_u(3,0.0);
691  DenseMatrix<double> interpolated_dudxi(3,DIM,0.0);
692  DenseMatrix<double> interpolated_d2udxi(3,3,0.0);
693  Vector<double> interpolated_xi(DIM,0.0);
694 
695  Vector<double> s(2);
696  s[0] = this->integral_pt()->knot(ipt,0);
697  s[1] = this->integral_pt()->knot(ipt,1);
698  this->my_interpolated_x(s,interpolated_xi);
699 
700 
701  //Calculate displacement values and derivatives:
702  //-----------------------------------------
703  //in both tangential directions
704  for(unsigned i=0;i<2;i++)
705  {
706  //Loop over c0-test functions
707  for(unsigned l=0;l<n_node;l++)
708  {
709  //Get the nodal value of the unknown
710  u_value[i] = this->raw_nodal_value(l,i);
711  interpolated_u[i] += u_value[i]*psi[l];
712 
713  // Loop over the first derivative directions
714  for(unsigned j=0;j<n_lagrangian;j++)
715  {
716  interpolated_dudxi(i,j) += u_value[i]*dpsidxi(l,j);
717  }
718 
719  // Loop over the second derivative directions
720  for(unsigned j=0;j<3;j++)
721  {
722  interpolated_d2udxi(i,j) += u_value[i]*d2psidxi(l,j);
723  }
724  }
725  }
726 
727  // in normal direction
728  for(unsigned l=0;l<3;l++)
729  {
730  for(unsigned k=0;k<n_position_type;k++)
731  {
732  //Get the nodal value of the unknown
733  u_value[k] = this->raw_nodal_value(l,2+k);
734  interpolated_u[2] += u_value[k]*psi1(l,k);
735 
736  // Loop over directions
737  for(unsigned j=0;j<n_lagrangian;j++)
738  {
739  interpolated_dudxi(2,j) += u_value[k]*dpsidxi1(l,k,j);
740  }
741 
742  // Loop over the second derivative directions
743  for(unsigned j=0;j<3;j++)
744  {
745  interpolated_d2udxi(2,j) += u_value[k]*d2psidxi1(l,k,j);
746  }
747  }
748  }
749 
750  //-------------------------------------------------------
751  // setup position vector and derivatives of undeformed configuration
752  Vector<double> r(n_dim);
753  DenseMatrix<double> a(n_lagrangian,n_dim), a_tn(n_lagrangian,n_dim);
754  RankThreeTensor<double> dadxi(n_lagrangian,n_lagrangian,n_dim);
755 
756  // get the undeformed geometry
757  Undeformed_midplane_pt->d2position(interpolated_xi,r,a,dadxi);
758 
759  // calculate the covariant metric tensors
760  double tensor_a[2][2], aup[2][2];
761 
762  for(unsigned i=0;i<2;i++)
763  {
764  for(unsigned j=0;j<2;j++)
765  {
766  /// initialise tensors to zero
767  tensor_a[i][j]=0.0;
768  for(unsigned k=0;k<n_dim;k++)
769  {
770  tensor_a[i][j] += a(i,k)*a(j,k);
771  }
772  }
773  }
774 
775  // Calculate determinant
776  double adet = tensor_a[0][0]*tensor_a[1][1] - tensor_a[0][1]*tensor_a[1][0];
777 
778  // calculate entries of the inverse
779  aup[0][0] = tensor_a[1][1]/adet;
780  aup[0][1] = -1*tensor_a[0][1]/adet;
781  aup[1][0] = -1*tensor_a[1][0]/adet;
782  aup[1][1] = tensor_a[0][0]/adet;
783 
784  // calculate the unit normal vectors
785  Vector<double> unit_n(n_dim),n(n_dim);
786  double magnitude_n;
787  n[0] = (a(0,1)*a(1,2) - a(0,2)*a(1,1));
788  n[1] = (a(0,2)*a(1,0) - a(0,0)*a(1,2));
789  n[2] = (a(0,0)*a(1,1) - a(0,1)*a(1,0));
790  magnitude_n = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
791  unit_n[0] = n[0]/magnitude_n;
792  unit_n[1] = n[1]/magnitude_n;
793  unit_n[2] = n[2]/magnitude_n;
794 
795  // allocate all tangential and normal based vectors
796  DenseMatrix<double> t(3,n_dim,0.0),t_tn(3,n_dim,0.0);
797  for(unsigned i=0;i<3;i++)
798  {
799  for(unsigned j=0;j<n_dim;j++)
800  {
801  if(i==2)
802  {
803  t(2,j) = unit_n[j];
804  }
805  else
806  {
807  t(i,j) = a(i,j);
808  }
809  }
810  }
811 
812  // compute for the derivative of the shell normal vector
813  DenseMatrix<double> dndxi(n_lagrangian,n_dim);
814  Vector<double> vec(3);
815  // loop over lagrangian coordinates
816  for(unsigned i=0;i<n_lagrangian;i++)
817  {
818  vec[0] = (dadxi(0,i,1)*t(1,2) - dadxi(0,i,2)*t(1,1)) - (dadxi(1,i,1)*t(0,2) - dadxi(1,i,2)*t(0,1));
819  vec[1] = (dadxi(0,i,2)*t(1,0) - dadxi(0,i,0)*t(1,2)) - (dadxi(1,i,2)*t(0,0) - dadxi(1,i,0)*t(0,2));
820  vec[2] = (dadxi(0,i,0)*t(1,1) - dadxi(0,i,1)*t(1,0)) - (dadxi(1,i,0)*t(0,1) - dadxi(1,i,1)*t(0,0));
821 
822  dndxi(i,0) = vec[0]/magnitude_n ;
823  dndxi(i,1) = vec[1]/magnitude_n ;
824  dndxi(i,2) = vec[2]/magnitude_n ;
825  }
826 
827 
828  // compute for the tangential gradient in tangential and normal directions -> Christoffel symbol
829  // \Gamma^{m}_{i,alpha} = dtdxi(i,alpha,m) = (dadxi(i,alpha,m)t(m,k))
830  RankThreeTensor<double> dtdxi(n_dim,n_lagrangian,n_dim);
831 
832  // Initialize matrix
833  for(unsigned i=0;i<n_dim;i++)
834  {
835  for(unsigned j=0;j<n_lagrangian;j++)
836  {
837  for(unsigned m=0;m<n_dim;m++)
838  {
839  dtdxi(i,j,m) = 0.0;
840 
841  }
842  }
843  }
844 
845  for(unsigned i=0;i<n_lagrangian;i++)
846  {
847  for(unsigned j=0;j<n_lagrangian;j++)
848  {
849  for(unsigned m=0;m<n_dim;m++)
850  {
851  for(unsigned k=0;k<n_dim;k++)
852  {
853  dtdxi(i,j,m) += dadxi(i,j,k)*t(m,k);
854  }
855  }
856  }
857  }
858 
859  for(unsigned i=0;i<n_lagrangian;i++)
860  {
861  for(unsigned m=0;m<n_dim;m++)
862  {
863  for(unsigned k=0;k<n_dim;k++)
864  {
865  dtdxi(2,i,m) += dndxi(i,k)*t(m,k);
866  }
867  }
868  }
869 
870  /// compute the first derivative of a displacement
871  /// in tangential and normal coordinate system
872  DenseMatrix<double> interpolated_dudxi_tn(n_dim,n_lagrangian,0.0);
873 
874  for(unsigned i=0;i<n_lagrangian;i++)
875  {
876  for(unsigned k=0;k<n_dim;k++)
877  {
878  interpolated_dudxi_tn(k,i) = interpolated_dudxi(k,i);
879  for(unsigned j=0;j<n_dim;j++)
880  {
881  interpolated_dudxi_tn(k,i) += interpolated_u[j]*dtdxi(j,i,k);
882  }
883  }
884  }
885 
886  // Compute the linearised strain tensor
887  double gamma[2][2];
888 
889  // Initialise the matrix
890  for(unsigned al=0;al<2;al++)
891  {
892  for(unsigned be=0;be<2;be++)
893  {
894  gamma[al][be] = 0.0;
895  }
896  }
897 
898  for(unsigned al=0;al<2;al++)
899  {
900  for(unsigned be=0;be<2;be++)
901  {
902  gamma[al][be] = ( interpolated_dudxi_tn(al,be) + interpolated_dudxi_tn(be,al))/2.0;
903  }
904  }
905 
906  /// compute the second derivative of a displacement
907  /// in tangential and normal coordinate system
908  DenseMatrix<double> interpolated_d2udxi_tn(n_dim,3,0.0);
909 
910  unsigned al,be;
911  // Loop over derivative
912  for(unsigned c=0;c<3;c++)
913  {
914  if(c==0)
915  {
916  al=0;
917  be=0;
918  }
919  else if(c==1)
920  {
921  al=1;
922  be=1;
923  }
924  else if(c==2)
925  {
926  al=0;
927  be=1;
928  }
929 
930  // Loop over components
931  for(unsigned k=0;k<n_dim;k++)
932  {
933  interpolated_d2udxi_tn(k,c) = interpolated_d2udxi(k,c);
934 
935  for(unsigned j=0;j<n_dim;j++)
936  {
937  interpolated_d2udxi_tn(k,c) += interpolated_dudxi_tn(j,al)*dtdxi(j,be,k);
938  }
939  for(unsigned i=0;i<n_dim;i++)
940  {
941  interpolated_d2udxi_tn(k,c) += interpolated_dudxi(i,be)*dtdxi(i,al,k);
942  }
943  }
944  }
945 
946  // Pre-compute for cross product terms
947  Vector<double> L(n_dim,0.0),temp(n_dim,0.0);
948 
949  L[0] = tensor_a[0][1]*interpolated_dudxi_tn(2,1) - tensor_a[1][1]*interpolated_dudxi_tn(2,0);
950  L[1] = -1.0*tensor_a[0][0]*interpolated_dudxi_tn(2,1) + tensor_a[1][0]*interpolated_dudxi_tn(2,0);
951  L[2] = tensor_a[0][0]*interpolated_dudxi_tn(1,1) - tensor_a[0][1]*interpolated_dudxi_tn(0,1)
952  + tensor_a[1][1]*interpolated_dudxi_tn(0,0) - tensor_a[1][0]*interpolated_dudxi_tn(1,0);
953 
954  // calculate for the linearised bending tensor: kappa
955  double kappa[2][2];
956 
957  // Initialise the bending matrix
958  for(unsigned al=0;al<2;al++)
959  {
960  for(unsigned be=0;be<2;be++)
961  {
962  kappa[al][be] = 0.0;
963  }
964  }
965 
966  unsigned c=0;
967  for(unsigned al=0;al<2;al++)
968  {
969  for(unsigned be=0;be<2;be++)
970  {
971  if(al==0 && be==0) {c=0;}
972  else if(al==1 && be==1) {c=1;}
973  else if(al!=be) {c=2;}
974 
975  for(unsigned k=0;k<n_dim;k++)
976  {
977  kappa[al][be] -= 1.0/adet*(dtdxi(al,be,k)*L[k]);
978  }
979 
980  kappa[al][be] += 1.0/adet/adet*L[2]*dtdxi(al,be,2);
981  kappa[al][be] -= interpolated_d2udxi_tn(2,c);
982  }
983  }
984 
985  // calculate the plane stress stiffness tensor
986  double Et[2][2][2][2];
987  double Nu = 0.3;
988  // some constants
989  double C1 = 0.5*(1.0-Nu);
990  double C2 = Nu;
991 
992  //Loop over first index
993  for(unsigned i=0;i<2;i++)
994  {
995  for(unsigned j=0;j<2;j++)
996  {
997  for(unsigned k=0;k<2;k++)
998  {
999  for(unsigned l=0;l<2;l++)
1000  {
1001  Et[i][j][k][l] = C1*(aup[i][k]*aup[j][l] + aup[i][l]*aup[j][k]) + C2*aup[i][j]*aup[k][l];
1002  }
1003  }
1004  }
1005  }
1006 
1007  //Get source function
1008  Vector<double> source(n_dim),f(n_dim);
1009  get_source_function(ipt,interpolated_xi,unit_n,source);
1010  // decompose in the normal and tangential coordinates
1011  f[0] = source[0]*t(0,0) + source[1]*t(0,1) + source[2]*t(0,2);
1012  f[1] = source[0]*t(1,0) + source[1]*t(1,1) + source[2]*t(1,2);
1013  f[2] = source[0]*t(2,0) + source[1]*t(2,1) + source[2]*t(2,2);
1014  source = f;
1015 
1016  //--------------------------------
1017  // Assemble residuals and Jacobian
1018  //--------------------------------
1019  // Loop over directions
1020  for(unsigned i=0;i<n_dim;i++)
1021  {
1022  // compute for variations
1023  if(i==2)
1024  {
1025  // Loop over the c1-test functions
1026  for(unsigned l=0;l<3;l++)
1027  {
1028  for(unsigned p=0;p<n_position_type;p++)
1029  {
1030  // initialise
1031  DenseMatrix<double> delta_kappa(2,2,0.0);
1032  DenseMatrix<double> delta_gamma(2,2,0.0);
1033  for(unsigned al=0;al<2;al++)
1034  {
1035  for(unsigned be=0;be<2;be++)
1036  {
1037  // compute for variations of the strain tensor
1038  delta_gamma(al,be) = (dtdxi(2,be,al) + dtdxi(2,al,be))/2.0*psi1(l,p);
1039 
1040  // compute for variations of the bending tensor
1041  if((al==0) & (be==0)) {c=0;}
1042  else if((al==1) & (be==1)) {c=1;}
1043  else if(al!=be) {c=2;}
1044 
1045  delta_kappa(al,be) -= d2psidxi1(l,p,c);
1046 
1047  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,0)*( dtdxi(2,1,2)*tensor_a[0][1]*psi1(l,p)-dtdxi(2,0,2)*tensor_a[1][1]*psi1(l,p) );
1048 
1049  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,1)*( -1*dtdxi(2,1,2)*tensor_a[0][0]*psi1(l,p) + dtdxi(2,0,2)*tensor_a[1][0]*psi1(l,p) );
1050 
1051  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,2)*( dtdxi(2,1,1)*tensor_a[0][0]*psi1(l,p)-dtdxi(2,1,0)*tensor_a[0][1]*psi1(l,p)
1052  + dtdxi(2,0,0)*tensor_a[1][1]*psi1(l,p)-dtdxi(2,0,1)*tensor_a[1][0]*psi1(l,p) );
1053 
1054  delta_kappa(al,be) += dtdxi(al,be,2)/adet/adet*( dtdxi(2,1,1)*tensor_a[0][0]*psi1(l,p)-dtdxi(2,1,0)*tensor_a[0][1]*psi1(l,p)
1055  + dtdxi(2,0,0)*tensor_a[1][1]*psi1(l,p)-dtdxi(2,0,1)*tensor_a[1][0]*psi1(l,p) );
1056 
1057  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,0)*( tensor_a[0][1]*dpsidxi1(l,p,1) - tensor_a[1][1]*dpsidxi1(l,p,0));
1058 
1059  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,1)*( -1*tensor_a[0][0]*dpsidxi1(l,p,1) + tensor_a[1][0]*dpsidxi1(l,p,0) );
1060 
1061 
1062  // for the zero derivative
1063  for(unsigned k=0;k<n_dim;k++)
1064  {
1065  delta_kappa(al,be) -= (dtdxi(2,al,k)*dtdxi(k,be,2))*psi1(l,p);
1066  }
1067 
1068  // for the first derivative with respect to \al
1069  delta_kappa(al,be) -= (dtdxi(2,be,2))*dpsidxi1(l,p,al);
1070 
1071  // for the first derivative with respect to \be
1072  delta_kappa(al,be) -= (dtdxi(2,al,2))*dpsidxi1(l,p,be);
1073  }
1074  }// end of compute for variations
1075 
1076  local_eqn = this->nodal_local_eqn(l,2+p);
1077  if(local_eqn >= 0)
1078  {
1079  // add in external forcing
1080  residuals[local_eqn] -= (1.0/H)*source[i]*psi1(l,p)*W1*sqrt(adet);
1081  // Loop over the Greek indicies
1082  for(unsigned al=0;al<2;al++)
1083  {
1084  for(unsigned be=0;be<2;be++)
1085  {
1086  for(unsigned ga=0;ga<2;ga++)
1087  {
1088  for(unsigned de=0;de<2;de++)
1089  {
1090  residuals[local_eqn] += Et[al][be][ga][de]*(gamma[al][be]*delta_gamma(ga,de) + 1.0/12.0*H*H*kappa[al][be]*delta_kappa(ga,de))*W1*sqrt(adet);
1091  }
1092  }
1093  }
1094  } // End of if
1095  } // end of loop over position type
1096  }
1097  } // end of loop over n_shape
1098  }
1099 
1100  else /// find residuals for the first and second tangential directions
1101  {
1102  // Loop over the test functions
1103  for(unsigned l=0;l<n_node;l++)
1104  {
1105  // initialise
1106  DenseMatrix<double> delta_kappa(2,2,0.0);
1107  DenseMatrix<double> delta_gamma(2,2,0.0);
1108 
1109  // compute for variations of the strain tensor
1110  if(i==0)
1111  {
1112  delta_gamma(0,0) = dpsidxi(l,0) + dtdxi(i,0,0)*psi[l];
1113  delta_gamma(0,1) = dpsidxi(l,1)/2.0 + (dtdxi(i,1,0) + dtdxi(i,0,1))/2.0*psi[l];
1114  delta_gamma(1,0) = dpsidxi(l,1)/2.0 + (dtdxi(i,1,0) + dtdxi(i,0,1))/2.0*psi[l];
1115  delta_gamma(1,1) = dtdxi(i,1,1)*psi[l];
1116  }
1117  else if(i==1)
1118  {
1119  delta_gamma(0,0) = dtdxi(i,0,0)*psi[l];
1120  delta_gamma(0,1) = dpsidxi(l,0)/2.0 + (dtdxi(i,1,0) + dtdxi(i,0,1))/2.0*psi[l];
1121  delta_gamma(1,0) = dpsidxi(l,0)/2.0 + (dtdxi(i,1,0) + dtdxi(i,0,1))/2.0*psi[l];
1122  delta_gamma(1,1) = dpsidxi(l,1) + dtdxi(i,1,1)*psi[l];
1123  }
1124 
1125  // compute for variations of the bending tensor
1126  for(unsigned al=0;al<2;al++)
1127  {
1128  for(unsigned be=0;be<2;be++)
1129  {
1130  // compute for variations of the bending tensor
1131  if((al==0) & (be==0)) {c=0;}
1132  else if((al==1) & (be==1)) {c=1;}
1133  else if(al!=be) {c=2;}
1134 
1135  if(i==0)
1136  {
1137  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,0)*( dtdxi(0,1,2)*tensor_a[0][1]*psi[l]-dtdxi(0,0,2)*tensor_a[1][1]*psi[l] );
1138 
1139  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,1)*( -1*dtdxi(0,1,2)*tensor_a[0][0]*psi[l] + dtdxi(0,0,2)*tensor_a[1][0]*psi[l] );
1140 
1141  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,2)*( dtdxi(0,1,1)*tensor_a[0][0]*psi[l]-dtdxi(0,1,0)*tensor_a[0][1]*psi[l]
1142  + dtdxi(0,0,0)*tensor_a[1][1]*psi[l]-dtdxi(0,0,1)*tensor_a[1][0]*psi[l] );
1143 
1144  delta_kappa(al,be) += dtdxi(al,be,2)/adet/adet*( dtdxi(0,1,1)*tensor_a[0][0]*psi[l]-dtdxi(0,1,0)*tensor_a[0][1]*psi[l]
1145  + dtdxi(0,0,0)*tensor_a[1][1]*psi[l]-dtdxi(0,0,1)*tensor_a[1][0]*psi[l] );
1146 
1147  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,2)*( -1*tensor_a[0][1]*dpsidxi(l,1) + tensor_a[1][1]*dpsidxi(l,0));
1148 
1149  delta_kappa(al,be) += dtdxi(al,be,2)/adet/adet*( -1*tensor_a[0][1]*dpsidxi(l,1) + tensor_a[1][1]*dpsidxi(l,0) );
1150 
1151  }
1152  else if(i==1)
1153  {
1154  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,0)*( dtdxi(1,1,2)*tensor_a[0][1]*psi[l]-dtdxi(1,0,2)*tensor_a[1][1]*psi[l] );
1155 
1156  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,1)*( -1*dtdxi(1,1,2)*tensor_a[0][0]*psi[l] + dtdxi(1,0,2)*tensor_a[1][0]*psi[l] );
1157 
1158  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,2)*( dtdxi(1,1,1)*tensor_a[0][0]*psi[l]-dtdxi(1,1,0)*tensor_a[0][1]*psi[l]
1159  + dtdxi(1,0,0)*tensor_a[1][1]*psi[l]-dtdxi(1,0,1)*tensor_a[1][0]*psi[l] );
1160 
1161  delta_kappa(al,be) += dtdxi(al,be,2)/adet/adet*( dtdxi(1,1,1)*tensor_a[0][0]*psi[l]-dtdxi(1,1,0)*tensor_a[0][1]*psi[l]
1162  + dtdxi(1,0,0)*tensor_a[1][1]*psi[l]-dtdxi(1,0,1)*tensor_a[1][0]*psi[l] );
1163 
1164  delta_kappa(al,be) += -1.0/adet*dtdxi(al,be,2)*( tensor_a[0][0]*dpsidxi(l,1) - tensor_a[1][0]*dpsidxi(l,0));
1165 
1166  delta_kappa(al,be) += dtdxi(al,be,2)/adet/adet*( tensor_a[0][0]*dpsidxi(l,1) - tensor_a[1][0]*dpsidxi(l,0) );
1167 
1168  }
1169 
1170  // for the zero derivative
1171  for(unsigned k=0;k<n_dim;k++)
1172  {
1173  delta_kappa(al,be) -= (dtdxi(i,al,k)*dtdxi(k,be,2))*psi[l];
1174  }
1175 
1176  // for the first derivative with respect to \al
1177  delta_kappa(al,be) -= (dtdxi(i,be,2))*dpsidxi(l,al);
1178 
1179  // for the first derivative with respect to \be
1180  delta_kappa(al,be) -= (dtdxi(i,al,2))*dpsidxi(l,be);
1181  }
1182  } // end of compute for variations
1183 
1184  //Get the local equation
1185  local_eqn = this->nodal_local_eqn(l,i);
1186 
1187  if(local_eqn >= 0)
1188  {
1189  // add in external forcing
1190  residuals[local_eqn] -= (1.0/H)*source[i]*psi[l]*W*sqrt(adet);
1191  // Loop over the Greek indicies
1192  for(unsigned al=0;al<2;al++)
1193  {
1194 
1195  for(unsigned be=0;be<2;be++)
1196  {
1197  for(unsigned ga=0;ga<2;ga++)
1198  {
1199  for(unsigned de=0;de<2;de++)
1200  {
1201  residuals[local_eqn] += Et[al][be][ga][de]*(gamma[al][be]*delta_gamma(ga,de) + 1.0/12.0*H*H*kappa[al][be]*delta_kappa(ga,de))*W1*sqrt(adet);
1202  }
1203  }
1204  }
1205  }
1206  } // End of if
1207  }
1208  }// end of else if (of direction)
1209  }
1210  } // End of loop over integration points
1211 }
1212 
1213 //======================================================================
1214 /// Self-test: Return 0 for OK
1215 //======================================================================
1216 template <unsigned DIM, unsigned NNODE_1D>
1218 {
1219 
1220  bool passed=true;
1221 
1222  // Check lower-level stuff
1223  if (FiniteElement::self_test()!=0)
1224  {
1225  passed=false;
1226  }
1227 
1228  // Return verdict
1229  if (passed)
1230  {
1231  return 0;
1232  }
1233  else
1234  {
1235  return 1;
1236  }
1237 
1238 }
1239 
1240 
1241 
1242 //======================================================================
1243 /// Output function:
1244 ///
1245 /// x,y,u or x,y,z,u
1246 ///
1247 /// nplot points in each coordinate direction
1248 //======================================================================
1249 template <unsigned DIM, unsigned NNODE_1D>
1250 void MyShellEquations<DIM,NNODE_1D>::output(std::ostream &outfile,
1251  const unsigned &nplot)
1252 {
1253 
1254  //Vector of local coordinates
1255  Vector<double> s(DIM),x(DIM);
1256 
1257  // Tecplot header info
1258  //outfile << tecplot_zone_string(nplot);
1259 
1260  // Loop over plot points
1261  Vector<double> u(this->required_nvalue(0),0.0);
1262  unsigned num_plot_points=this->nplot_points(nplot);
1263  Vector<double> r(3);
1264  Vector<double> interpolated_xi(DIM,0.0);
1265 
1266  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
1267  {
1268 
1269  // Get local coordinates of plot point
1270  this->get_s_plot(iplot,nplot,s);
1271  u = interpolated_u_shell(s);
1272  // Get x position as Vector
1273  this->my_interpolated_x(s,x);
1274 
1275  for(unsigned i=0;i<DIM;i++)
1276  {
1277  outfile << x[i] << " ";
1278  }
1279 
1280  // Loop for variables
1281  for(unsigned j=0;j<this->required_nvalue(0);j++)
1282  {
1283  outfile << u[j] << " " ;
1284  }
1285 
1286  outfile << std::endl;
1287  }
1288 
1289  // Write tecplot footer (e.g. FE connectivity lists)
1290  //write_tecplot_zone_footer(outfile,nplot);
1291 
1292 }
1293 
1294 
1295 //======================================================================
1296 /// C-style output function:
1297 ///
1298 /// x,y,u or x,y,z,u
1299 ///
1300 /// nplot points in each coordinate direction
1301 //======================================================================
1302 template <unsigned DIM, unsigned NNODE_1D>
1304  const unsigned &nplot)
1305 {
1306  //Vector of local coordinates
1307  Vector<double> s(DIM);
1308 
1309  // Tecplot header info
1310  fprintf(file_pt,"%s",this->tecplot_zone_string(nplot).c_str());
1311 
1312  // Loop over plot points
1313  Vector<double> u(this->required_nvalue(0),0.0);
1314  unsigned num_plot_points=this->nplot_points(nplot);
1315  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
1316  {
1317  // Get local coordinates of plot point
1318  this->get_s_plot(iplot,nplot,s);
1319 
1320  for(unsigned i=0;i<DIM;i++)
1321  {
1322  fprintf(file_pt,"%g ",this->interpolated_x(s,i));
1323  }
1324  u = interpolated_u_shell(s);
1325  fprintf(file_pt,"%g \n",u[0]);//interpolated_u_poisson(s));
1326  }
1327 
1328  // Write tecplot footer (e.g. FE connectivity lists)
1329  //write_tecplot_zone_footer(file_pt,nplot);
1330 }
1331 
1332 
1333 
1334 //======================================================================
1335  /// Output exact solution
1336  ///
1337  /// Solution is provided via function pointer.
1338  /// Plot at a given number of plot points.
1339  ///
1340  /// x,y,u_exact or x,y,z,u_exact
1341 //======================================================================
1342 template <unsigned DIM, unsigned NNODE_1D>
1344  const unsigned &nplot,
1345  FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
1346 {
1347  //Vector of local coordinates
1348  Vector<double> s(DIM);
1349 
1350  // Vector for coordintes
1351  Vector<double> x(DIM);
1352 
1353  // Tecplot header info
1354  outfile << this->tecplot_zone_string(nplot);
1355 
1356  // Exact solution Vector (here a scalar)
1357  Vector<double> exact_soln(this->required_nvalue(0));
1358 
1359  // Loop over plot points
1360  unsigned num_plot_points=this->nplot_points(nplot);
1361  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
1362  {
1363 
1364  // Get local coordinates of plot point
1365  this->get_s_plot(iplot,nplot,s);
1366 
1367  // Get x position as Vector
1368  this->my_interpolated_x(s,x);
1369 
1370  // Get exact solution at this point
1371  (*exact_soln_pt)(x,exact_soln);
1372 
1373  //Output x,y,...,u_exact
1374  for(unsigned i=0;i<DIM;i++)
1375  {
1376  outfile << x[i] << " ";
1377  }
1378  // Loop over variables
1379  for(unsigned j=0;j<this->required_nvalue(0);j++)
1380  {
1381  outfile << exact_soln[j] << "\t";
1382  }
1383  outfile << std::endl;
1384  }
1385 
1386  // Write tecplot footer (e.g. FE connectivity lists)
1387  //write_tecplot_zone_footer(outfile,nplot);
1388 }
1389 
1390 
1391 
1392 
1393 //======================================================================
1394  /// Validate against exact solution
1395  ///
1396  /// Solution is provided via function pointer.
1397  /// Plot error at a given number of plot points.
1398  ///
1399 //======================================================================
1400 template <unsigned DIM, unsigned NNODE_1D>
1402  FiniteElement::SteadyExactSolutionFctPt exact_soln_pt,
1403  double& error, double& norm)
1404 {
1405  // Initialise
1406  error=0.0;
1407  norm=0.0;
1408 
1409  //Vector of local coordinates
1410  Vector<double> s(DIM);
1411 
1412  // Vector for coordintes
1413  Vector<double> x(DIM);
1414 
1415  //Set the value of n_intpt
1416  unsigned n_intpt = this->integral_pt()->nweight();
1417 
1418  // Tecplot
1419  //outfile << "ZONE" << std::endl;
1420 
1421  // Exact solution Vector (here a scalar)
1422  Vector<double> exact_soln(this->required_nvalue(0));
1423 
1424  //Loop over the integration points
1425  for(unsigned ipt=0;ipt<n_intpt;ipt++)
1426  {
1427 
1428  //Assign values of s
1429  for(unsigned i=0;i<DIM;i++)
1430  {
1431  s[i] = this->integral_pt()->knot(ipt,i);
1432  }
1433 
1434  //Get the integral weight
1435  double w = this->integral_pt()->weight(ipt);
1436 
1437  // Get jacobian of mapping
1438  double J=this->J_eulerian(s);
1439 
1440  //Premultiply the weights and the Jacobian
1441  double W = w*J;
1442 
1443  // Get x position as Vector
1444  this->my_interpolated_x(s,x);
1445 
1446  // Get FE function value
1447  Vector<double> u_fe(this->required_nvalue(0),0.0);
1448  u_fe =interpolated_u_shell(s);
1449 
1450  // Get exact solution at this point
1451  (*exact_soln_pt)(x,exact_soln);
1452 
1453  //Output x,y,...,error
1454  for(unsigned i=0;i<DIM;i++)
1455  {
1456  outfile << x[i] << " ";
1457  }
1458  for(unsigned ii=0;ii<this->required_nvalue(0);ii++)
1459  {
1460  outfile << exact_soln[ii] << " " << exact_soln[ii]-u_fe[ii] << " ";
1461  }
1462  outfile << std::endl;
1463 
1464  // Loop over variables
1465  double tmp1 = 0.0, tmp2 =0.0;
1466  for(unsigned ii=0;ii<1;ii++)
1467  {
1468  // Add to error and norm
1469  tmp1 = (exact_soln[ii]*exact_soln[ii]*W);
1470  tmp2 = ((exact_soln[ii]-u_fe[ii])*(exact_soln[ii]-u_fe[ii])*W);
1471  norm += tmp1;
1472  error += tmp2;
1473  }
1474  } //End of loop over integration pts
1475 }
1476 
1477 //====================================================================
1478 // Force build of templates
1479 //====================================================================
1480 template class BellShellElement<2,2>;
1481 template class BellShellElement<2,3>;
1482 }
1483 
1484 //////////////////////////////////////////////////////////////////////
1485 //////////////////////////////////////////////////////////////////////
1486 //////////////////////////////////////////////////////////////////////
1487 
1488 //=======================start_of_namespace===========================
1489 /// Namespace for the solution of 2D linear shell equation
1490 //====================================================================
1492 {
1493  /// Pressure load
1494  double P_ext;
1495 
1496  double epsilon = 1.0e-6;
1497 
1498  /// Exact solution as a vector
1499  /// differentiate u with respect to global coordinates
1500  void get_exact_u(const Vector<double>& x, Vector<double>& u)
1501  {
1502  u[0] = 0.0;
1503  u[1] = 0.0;
1504  u[2] = 0.0;
1505  u[3] = 0.0;
1506  u[4] = 0.0;
1507  u[5] = 0.0;
1508  u[6] = 0.0;
1509  u[7] = 0.0;
1510  }
1511 
1512  /// Source function applied in the normal vector
1513  void source_function(const Vector<double>& x, const Vector<double>& unit_n, Vector<double>& source)
1514  {
1515  for(unsigned i=0;i<3;i++)
1516  {
1517  source[i] = 1.0*epsilon*P_ext*unit_n[i];
1518  }
1519  }
1520 } // end of namespace
1521 
1522 //==start_of_problem_class============================================
1523 /// 2D linearised shell problem.
1524 //====================================================================
1525 template<class ELEMENT, unsigned DIM, unsigned NNODE_1D>
1526 class MyLinearisedShellProblem : public Problem
1527 {
1528 
1529 public:
1530 
1531  /// Constructor: Pass number of elements and pointer to source function
1533  const string& node_file_name,
1534  const string& element_file_name,
1535  const string& poly_file_name);
1536 
1537  /// Destructor (empty)
1539  {
1540  delete mesh_pt();
1541  }
1542 
1543  /// Update the problem specs before solve: (Re)set boundary conditions
1544  void actions_before_newton_solve();
1545 
1546  /// Update the problem specs after solve (empty)
1548 
1549  /// \short Doc the solution, pass the number of the case considered,
1550  /// so that output files can be distinguished.
1551  void doc_solution(DocInfo& doc_info);
1552 
1553  void parameter_study();
1554 
1555 private:
1556 
1557  /// Pointer to source function
1559  /// Pointer to geometric object that represents the shell's undeformed shape
1560  GeomObject* Undef_midplane_pt;
1561 
1562 }; // end of problem class
1563 
1564 //=====start_of_constructor===============================================
1565 /// \short Constructor for 2D Shell problem.
1566 /// Discretise the 2D domain with n_element elements of type ELEMENT.
1567 /// Specify function pointer to source function.
1568 //========================================================================
1569 template<class ELEMENT, unsigned DIM, unsigned NNODE_1D>
1572 const string& node_file_name,const string& element_file_name,
1573 const string& poly_file_name) :
1574  Source_fct_pt(source_fct_pt)
1575 {
1576  // Build mesh and store pointer in Problem
1577  Problem::mesh_pt() = new TriangleMesh<ELEMENT>(node_file_name,element_file_name,poly_file_name);
1578 
1579  // set the undeformed shell
1580  Undef_midplane_pt = new EllipticalTube(1.0,1.0);
1581 
1582  unsigned n_node = this->mesh_pt()->nnode();
1583  cout << "\n\nNumber of nodes in the mesh = " << n_node << endl;
1584 
1585  // find number of elements in the mesh
1586  unsigned n_element = mesh_pt()->nelement();
1587  cout << "Number of nelements in the mesh = " << n_element << endl;
1588 
1589  // pinning the middle nodes in each element for normal direction
1590  for(unsigned n=0;n<n_element;n++)
1591  {
1592  // Upcast from GeneralisedElement to the present element
1593  ELEMENT *elem_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(n));
1594 
1595  unsigned nnode = elem_pt->nnode();
1596  for(unsigned i=0;i<nnode;i++)
1597  {
1598  if((i==0) || (i==1) || (i==2))
1599  {
1600  }
1601  else
1602  {
1603  elem_pt->node_pt(i)->pin(2);
1604  elem_pt->node_pt(i)->pin(3);
1605  elem_pt->node_pt(i)->pin(4);
1606  elem_pt->node_pt(i)->pin(5);
1607  elem_pt->node_pt(i)->pin(6);
1608  elem_pt->node_pt(i)->pin(7);
1609  }
1610  }
1611  } // end of the middle node pinning
1612 
1613  // start_of_boundary_conditions
1614  // Set the boundary conditions for this problem: By default, all nodal
1615  // values are free -- we only need to pin the ones that have
1616  // Dirichlet conditions.
1617  unsigned n_side0 = mesh_pt()->nboundary_node(0);
1618  unsigned n_side1 = mesh_pt()->nboundary_node(1);
1619  unsigned n_side2 = mesh_pt()->nboundary_node(2);
1620  unsigned n_side3 = mesh_pt()->nboundary_node(3);
1621 
1622  //------- CIRCULAR TUBE BENDING PROBLEM -----------
1623  // Pin the nodal values at nodes on mesh
1624  // boundary 0 (= the lower domain boundary at y=0)
1625  /// loop over the nodes on the boundary
1626  for(unsigned i=0;i<n_side0;i++)
1627  {
1628  //mesh_pt()->boundary_node_pt(0,i)->pin(0);
1629  mesh_pt()->boundary_node_pt(0,i)->pin(1);
1630  //mesh_pt()->boundary_node_pt(0,i)->pin(2);
1631  //mesh_pt()->boundary_node_pt(0,i)->pin(3);
1632  mesh_pt()->boundary_node_pt(0,i)->pin(4);
1633  mesh_pt()->boundary_node_pt(0,i)->pin(5);
1634  mesh_pt()->boundary_node_pt(0,i)->pin(6);
1635  mesh_pt()->boundary_node_pt(0,i)->pin(7);
1636  }
1637 
1638  // boundary 1 (= the right domain boundary at x=1)
1639  for(unsigned i=0;i<n_side1;i++)
1640  {
1641  mesh_pt()->boundary_node_pt(1,i)->pin(0);
1642  mesh_pt()->boundary_node_pt(1,i)->pin(1);
1643  mesh_pt()->boundary_node_pt(1,i)->pin(2);
1644  mesh_pt()->boundary_node_pt(1,i)->pin(3);
1645  mesh_pt()->boundary_node_pt(1,i)->pin(4);
1646  mesh_pt()->boundary_node_pt(1,i)->pin(5);
1647  mesh_pt()->boundary_node_pt(1,i)->pin(6);
1648  mesh_pt()->boundary_node_pt(1,i)->pin(7);
1649  }
1650 
1651  // boundary 2 (= the right domain boundary at y=1)
1652  for(unsigned i=0;i<n_side2;i++)
1653  {
1654  //mesh_pt()->boundary_node_pt(2,i)->pin(0);
1655  mesh_pt()->boundary_node_pt(2,i)->pin(1);
1656  //mesh_pt()->boundary_node_pt(2,i)->pin(2);
1657  //mesh_pt()->boundary_node_pt(2,i)->pin(3);
1658  mesh_pt()->boundary_node_pt(2,i)->pin(4);
1659  mesh_pt()->boundary_node_pt(2,i)->pin(5);
1660  mesh_pt()->boundary_node_pt(2,i)->pin(6);
1661  mesh_pt()->boundary_node_pt(2,i)->pin(7);
1662  }
1663 
1664  // boundary 3 (= the right domain boundary at x=0)
1665  for(unsigned i=0;i<n_side3;i++)
1666  {
1667  mesh_pt()->boundary_node_pt(3,i)->pin(0);
1668  mesh_pt()->boundary_node_pt(3,i)->pin(1);
1669  mesh_pt()->boundary_node_pt(3,i)->pin(2);
1670  mesh_pt()->boundary_node_pt(3,i)->pin(3);
1671  mesh_pt()->boundary_node_pt(3,i)->pin(4);
1672  mesh_pt()->boundary_node_pt(3,i)->pin(5);
1673  mesh_pt()->boundary_node_pt(3,i)->pin(6);
1674  mesh_pt()->boundary_node_pt(3,i)->pin(7);
1675  } // end of boundary conditions
1676 
1677  // Loop over elements and set pointers to Physical parameters
1678  for(unsigned i=0;i<n_element;i++)
1679  {
1680  // Upcast from GeneralisedElement to the present element
1681  ELEMENT *elem_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(i));
1682 
1683  //Set the source function pointer and all physical variables
1684  elem_pt->source_fct_pt() = Source_fct_pt;
1685 
1686  //Set the pointer to the undeformed mid-plane geometry
1687  elem_pt->undeformed_midplane_pt() = Undef_midplane_pt;
1688  } // end of loop over elements
1689 
1690  // Setup equation numbering scheme
1691  assign_eqn_numbers();
1692 
1693 } // end of constructor
1694 
1695 //===start_of_actions_before_newton_solve========================================
1696 /// \short Update the problem specs before solve: (Re)set boundary values
1697 /// from the exact solution.
1698 //========================================================================
1699 template<class ELEMENT, unsigned DIM, unsigned NNODE_1D>
1701 {
1702  // Assign boundary values for this problem by reading them out
1703  // from the exact solution.
1704  for(unsigned n=0;n<mesh_pt()->nboundary();n++)
1705  {
1706  // find number of nodes in each boundary
1707  unsigned n_side = mesh_pt()->nboundary_node(n);
1708  /// loop over the nodes on the boundary
1709  for(unsigned j=0;j<n_side;j++)
1710  {
1711  // Left boundary is every nodes on the left boundary
1712  Node* left_node_pt=mesh_pt()->boundary_node_pt(n,j);
1713 
1714  // Loop for variables u
1715  ELEMENT e;
1716  Vector<double> u((e.required_nvalue(0)));
1717  for(unsigned i=0;i<(e.required_nvalue(0));i++)
1718  {
1719  // Determine the position of the boundary node (the exact solution
1720  // requires the coordinate in a 1D vector!)
1721  Vector<double> x(2);
1722  x[0]=left_node_pt->x(0);
1723  x[1]=left_node_pt->x(1);
1724 
1725  // Boundary value (read in from exact solution)
1727 
1728  // Assign the boundary condition to nodal values
1729  left_node_pt->set_value(i,u[i]);
1730  }
1731  }
1732  }
1733 } // end of actions before solve
1734 
1735 
1736 //===start_of_doc=========================================================
1737 /// Doc the solution in tecplot format. Label files with label.
1738 //========================================================================
1739 template<class ELEMENT, unsigned DIM, unsigned NNODE_1D>
1741 {
1742 
1743  ofstream some_file;
1744  char filename[100];
1745 
1746  // Number of plot points
1747  unsigned npts;
1748  npts=10;
1749 
1750  // Output solution with specified number of plot points per element
1751  sprintf(filename,"%s/soln%i.dat",doc_info.directory().c_str(),
1752  doc_info.number());
1753  some_file.open(filename);
1754  some_file.precision(20);
1755  mesh_pt()->output(some_file,npts);
1756  some_file.close();
1757 
1758 } // end of doc
1759 
1760 //===start_of_parameter_study=============================================
1761 /// Solver loop to perform parameter study
1762 //========================================================================
1763 template<class ELEMENT, unsigned DIM, unsigned NNODE_1D>
1765 {
1766  // over-ride the default maximum value for the residuals
1767  Problem::Max_residuals = 1.0e10;
1768 
1769  unsigned nstep = 3;
1770 
1771  // set the increments in control parameters
1772  double pext_increment = 1.0;
1773  // set initial values for control parameters
1774  Physical_Variables::P_ext = 0.0 - pext_increment;
1775 
1776  // Set up doc info
1777  DocInfo doc_info;
1778  doc_info.set_directory("RESLT_unstructured_curved_shell");
1779 
1780  // Loop over parameter increments
1781  for(unsigned i=0;i<nstep;i++)
1782  {
1783  Physical_Variables::P_ext += pext_increment;
1784 
1785  // solve the system
1786  newton_solve();
1787 
1788  // document solution
1789  doc_info.number() = i;
1790  doc_solution(doc_info);
1791  }
1792 } //end of parameter study
1793 
1794 ////////////////////////////////////////////////////////////////////////
1795 ////////////////////////////////////////////////////////////////////////
1796 ////////////////////////////////////////////////////////////////////////
1797 
1798 
1799 //======start_of_main==================================================
1800 /// Driver for 2D linearised shell problem
1801 //=====================================================================
1802 int main(int argc, char* argv[])
1803 {
1804  // Store command line arguments
1805  CommandLineArgs::setup(argc,argv);
1806 
1807  // Check number of command line arguments: Need exactly two.
1808  if (argc!=4)
1809  {
1810  std::string error_message =
1811  "Wrong number of command line arguments.\n";
1812  error_message +=
1813  "Must specify the following file names \n";
1814  error_message +=
1815  "filename.node then filename.ele then filename.poly\n";
1816 
1817  throw OomphLibError(error_message,
1818  "main()",
1819  OOMPH_EXCEPTION_LOCATION);
1820  }
1821  // Convert arguments to strings that specify th input file names
1822  string node_file_name(argv[1]);
1823  string element_file_name(argv[2]);
1824  string poly_file_name(argv[3]);
1825 
1826  // Set up the problem:
1827  MyLinearisedShellProblem<BellShellElement<2,3>,2,3> //Element type as template parameter
1828  problem(Physical_Variables::source_function,node_file_name,element_file_name,poly_file_name);
1829 
1830 
1831  // Check whether the problem can be solved
1832  cout << "\n\n\nProblem self-test ";
1833  if (problem.self_test()==0)
1834  {
1835  cout << "passed: Problem can be solved." << std::endl;
1836  }
1837  else
1838  {
1839  throw OomphLibError("failed!","main()",OOMPH_EXCEPTION_LOCATION);
1840  }
1841 
1842  // Solve the problem
1843  problem.parameter_study();
1844 } //end of main
1845 
1846 
1847 
1848 
1849 
1850 
1851 
1852 
1853 
1854 
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element&#39;s contribution to its residual vector (wrapper)
void actions_before_newton_solve()
Update the problem specs before solve: (Re)set boundary conditions.
void output(std::ostream &outfile, const unsigned &n_plot)
Output function: x,y,u or x,y,z,u at n_plot^DIM plot points.
static const unsigned Initial_Nvalue
Static int that holds the number of variables at nodes: always the same.
SourceFctPt source_fct_pt() const
Access function: Pointer to source function. Const version.
void actions_after_newton_solve()
Update the problem specs after solve (empty)
Namespace for the solution of 2D linear shell equation.
BellShellElement(const BellShellElement< DIM, NNODE_1D > &dummy)
Broken copy constructor.
BellShellElement elements are with subparametric interpolation for the function.
virtual void get_source_function(const unsigned &ipt, const Vector< double > &x, const Vector< double > &unit_n, Vector< double > &source) const
FaceGeometry()
Constructor: Call the constructor for the appropriate lower-dimensional TElement. ...
void output(std::ostream &outfile)
Output function: x,y,u or x,y,z,u.
double * Lambda_sq_pt
Pointer to Timescale ratio.
MyShellEquations()
Constructor (must initialise the Source_fct_pt to null)
void compute_error(std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
Dummy, time dependent error checker.
void source_function(const Vector< double > &x, const Vector< double > &unit_n, Vector< double > &source)
Source function applied in the normal vector.
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output function for an exact solution: x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot points...
GeomObject * Undeformed_midplane_pt
Pointer to undeformed beam:
Vector< double > interpolated_u_shell(const Vector< double > &s) const
Return FE representation of unknown value u(s) at local coordinate s.
SourceFctGradientPt Source_fct_gradient_pt
Pointer to gradient of source function.
void output(std::ostream &outfile)
Output with default number of plot points.
BellShellElement()
Constructor: Call constructors for BellElement and Shell equations.
virtual void output_fct(std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Output exact soln: x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot points (dummy time-dependent versi...
int main(int argc, char *argv[])
Driver for 2D linearised shell problem.
void parameter_study()
Solver loop to perform parameter study.
void output_fct(std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Output function for a time-dependent exact solution. x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot ...
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function: x,y,u or x,y,z,u at n_plot^DIM plot points.
SourceFctGradientPt & source_fct_gradient_pt()
Access function: Pointer to gradient of source function.
double * Sigma0_pt
Pointer to axial prestress.
SourceFctGradientPt source_fct_gradient_pt() const
Access function: Pointer to gradient source function. Const version.
GeomObject * Undef_midplane_pt
Pointer to geometric object that represents the shell&#39;s undeformed shape.
SourceFctPt & source_fct_pt()
Access function: Pointer to source function.
void output(FILE *file_pt)
C_style output with default number of plot points.
unsigned required_nvalue(const unsigned &n) const
Required # of `values&#39; (pinned or dofs) at node n.
void get_exact_u(const Vector< double > &x, Vector< double > &u)
void output(FILE *file_pt)
C-style output function: x,y,u or x,y,z,u.
MyShellEquations(const MyShellEquations &dummy)
Broken copy constructor.
virtual unsigned u_index_shell() const
Return the index at which the unknown value is stored. In derived multi-physics elements, this function should be overloaded to reflect the chosen storage scheme. Note that these equations require that the unknown is always stored at the same index at each node.
GeomObject *& undeformed_midplane_pt()
Access function: Undeformed shell.
SourceFctPt Source_fct_pt
Pointer to source function:
void doc_solution(DocInfo &doc_info)
Doc the solution, pass the number of the case considered, so that output files can be distinguished...
double * H_pt
Pointer to wall thickness.
MyShellEquations< DIM, NNODE_1D >::SourceFctPt Source_fct_pt
Pointer to source function.
MyLinearisedShellProblem(typename MyShellEquations< DIM, NNODE_1D >::SourceFctPt source_fct_pt, const string &node_file_name, const string &element_file_name, const string &poly_file_name)
Constructor: Pass number of elements and pointer to source function.