axisym_fvk_elements.h
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Version 1.0; svn revision $LastChangedRevision: 1097 $
7 //LIC//
8 //LIC// $LastChangedDate: 2015-12-17 11:53:17 +0000 (Thu, 17 Dec 2015) $
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 //Header file for axisymmetric FoepplvonKarman elements
31 #ifndef OOMPH_AXISYM_FOEPPLVONKARMAN_ELEMENTS_HEADER
32 #define OOMPH_AXISYM_FOEPPLVONKARMAN_ELEMENTS_HEADER
33 
34 
35 // Config header generated by autoconfig
36 #ifdef HAVE_CONFIG_H
37 #include <oomph-lib-config.h>
38 #endif
39 
40 #include "../generic/nodes.h"
41 #include "../generic/Qelements.h"
42 #include "../generic/oomph_utilities.h"
43 #include "../generic/element_with_external_element.h"
44 
45 namespace oomph
46 {
47 
48 //=============================================================
49 /// A class for all isoparametric elements that solve the
50 /// axisum Foeppl von Karman equations.
51 ///
52 /// This contains the generic maths. Shape functions, geometric
53 /// mapping etc. must get implemented in derived class.
54 //=============================================================
55  class AxisymFoepplvonKarmanEquations : public virtual FiniteElement
56  {
57  public:
58 
59  /// \short Function pointer to pressure function fct(r,f(r)) --
60  /// r is a Vector!
61  typedef void (*AxisymFoepplvonKarmanPressureFctPt)
62  (const double& r, double& f);
63 
64  /// \short Constructor (must initialise the Pressure_fct_pt and
65  /// Airy_forcing_fct_pt to null). Also set physical parameters to their
66  /// default values.
69  {
70  //Set all the physical constants to the default value (zero)
72  Linear_bending_model = false;
73  }
74 
75  /// Broken copy constructor
77  {
78  BrokenCopy::broken_copy("AxisymFoepplvonKarmanEquations");
79  }
80 
81  /// Broken assignment operator
83  {
84  BrokenCopy::broken_assign("AxisymFoepplvonKarmanEquations");
85  }
86 
87  /// FvK parameter
88  const double &eta() const {return *Eta_pt;}
89 
90  /// Pointer to FvK parameter
91  double* &eta_pt() {return Eta_pt;}
92 
93  /// \short Return the index at which the i-th unknown value
94  /// is stored. The default value, i, is appropriate for single-physics
95  /// problems. By default, these are:
96  /// 0: w
97  /// 1: laplacian w
98  /// 2: phi
99  /// 3: laplacian phi
100  /// 4-5: smooth first derivatives
101  /// In derived multi-physics elements, this function should be overloaded
102  /// to reflect the chosen storage scheme. Note that these equations require
103  /// that the unknown is always stored at the same index at each node.
104  virtual inline unsigned nodal_index_fvk(const unsigned& i=0)
105  const {return i;}
106 
107  /// Output with default number of plot points
108  void output(std::ostream &outfile)
109  {
110  const unsigned n_plot=5;
111  output(outfile,n_plot);
112  }
113 
114  /// \short Output FE representation of soln: r,w,sigma_r_r,sigma_phi_phi
115  /// at n_plot plot points
116  void output(std::ostream &outfile, const unsigned &n_plot);
117 
118  /// C_style output with default number of plot points
119  void output(FILE* file_pt)
120  {
121  const unsigned n_plot=5;
122  output(file_pt,n_plot);
123  }
124 
125  /// \short C-style output FE representation of soln: r,w at
126  /// n_plot plot points
127  void output(FILE* file_pt, const unsigned &n_plot);
128 
129  /// Output exact soln: r,w_exact at n_plot plot points
130  void output_fct(std::ostream &outfile, const unsigned &n_plot,
132 
133  /// \short Output exact soln: r,w_exact at
134  /// n_plot plot points (dummy time-dependent version to
135  /// keep intel compiler happy)
136  virtual void output_fct(std::ostream &outfile, const unsigned &n_plot,
137  const double& time,
139  exact_soln_pt)
140  {
141  throw OomphLibError(
142  "There is no time-dependent output_fct() for Foeppl von Karman"
143  "elements ",
144  OOMPH_CURRENT_FUNCTION,
145  OOMPH_EXCEPTION_LOCATION);
146  }
147 
148  /// Get error against and norm of exact solution
149  void compute_error(std::ostream &outfile,
151  double& error, double& norm);
152 
153 
154  /// Dummy, time dependent error checker
155  void compute_error(std::ostream &outfile,
157  const double& time, double& error, double& norm)
158  {
159  throw OomphLibError(
160  "There is no time-dependent compute_error() for Foeppl von Karman"
161  "elements",
162  OOMPH_CURRENT_FUNCTION,
163  OOMPH_EXCEPTION_LOCATION);
164  }
165 
166  /// Access function: Pointer to pressure function
168  {return Pressure_fct_pt;}
169 
170  /// Access function: Pointer to pressure function. Const version
172  {return Pressure_fct_pt;}
173 
174  /// Access function: Pointer to Airy forcing function
176  {return Airy_forcing_fct_pt;}
177 
178  /// Access function: Pointer to Airy forcing function. Const version
180  const {return Airy_forcing_fct_pt;}
181 
182  /// \short Get pressure term at (Eulerian) position r. This function is
183  /// virtual to allow overloading in multi-physics problems where
184  /// the strength of the pressure function might be determined by
185  /// another system of equations.
186  inline virtual void get_pressure_fvk(const unsigned& ipt,
187  const double& r,
188  double& pressure) const
189  {
190  //If no pressure function has been set, return zero
191  if(Pressure_fct_pt==0)
192  {
193  pressure = 0.0;
194  }
195  else
196  {
197  // Get pressure strength
198  (*Pressure_fct_pt)(r,pressure);
199  }
200  }
201 
202  /// \short Get Airy forcing term at (Eulerian) position r. This function is
203  /// virtual to allow overloading in multi-physics problems where
204  /// the strength of the pressure function might be determined by
205  /// another system of equations.
206  inline virtual void get_airy_forcing_fvk(const unsigned& ipt,
207  const double& r,
208  double& airy_forcing) const
209  {
210  //If no Airy forcing function has been set, return zero
211  if(Airy_forcing_fct_pt==0)
212  {
213  airy_forcing = 0.0;
214  }
215  else
216  {
217  // Get Airy forcing strength
218  (*Airy_forcing_fct_pt)(r,airy_forcing);
219  }
220  }
221 
222  /// Get gradient of deflection: gradient[i] = dw/dr_i */
224  Vector<double>& gradient) const
225  {
226  //Find out how many nodes there are in the element
227  const unsigned n_node = nnode();
228 
229  //Get the index at which the unknown is stored
230  const unsigned w_nodal_index = nodal_index_fvk(0);
231 
232  //Set up memory for the shape and test functions
233  Shape psi(n_node);
234  DShape dpsidr(n_node,1);
235 
236  //Call the derivatives of the shape and test functions
237  dshape_eulerian(s,psi,dpsidr);
238 
239  //Initialise to zero
240  gradient[0] = 0.0;
241 
242  // Loop over nodes
243  for(unsigned l=0;l<n_node;l++)
244  {
245  gradient[0] += this->nodal_value(l,w_nodal_index)*dpsidr(l,0);
246  }
247  }
248 
249  /// Fill in the residuals with this element's contribution
251 
252 
253  // hierher Jacobian not yet implemented
254  //void fill_in_contribution_to_jacobian(Vector<double> &residuals,
255  // DenseMatrix<double> &jacobian);
256 
257  /// \short Return FE representation of vertical displacement, w_fvk(s)
258  /// at local coordinate s
259  inline double interpolated_w_fvk(const Vector<double> &s) const
260  {
261  //Find number of nodes
262  const unsigned n_node = nnode();
263 
264  //Get the index at which the unknown is stored
265  const unsigned w_nodal_index = nodal_index_fvk(0);
266 
267  //Local shape function
268  Shape psi(n_node);
269 
270  //Find values of shape function
271  shape(s,psi);
272 
273  //Initialise value of u
274  double interpolated_w = 0.0;
275 
276  //Loop over the local nodes and sum
277  for(unsigned l=0;l<n_node;l++)
278  {
279  interpolated_w += this->nodal_value(l,w_nodal_index)*psi[l];
280  }
281 
282  return(interpolated_w);
283  }
284 
285  /// \short Compute in-plane stresses. Return boolean to indicate success
286  /// (false if attempt to evaluate stresses at zero radius)
287  bool interpolated_stress(const Vector<double> &s, double& sigma_r_r,
288  double& sigma_phi_phi);
289 
290 
291  /// \short Self-test: Return 0 for OK
292  unsigned self_test();
293 
294  /// \short Sets a flag to signify that we are solving the linear,
295  /// pure bending equations, and pin all the nodal values that will
296  /// not be used in this case
298  {
299  // Set the boolean flag
300  Linear_bending_model = true;
301 
302  // Get the index of the first FvK nodal value
303  unsigned first_fvk_nodal_index = nodal_index_fvk();
304 
305  // Get the total number of FvK nodal values (assuming they are stored
306  // contiguously) at node 0 (it's the same at all nodes anyway)
307  unsigned total_fvk_nodal_indices = 6;
308 
309  // Get the number of nodes in this element
310  unsigned n_node = nnode();
311 
312  // Loop over the appropriate nodal indices
313  for(unsigned index=first_fvk_nodal_index+2;
314  index<first_fvk_nodal_index+total_fvk_nodal_indices;
315  index++)
316  {
317  // Loop over the nodes in the element
318  for(unsigned inod=0;inod<n_node;inod++)
319  {
320  // Pin the nodal value at the current index
321  node_pt(inod)->pin(index);
322  }
323  }
324  }
325 
326 
327  protected:
328 
329  /// \short Shape/test functions and derivs w.r.t. to global coords at
330  /// local coord. s; return Jacobian of mapping
332  (const Vector<double> &s,
333  Shape &psi,
334  DShape &dpsidr,
335  Shape &test,
336  DShape &dtestdr)
337  const=0;
338 
339 
340  /// \short Shape/test functions and derivs w.r.t. to global coords at
341  /// integration point ipt; return Jacobian of mapping
343  (const unsigned &ipt,
344  Shape &psi,
345  DShape &dpsidr,
346  Shape &test,
347  DShape &dtestdr)
348  const=0;
349 
350  /// Pointer to FvK parameter
351  double *Eta_pt;
352 
353  /// Pointer to pressure function:
355 
356  /// Pointer to Airy forcing function
358 
359  /// Default value for physical constants
360  static double Default_Physical_Constant_Value;
361 
362  /// \short Flag which stores whether we are using a linear,
363  /// pure bending model instead of the full non-linear Foeppl-von Karman
365 
366  };
367 
368 
369 
370 ///////////////////////////////////////////////////////////////////////////
371 ///////////////////////////////////////////////////////////////////////////
372 ///////////////////////////////////////////////////////////////////////////
373 
374 
375 //======================================================================
376 /// Axisym FoepplvonKarmanElement elements are 1D
377 /// Foeppl von Karman elements with isoparametric interpolation for the
378 /// function.
379 //======================================================================
380  template <unsigned NNODE_1D>
381  class AxisymFoepplvonKarmanElement : public virtual QElement<1,NNODE_1D>,
382  public virtual AxisymFoepplvonKarmanEquations
383  {
384 
385  private:
386 
387  /// \short Static int that holds the number of variables at
388  /// nodes: always the same
389  static const unsigned Initial_Nvalue;
390 
391  public:
392 
393  ///\short Constructor: Call constructors for QElement and
394  /// AxisymFoepplvonKarmanEquations
397  {}
398 
399  /// Broken copy constructor
402  {
403  BrokenCopy::broken_copy("AxisymFoepplvonKarmanElement");
404  }
405 
406  /// Broken assignment operator
408  {
409  BrokenCopy::broken_assign("AxisymFoepplvonKarmanElement");
410  }
411 
412  /// \short Required # of `values' (pinned or dofs)
413  /// at node n
414  inline unsigned required_nvalue(const unsigned &n) const
415  {return Initial_Nvalue;}
416 
417 
418  /// \short Output function:
419  /// r,w,sigma_r_r,sigma_phi_phi
420  void output(std::ostream &outfile)
422 
423  /// \short Output function:
424  /// r,w,sigma_r_r,sigma_phi_phi at n_plot plot points
425  void output(std::ostream &outfile, const unsigned &n_plot)
426  {AxisymFoepplvonKarmanEquations::output(outfile,n_plot);}
427 
428  /// \short C-style output function:
429  /// r,w
430  void output(FILE* file_pt)
432 
433  /// \short C-style output function:
434  /// r,w at n_plot plot points
435  void output(FILE* file_pt, const unsigned &n_plot)
436  {AxisymFoepplvonKarmanEquations::output(file_pt,n_plot);}
437 
438  /// \short Output function for an exact solution:
439  /// r,w_exact at n_plot plot points
440  void output_fct(std::ostream &outfile, const unsigned &n_plot,
442  {AxisymFoepplvonKarmanEquations::output_fct(outfile,n_plot,exact_soln_pt);}
443 
444  /// \short Output function for a time-dependent exact solution.
445  /// r,w_exact at n_plot plot points
446  /// (Calls the steady version)
447  void output_fct(std::ostream &outfile, const unsigned &n_plot,
448  const double& time,
451  (outfile,n_plot,time,exact_soln_pt);}
452 
453 
454  protected:
455 
456  /// \short Shape, test functions & derivs. w.r.t. to global coords.
457  /// Return Jacobian.
459  const Vector<double> &s, Shape &psi, DShape &dpsidr,
460  Shape &test, DShape &dtestdr) const;
461 
462  /// \short Shape, test functions & derivs. w.r.t. to global coords. at
463  /// integration point ipt. Return Jacobian.
465  (const unsigned& ipt,
466  Shape &psi,
467  DShape &dpsidr,
468  Shape &test,
469  DShape &dtestdr)
470  const;
471 
472  };
473 
474 
475 
476 //Inline functions:
477 
478 //======================================================================
479 /// Define the shape functions and test functions and derivatives
480 /// w.r.t. global coordinates and return Jacobian of mapping.
481 ///
482 /// Galerkin: Test functions = shape functions
483 //======================================================================
484  template<unsigned NNODE_1D>
487  const Vector<double> &s,
488  Shape &psi,
489  DShape &dpsidr,
490  Shape &test,
491  DShape &dtestdr) const
492 
493  {
494  //Call the geometrical shape functions and derivatives
495  const double J = this->dshape_eulerian(s,psi,dpsidr);
496 
497  //Set the test functions equal to the shape functions
498  test = psi;
499  dtestdr= dpsidr;
500 
501  //Return the jacobian
502  return J;
503  }
504 
505 
506 //======================================================================
507 /// Define the shape functions and test functions and derivatives
508 /// w.r.t. global coordinates and return Jacobian of mapping.
509 ///
510 /// Galerkin: Test functions = shape functions
511 //======================================================================
512  template<unsigned NNODE_1D>
515  const unsigned &ipt,
516  Shape &psi,
517  DShape &dpsidr,
518  Shape &test,
519  DShape &dtestdr) const
520  {
521  //Call the geometrical shape functions and derivatives
522  const double J = this->dshape_eulerian_at_knot(ipt,psi,dpsidr);
523 
524  //Set the pointers of the test functions
525  test = psi;
526  dtestdr = dpsidr;
527 
528  //Return the jacobian
529  return J;
530  }
531 
532 
533 
534 ///////////////////////////////////////////////////////////////////////////
535 ///////////////////////////////////////////////////////////////////////////
536 ///////////////////////////////////////////////////////////////////////////
537 
538 
539 //======================================================================
540 /// FSI Axisym FoepplvonKarmanElement elements are 1D
541 /// Foeppl von Karman elements with isoparametric interpolation for the
542 /// function. Gets traction from adjacent fluid element(s) of type
543 /// FLUID_ELEMENT.
544 //======================================================================
545  template <unsigned NNODE_1D, class FLUID_ELEMENT>
547  public virtual AxisymFoepplvonKarmanElement<NNODE_1D>,
548  public virtual ElementWithExternalElement
549  {
550 
551  public:
552 
553  /// Constructor
556  {
557  // Set source element storage: one interaction with an external
558  // element -- the fluid bulk element that provides the pressure
559  this->set_ninteraction(1);
560  }
561 
562  /// Empty virtual destructor
564 
565  /// \short Return the ratio of the stress scales used to non-dimensionalise
566  /// the fluid and elasticity equations.
567  const double &q() const {return *Q_pt;}
568 
569  /// \short Return a pointer the ratio of stress scales used to
570  /// non-dimensionalise the fluid and solid equations.
571  double* &q_pt() {return Q_pt;}
572 
573  /// \short How many items of Data does the shape of the object depend on?
574  /// All nodal data
575  virtual unsigned ngeom_data() const
576  {
577  return this->nnode();
578  }
579 
580  /// \short Return pointer to the j-th Data item that the object's
581  /// shape depends on.
582  virtual Data* geom_data_pt(const unsigned& j)
583  {
584  return this->node_pt(j);
585  }
586 
587  /// \short Overloaded position function: Return 2D position vector:
588  /// (r(zeta),z(zeta)) of material point whose "Lagrangian coordinate"
589  /// is given by zeta. Here r=zeta!
590  void position(const Vector<double>& zeta, Vector<double>& r) const
591  {
592  const unsigned t=0;
593  this->position(t,zeta,r);
594  }
595 
596  /// \short Overloaded position function: Return 2D position vector:
597  /// (r(zeta),z(zeta)) of material point whose "Lagrangian coordinate"
598  /// is given by zeta.
599  void position(const unsigned& t, const Vector<double>& zeta,
600  Vector<double>& r) const
601  {
602  //Find number of nodes
603  const unsigned n_node = this->nnode();
604 
605  //Get the index at which the poisson unknown is stored
606  const unsigned w_nodal_index = this->nodal_index_fvk(0);
607 
608  //Local shape function
609  Shape psi(n_node);
610 
611  //Find values of shape function
612  this->shape(zeta,psi);
613 
614  //Initialise
615  double interpolated_w = 0.0;
616  double interpolated_r = 0.0;
617 
618  //Loop over the local nodes and sum
619  for(unsigned l=0;l<n_node;l++)
620  {
621  interpolated_w += this->nodal_value(t,l,w_nodal_index)*psi[l];
622  interpolated_r += this->node_pt(l)->x(t,0)*psi[l];
623  }
624 
625  // Assign
626  r[0]=interpolated_r;
627  r[1]=interpolated_w;
628  }
629 
630  /// \short j-th time-derivative on object at current time:
631  /// \f$ \frac{d^{j} r(\zeta)}{dt^j} \f$.
632  void dposition_dt(const Vector<double>& zeta, const unsigned& j,
633  Vector<double>& drdt)
634  {
635  //Find number of nodes
636  const unsigned n_node = this->nnode();
637 
638  //Get the index at which the poisson unknown is stored
639  const unsigned w_nodal_index = this->nodal_index_fvk(0);
640 
641  //Local shape function
642  Shape psi(n_node);
643 
644  //Find values of shape function
645  this->shape(zeta,psi);
646 
647  //Initialise
648  double interpolated_dwdt = 0.0;
649  double interpolated_drdt = 0.0;
650 
651  //Loop over the local nodes and sum
652  for(unsigned l=0;l<n_node;l++)
653  {
654  // Get the timestepper
656 
657  // If we are doing an unsteady solve then calculate the derivative
658  if(!time_stepper_pt->is_steady())
659  {
660  // Get the number of values required to represent history
661  const unsigned n_time=time_stepper_pt->ntstorage();
662 
663  // Loop over history values
664  for(unsigned t=0;t<n_time;t++)
665  {
666  //Add the contribution to the derivative
667  interpolated_dwdt+=time_stepper_pt->weight(1,t)*
668  this->nodal_value(t,l,w_nodal_index)*psi[l];
669  }
670  }
671  }
672 
673  // Assign
674  drdt[0]=interpolated_drdt;
675  drdt[1]=interpolated_dwdt;
676  }
677 
678 
679 
680  /// \short Overload pressure term at (Eulerian) position r.
681  /// Adds fluid traction to pressure imposed by "pressure fct pointer"
682  /// (which can be regarded as applying an external (i.e.
683  /// "on the other side" of the fluid) pressure
684  inline virtual void get_pressure_fvk(const unsigned& ipt,
685  const double& r,
686  double& pressure) const
687  {
688  pressure=0.0;
689 
690  // Get underlying version
692 
693  // Get FSI parameter
694  const double q_value=q();
695 
696  // Get fluid element
697  FLUID_ELEMENT* ext_el_pt=
698  dynamic_cast<FLUID_ELEMENT*>(external_element_pt(0,ipt));
700 
701  // Outer unit normal is vertically upward (in z direction)
702  // (within an essentiall flat) model for the wall)
703  Vector<double> normal(2);
704  normal[0]=0.0;
705  normal[1]=1.0;
706 
707  // Get traction
708  Vector<double> traction(3);
709  ext_el_pt->traction(s_ext,normal,traction);
710 
711  // Add z-component of traction
712  pressure-=q_value*traction[1];
713  }
714 
715 
716  /// Output integration points (for checking of fsi setup)
717  void output_integration_points(std::ostream &outfile)
718  {
719  // How many nodes do we have?
720  unsigned nnod=this->nnode();
721  Shape psi(nnod);
722 
723  //Get the index at which the unknown is stored
724  const unsigned w_nodal_index = this->nodal_index_fvk(0);
725 
726  //Loop over the integration points
727  const unsigned n_intpt = this->integral_pt()->nweight();
728  outfile << "ZONE I=" << n_intpt << std::endl;
729  for(unsigned ipt=0;ipt<n_intpt;ipt++)
730  {
731  // Get shape fct
732  Vector<double> s(1);
733  s[0]=this->integral_pt()->knot(ipt,0);
734  shape(s,psi);
735 
736  //Initialise
737  double interpolated_w = 0.0;
738  double interpolated_r = 0.0;
739 
740  //Loop over the local nodes and sum
741  for(unsigned l=0;l<nnod;l++)
742  {
743  interpolated_w += this->nodal_value(l,w_nodal_index)*psi[l];
744  interpolated_r += this->node_pt(l)->x(0)*psi[l];
745  }
746 
747  // Get fluid element
748  FLUID_ELEMENT* ext_el_pt=
749  dynamic_cast<FLUID_ELEMENT*>(external_element_pt(0,ipt));
751 
752  // Get veloc
753  Vector<double> veloc(3);
754  ext_el_pt->interpolated_u_axi_nst(s_ext,veloc);
755  Vector<double> x(2);
756  ext_el_pt->interpolated_x(s_ext,x);
757 
758  outfile << interpolated_r << " "
759  << interpolated_w << " "
760  << veloc[0] << " "
761  << veloc[1] << " "
762  << x[0] << " "
763  << x[1] << " "
764  << std::endl;
765  }
766  }
767 
768 
769  /// Output adjacent fluid elements (for checking of fsi setup)
770  void output_adjacent_fluid_elements(std::ostream &outfile,
771  const unsigned& nplot)
772  {
773  //Loop over the integration points
774  const unsigned n_intpt = this->integral_pt()->nweight();
775  for(unsigned ipt=0;ipt<n_intpt;ipt++)
776  {
777  // Get fluid element
778  FLUID_ELEMENT* ext_el_pt=
779  dynamic_cast<FLUID_ELEMENT*>(external_element_pt(0,ipt));
780 
781  // Dump it
782  ext_el_pt->output(outfile,nplot);
783  }
784  }
785 
786  /// \short Perform any auxiliary node update fcts of the adjacent
787  /// fluid elements
789  {
791  }
792 
793  /// \short Perform any auxiliary node update fcts of the adjacent
794  /// fluid elements
796  {
798  }
799 
800 
801  /// \short Perform any auxiliary node update fcts of the adjacent
802  /// fluid elements
804  {
806  }
807 
808 
809  /// \short Perform any auxiliary node update fcts of the adjacent
810  /// fluid elements
812  {
814  }
815 
816 
817  /// \short Update the nodal positions in all fluid elements that affect
818  /// the traction on this element
820  {
821  // Don't update elements repeatedly
822  std::map<FLUID_ELEMENT*,bool> done;
823 
824  // Number of integration points
825  unsigned n_intpt=integral_pt()->nweight();
826 
827  // Loop over all integration points in wall element
828  for (unsigned iint=0;iint<n_intpt;iint++)
829  {
830  // Get fluid element that affects this integration point
831  FLUID_ELEMENT* el_f_pt=dynamic_cast<FLUID_ELEMENT*>
832  (external_element_pt(0,iint));
833 
834  // Is there an adjacent fluid element?
835  if (el_f_pt!=0)
836  {
837  // Have we updated its positions yet?
838  if (!done[el_f_pt])
839  {
840  // Update nodal positions
841  el_f_pt->node_update();
842  done[el_f_pt]=true;
843  }
844  }
845  }
846  }
847 
848 
849  /// \short Output FE representation of soln: r,w,dwdt,sigma_r_r,sigma_phi_phi
850  /// at n_plot plot points
851  void output(std::ostream &outfile, const unsigned &n_plot)
852  {
853  //Vector of local coordinates
854  Vector<double> s(1);
855 
856  // Tecplot header info
857  outfile << "ZONE\n";
858 
859  // Loop over plot points
860  unsigned num_plot_points=nplot_points(n_plot);
861  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
862  {
863  // Get local coordinates of plot point
864  get_s_plot(iplot,n_plot,s);
865 
866  // Get velocity
867  Vector<double> drdt(2);
868  dposition_dt(s,1,drdt);
869 
870  // Get stress
871  double sigma_r_r=0.0;
872  double sigma_phi_phi=0.0;
873  bool success=this->interpolated_stress(s,sigma_r_r,sigma_phi_phi);
874  if (success)
875  {
876  outfile << this->interpolated_x(s,0) << " "
877  << this->interpolated_w_fvk(s) << " "
878  << drdt[0] << " "
879  << drdt[1] << " "
880  << sigma_r_r << " "
881  << sigma_phi_phi << std::endl;
882  }
883  }
884  }
885 
886 
887  protected:
888 
889  /// \short Pointer to the ratio, \f$ Q \f$ , of the stress used to
890  /// non-dimensionalise the fluid stresses to the stress used to
891  /// non-dimensionalise the solid stresses.
892  double *Q_pt;
893 
894  };
895 
896 
897 
898 
899 }
900 
901 #endif
902 
void position(const unsigned &t, const Vector< double > &zeta, Vector< double > &r) const
Overloaded position function: Return 2D position vector: (r(zeta),z(zeta)) of material point whose "L...
void output(FILE *file_pt)
C_style output with default number of plot points.
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
virtual void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s) const
Get cector of local coordinates of plot point i (when plotting nplot points in each "coordinate direc...
Definition: elements.h:2938
void node_update_adjacent_fluid_elements()
Update the nodal positions in all fluid elements that affect the traction on this element...
AxisymFoepplvonKarmanPressureFctPt airy_forcing_fct_pt() const
Access function: Pointer to Airy forcing function. Const version.
Vector< double > & external_element_local_coord(const unsigned &interaction_index, const unsigned &ipt)
Access function to get source element's local coords for specified interaction index at specified int...
AxisymFoepplvonKarmanEquations()
Constructor (must initialise the Pressure_fct_pt and Airy_forcing_fct_pt to null). Also set physical parameters to their default values.
double * Q_pt
Pointer to the ratio, , of the stress used to non-dimensionalise the fluid stresses to the stress us...
AxisymFoepplvonKarmanElement()
Constructor: Call constructors for QElement and AxisymFoepplvonKarmanEquations.
virtual Data * geom_data_pt(const unsigned &j)
Return pointer to the j-th Data item that the object's shape depends on.
double dshape_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsidx) const
Compute the geometric shape functions and also first derivatives w.r.t. global coordinates at local c...
Definition: elements.cc:3225
void update_before_external_interaction_geometric_fd()
Perform any auxiliary node update fcts of the adjacent fluid elements.
cstr elem_len * i
Definition: cfortran.h:607
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:2976
double nodal_value(const unsigned &n, const unsigned &i) const
Return the i-th value stored at local node n. Produces suitably interpolated values for hanging nodes...
Definition: elements.h:2458
virtual double weight(const unsigned &i, const unsigned &j) const
Access function for j-th weight for the i-th derivative.
Definition: timesteppers.h:557
double dshape_and_dtest_eulerian_axisym_fvk(const Vector< double > &s, Shape &psi, DShape &dpsidr, Shape &test, DShape &dtestdr) const
Shape, test functions & derivs. w.r.t. to global coords. Return Jacobian.
char t
Definition: cfortran.h:572
AxisymFoepplvonKarmanPressureFctPt Pressure_fct_pt
Pointer to pressure function:
void dposition_dt(const Vector< double > &zeta, const unsigned &j, Vector< double > &drdt)
j-th time-derivative on object at current time: .
const double & eta() const
FvK parameter.
void set_ninteraction(const unsigned &n_interaction)
Set the number of interactions in the element This function is usually called in the specific element...
void operator=(const AxisymFoepplvonKarmanElement< NNODE_1D > &)
Broken assignment operator.
bool is_steady() const
Flag to indicate if a timestepper has been made steady (possibly temporarily to switch off time-depen...
Definition: timesteppers.h:375
unsigned ntstorage() const
Return the number of doubles required to represent history (one for steady)
Definition: timesteppers.h:562
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. r,w_exact at n_plot plot points (Calls the stead...
void operator=(const AxisymFoepplvonKarmanEquations &)
Broken assignment operator.
void pin(const unsigned &i)
Pin the i-th stored variable.
Definition: nodes.h:383
double dshape_and_dtest_eulerian_at_knot_axisym_fvk(const unsigned &ipt, Shape &psi, DShape &dpsidr, Shape &test, DShape &dtestdr) const
Shape, test functions & derivs. w.r.t. to global coords. at integration point ipt. Return Jacobian.
static const unsigned Initial_Nvalue
Static int that holds the number of variables at nodes: always the same.
void reset_in_external_interaction_geometric_fd(const unsigned &i)
Perform any auxiliary node update fcts of the adjacent fluid elements.
void output(std::ostream &outfile)
Output with default number of plot points.
void output(FILE *file_pt)
C-style output function: r,w.
unsigned self_test()
Self-test: Return 0 for OK.
TimeStepper *& time_stepper_pt()
Access function for pointer to time stepper: Null if object is not time-dependent.
Definition: geom_objects.h:197
void(* AxisymFoepplvonKarmanPressureFctPt)(const double &r, double &f)
Function pointer to pressure function fct(r,f(r)) – r is a Vector!
virtual double dshape_and_dtest_eulerian_axisym_fvk(const Vector< double > &s, Shape &psi, DShape &dpsidr, Shape &test, DShape &dtestdr) const =0
Shape/test functions and derivs w.r.t. to global coords at local coord. s; return Jacobian of mapping...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:995
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:3841
void update_in_external_interaction_geometric_fd(const unsigned &i)
Perform any auxiliary node update fcts of the adjacent fluid elements.
static char t char * s
Definition: cfortran.h:572
unsigned required_nvalue(const unsigned &n) const
Required # of `values' (pinned or dofs) at node n.
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function: r,w at n_plot plot points.
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
void output(std::ostream &outfile, const unsigned &n_plot)
Output FE representation of soln: r,w,dwdt,sigma_r_r,sigma_phi_phi at n_plot plot points...
virtual ~FSIAxisymFoepplvonKarmanElement()
Empty virtual destructor.
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
Definition: elements.h:1900
A class that represents a collection of data; each Data object may contain many different individual ...
Definition: nodes.h:89
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as ...
Definition: elements.h:1720
virtual void output_fct(std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Output exact soln: r,w_exact at n_plot plot points (dummy time-dependent version to keep intel compil...
void compute_error(std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
Dummy, time dependent error checker.
virtual unsigned nodal_index_fvk(const unsigned &i=0) const
Return the index at which the i-th unknown value is stored. The default value, i, is appropriate for ...
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2097
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output function for an exact solution: r,w_exact at n_plot plot points.
virtual double dshape_and_dtest_eulerian_at_knot_axisym_fvk(const unsigned &ipt, Shape &psi, DShape &dpsidr, Shape &test, DShape &dtestdr) const =0
Shape/test functions and derivs w.r.t. to global coords at integration point ipt; return Jacobian of ...
virtual void get_pressure_fvk(const unsigned &ipt, const double &r, double &pressure) const
Overload pressure term at (Eulerian) position r. Adds fluid traction to pressure imposed by "pressure...
void output_adjacent_fluid_elements(std::ostream &outfile, const unsigned &nplot)
Output adjacent fluid elements (for checking of fsi setup)
void output(std::ostream &outfile, const unsigned &n_plot)
Output function: r,w,sigma_r_r,sigma_phi_phi at n_plot plot points.
double *& q_pt()
Return a pointer the ratio of stress scales used to non-dimensionalise the fluid and solid equations...
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
virtual void get_pressure_fvk(const unsigned &ipt, const double &r, double &pressure) const
Get pressure term at (Eulerian) position r. This function is virtual to allow overloading in multi-ph...
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
FiniteElement *& external_element_pt(const unsigned &interaction_index, const unsigned &ipt)
Access function to source element for specified interaction index at specified integration point...
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
Definition: nodes.h:246
static double Default_Physical_Constant_Value
Default value for physical constants.
AxisymFoepplvonKarmanPressureFctPt Airy_forcing_fct_pt
Pointer to Airy forcing function.
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2134
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Get error against and norm of exact solution.
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Function pointer for function that computes Vector-valued time-dependent function as ...
Definition: elements.h:1726
void output_integration_points(std::ostream &outfile)
Output integration points (for checking of fsi setup)
double *& eta_pt()
Pointer to FvK parameter.
void position(const Vector< double > &zeta, Vector< double > &r) const
Overloaded position function: Return 2D position vector: (r(zeta),z(zeta)) of material point whose "L...
bool Linear_bending_model
Flag which stores whether we are using a linear, pure bending model instead of the full non-linear Fo...
double interpolated_w_fvk(const Vector< double > &s) const
Return FE representation of vertical displacement, w_fvk(s) at local coordinate s.
void get_gradient_of_deflection(const Vector< double > &s, Vector< double > &gradient) const
Get gradient of deflection: gradient[i] = dw/dr_i */.
AxisymFoepplvonKarmanEquations(const AxisymFoepplvonKarmanEquations &dummy)
Broken copy constructor.
bool interpolated_stress(const Vector< double > &s, double &sigma_r_r, double &sigma_phi_phi) const
Compute in-plane stresses. Return boolean to indicate success (false if attempt to evaluate stresses ...
AxisymFoepplvonKarmanPressureFctPt pressure_fct_pt() const
Access function: Pointer to pressure function. Const version.
void use_linear_bending_model()
Sets a flag to signify that we are solving the linear, pure bending equations, and pin all the nodal ...
AxisymFoepplvonKarmanPressureFctPt & airy_forcing_fct_pt()
Access function: Pointer to Airy forcing function.
void output(std::ostream &outfile)
Output function: r,w,sigma_r_r,sigma_phi_phi.
const double & q() const
Return the ratio of the stress scales used to non-dimensionalise the fluid and elasticity equations...
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
Definition: timesteppers.h:219
virtual unsigned ngeom_data() const
How many items of Data does the shape of the object depend on? All nodal data.
virtual void shape(const Vector< double > &s, Shape &psi) const =0
Calculate the geometric shape functions at local coordinate s. This function must be overloaded for e...
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output exact soln: r,w_exact at n_plot plot points.
virtual void get_airy_forcing_fvk(const unsigned &ipt, const double &r, double &airy_forcing) const
Get Airy forcing term at (Eulerian) position r. This function is virtual to allow overloading in mult...
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Fill in the residuals with this element's contribution.
void reset_after_external_interaction_geometric_fd()
Perform any auxiliary node update fcts of the adjacent fluid elements.
AxisymFoepplvonKarmanPressureFctPt & pressure_fct_pt()
Access function: Pointer to pressure function.