Example codes
and tutorials
The (Not-so) Quick Guide
List of tutorials/demo codes
Single-Physics Problems
Poisson
Adaptivity illustrated for Poisson
Advection-Diffusion
Unsteady heat equation
Linear wave equation
The Young-Laplace equation
Navier-Stokes
Free-surface Navier-Stokes
Axisymmetric Navier-Stokes
Solid mechanics
Beam structures
Shell structures
Multi-physics Problems
Fluid-structure interaction
Boussinesq convection
Steady thermoelasticity
Methods-based example codes and tutorials
Mesh generation
Linear solvers and preconditioners
Visualisation of the results
Parallel processing
How to write a new element
How to write a new refineable element
Default nonlinear solvers -- the sequence of action functions
...
Documentation
FE theory and top-down discussion of the data structure
The (Not-so) Quick Guide
Comprehensive bottom-up discussion of the data structure
List of available structured and unstructured meshes
Linear solvers and preconditioners
Visualisation of the results
Parallel processing
Coding conventions and C++ style
Creating documentation
Optimisation - robustness vs. "raw speed"
Linear vs. nonlinear problems
Storing shape functions
Changing the default "full" integration scheme
Disabling the ALE formulation of unsteady equations
C vs. C++ output
Different sparse assembly techniques and the STL memory pool
Publications
Publications
Talks
Journal publications
Theses
Picture show
Download
Copyright
Download/installation instructions
Download page
FAQ & Contact
FAQ
Change log
Bugs and other known problems
Completeness of the library & our "To-Do List"
Contact the developers
Get involved

 


Beta release!

Please note that the library has not been "officially" released. While we continue to work on the documentation, these web pages are likely to contain broken links and documents in draft form. Please send an email to

oomph-lib AT maths DOT man DOT ac DOT uk

if you wish to be informed of the library's "official" release.

linear_elasticity_traction_elements.h

Go to the documentation of this file.
00001 //LIC// ====================================================================
00002 //LIC// This file forms part of oomph-lib, the object-oriented, 
00003 //LIC// multi-physics finite-element library, available 
00004 //LIC// at http://www.oomph-lib.org.
00005 //LIC// 
00006 //LIC//           Version 0.90. August 3, 2009.
00007 //LIC// 
00008 //LIC// Copyright (C) 2006-2009 Matthias Heil and Andrew Hazel
00009 //LIC// 
00010 //LIC// This library is free software; you can redistribute it and/or
00011 //LIC// modify it under the terms of the GNU Lesser General Public
00012 //LIC// License as published by the Free Software Foundation; either
00013 //LIC// version 2.1 of the License, or (at your option) any later version.
00014 //LIC// 
00015 //LIC// This library is distributed in the hope that it will be useful,
00016 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 //LIC// Lesser General Public License for more details.
00019 //LIC// 
00020 //LIC// You should have received a copy of the GNU Lesser General Public
00021 //LIC// License along with this library; if not, write to the Free Software
00022 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00023 //LIC// 02110-1301  USA.
00024 //LIC// 
00025 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
00026 //LIC// 
00027 //LIC//====================================================================
00028 //Header file for elements that are used to apply surface loads to 
00029 //the equations of elasticity
00030 
00031 #ifndef OOMPH_LINEAR_ELASTICITY_TRACTION_ELEMENTS_HEADER
00032 #define OOMPH_LINEAR_ELASTICITY_TRACTION_ELEMENTS_HEADER
00033 
00034 // Config header generated by autoconfig
00035 #ifdef HAVE_CONFIG_H
00036   #include <oomph-lib-config.h>
00037 #endif
00038 
00039 
00040 //OOMPH-LIB headers
00041 #include "../generic/Qelements.h"
00042 
00043 namespace oomph
00044 {
00045 
00046 
00047 
00048 //=======================================================================
00049 /// Namespace containing the zero traction function for solid traction
00050 /// elements
00051 //=======================================================================
00052 namespace LinearElasticityTractionElementHelper
00053  {
00054 
00055   //=======================================================================
00056   /// Default load function (zero traction)
00057   //=======================================================================
00058   void Zero_traction_fct(const Vector<double> &x,
00059                          const Vector<double>& N,
00060                          Vector<double>& load)
00061    {
00062     unsigned n_dim=load.size();
00063     for (unsigned i=0;i<n_dim;i++) {load[i]=0.0;}
00064    }
00065  
00066  }
00067 
00068 
00069 //======================================================================
00070 /// A class for elements that allow the imposition of an applied traction
00071 /// in the principle of virtual displacements.
00072 /// The geometrical information can be read from the FaceGeometry<ELEMENT> 
00073 /// class and and thus, we can be generic enough without the need to have
00074 /// a separate equations class.
00075 //======================================================================
00076 template <class ELEMENT>
00077 class LinearElasticityTractionElement : public virtual FaceGeometry<ELEMENT>, 
00078 public virtual FaceElement
00079 {
00080   protected:
00081  
00082  /// Index at which the i-th velocity component is stored
00083  Vector<unsigned> U_index_linear_elasticity_traction;
00084  
00085  /// \short Pointer to an imposed traction function. Arguments:
00086  /// Lagrangian coordinate; Eulerian coordinate; outer unit normal;
00087  /// applied traction. (Not all of the input arguments will be
00088  /// required for all specific load functions but the list should
00089  /// cover all cases)
00090  void (*Traction_fct_pt)(const Vector<double> &x, 
00091                          const Vector<double> &n,
00092                          Vector<double> &result);
00093  
00094 
00095  /// \short Get the traction vector: Pass number of integration point (dummy), 
00096  /// Lagr. coordinate and normal vector and return the load vector
00097  /// (not all of the input arguments will be
00098  /// required for all specific load functions but the list should
00099  /// cover all cases). This function is virtual so it can be 
00100  /// overloaded for FSI.
00101  virtual void get_traction(const unsigned& intpt,
00102                            const Vector<double>& x,
00103                            const Vector<double>& n,
00104                            Vector<double>& traction)
00105   {
00106    Traction_fct_pt(x,n,traction);
00107   }
00108 
00109 
00110  /// \short Helper function that actually calculates the residuals
00111  // This small level of indirection is required to avoid calling
00112  // fill_in_contribution_to_residuals in fill_in_contribution_to_jacobian
00113  // which causes all kinds of pain if overloading later on
00114  void fill_in_contribution_to_residuals_linear_elasticity_traction(
00115   Vector<double> &residuals);
00116 
00117 
00118 public:
00119 
00120  /// \short Constructor, which takes a "bulk" element and the 
00121  /// value of the index and its limit
00122  LinearElasticityTractionElement(FiniteElement* const &element_pt, 
00123                       const int &face_index) : 
00124   FaceGeometry<ELEMENT>(), FaceElement()
00125   { 
00126 #ifdef PARANOID
00127    {
00128   //Check that the element is not a refineable 3d element
00129   ELEMENT* elem_pt = new ELEMENT;
00130   //If it's three-d
00131   if(elem_pt->dim()==3)
00132    {
00133     //Is it refineable
00134     if(dynamic_cast<RefineableElement*>(elem_pt))
00135      {
00136       //Issue a warning
00137       OomphLibWarning(
00138        "This flux element will not work correctly if nodes are hanging\n",
00139        "LinearElasticityTractionElement::Constructor",
00140        OOMPH_EXCEPTION_LOCATION);
00141      }
00142    }
00143  }
00144 #endif
00145  
00146    //Attach the geometrical information to the element. N.B. This function
00147    //also assigns nbulk_value from the required_nvalue of the bulk element
00148    element_pt->build_face_element(face_index,this);
00149 
00150    //Find the dimension of the problem
00151    unsigned n_dim = element_pt->nodal_dimension();
00152    
00153    //Find the index at which the displacmenet unknowns are stored
00154    ELEMENT* cast_element_pt = dynamic_cast<ELEMENT*>(element_pt);
00155    this->U_index_linear_elasticity_traction.resize(n_dim);
00156    for(unsigned i=0;i<n_dim;i++)
00157     {
00158      this->U_index_linear_elasticity_traction[i] = 
00159       cast_element_pt->u_index_linear_elasticity(i);
00160     }
00161  
00162    // Zero traction
00163    Traction_fct_pt=&LinearElasticityTractionElementHelper::Zero_traction_fct;
00164   }
00165  
00166 
00167  /// Reference to the traction function pointer
00168  void (* &traction_fct_pt())(const Vector<double>& x,
00169                              const Vector<double>& n,
00170                              Vector<double>& traction)
00171   {return Traction_fct_pt;}
00172 
00173 
00174  /// Return the residuals
00175  void fill_in_contribution_to_residuals(Vector<double> &residuals)
00176   {
00177    fill_in_contribution_to_residuals_linear_elasticity_traction(residuals);
00178   }
00179 
00180  
00181 
00182  /// Fill in contribution from Jacobian
00183  void fill_in_contribution_to_jacobian(Vector<double> &residuals,
00184                                    DenseMatrix<double> &jacobian)
00185   {
00186    //Call the residuals
00187    fill_in_contribution_to_residuals_linear_elasticity_traction(residuals);
00188    //Call the generic FD jacobian calculation
00189    //FaceGeometry<ELEMENT>::fill_in_jacobian_from_solid_position_by_fd(jacobian);
00190   }
00191 
00192  /// \short Output function
00193  void output(std::ostream &outfile)
00194   {FiniteElement::output(outfile);}
00195 
00196  /// \short Output function
00197  void output(std::ostream &outfile, const unsigned &n_plot)
00198   {FiniteElement::output(outfile,n_plot);}
00199 
00200  /// \short C_style output function
00201  void output(FILE* file_pt)
00202   {FiniteElement::output(file_pt);}
00203 
00204  /// \short C-style output function
00205  void output(FILE* file_pt, const unsigned &n_plot)
00206   {FiniteElement::output(file_pt,n_plot);}
00207 
00208 
00209  /// \short Compute traction vector at specified local coordinate
00210  /// Should only be used for post-processing; ignores dependence
00211  /// on integration point!
00212  void traction(const Vector<double>& s, 
00213                Vector<double>& traction);
00214 
00215 }; 
00216 
00217 ///////////////////////////////////////////////////////////////////////
00218 ///////////////////////////////////////////////////////////////////////
00219 ///////////////////////////////////////////////////////////////////////
00220 
00221 //=====================================================================
00222 /// Compute traction vector at specified local coordinate
00223 /// Should only be used for post-processing; ignores dependence
00224 /// on integration point!
00225 //=====================================================================
00226 template<class ELEMENT>
00227 void LinearElasticityTractionElement<ELEMENT>::traction(const Vector<double>& s, 
00228                                              Vector<double>& traction)
00229 {
00230  unsigned n_dim = this->nodal_dimension();
00231 
00232  // Position vector
00233  Vector<double> x(n_dim);
00234  interpolated_x(s,x);
00235 
00236  // Outer unit normal
00237  Vector<double> unit_normal(n_dim);
00238  outer_unit_normal(s,unit_normal);
00239 
00240  // Dummy
00241  unsigned ipt=0;
00242 
00243  // Traction vector
00244  get_traction(ipt,x,unit_normal,traction);
00245 
00246 }
00247 
00248  
00249 //=====================================================================
00250 /// Return the residuals for the LinearElasticityTractionElement equations
00251 //=====================================================================
00252 template<class ELEMENT>
00253 void LinearElasticityTractionElement<ELEMENT>::
00254 fill_in_contribution_to_residuals_linear_elasticity_traction(
00255  Vector<double> &residuals)
00256 {
00257  //Find out how many nodes there are
00258  unsigned n_node = nnode();
00259 
00260  //Find out how many positional dofs there are
00261  unsigned n_position_type = this->nnodal_position_type();
00262 
00263 
00264  if(n_position_type != 1)
00265   {
00266    throw OomphLibError(
00267     "LinearElasticity is not yet implemented for more than one position type",
00268     "LinearElasticityEquationsBase<DIM>::get_strain()",
00269     OOMPH_EXCEPTION_LOCATION);
00270   }
00271 
00272 
00273  //Find out the dimension of the node
00274  unsigned n_dim = this->nodal_dimension();
00275 
00276  //Cache the nodal indices at which the displacement components are stored
00277  unsigned u_nodal_index[n_dim];
00278  for(unsigned i=0;i<n_dim;i++)
00279   {
00280    u_nodal_index[i] = this->U_index_linear_elasticity_traction[i];
00281   }
00282 
00283  //Integer to hold the local equation number
00284  int local_eqn=0;
00285    
00286  //Set up memory for the shape functions
00287  //Note that in this case, the number of lagrangian coordinates is always
00288  //equal to the dimension of the nodes
00289  Shape psi(n_node);
00290  DShape dpsids(n_node,n_dim-1); 
00291 
00292  //Set the value of n_intpt
00293  unsigned n_intpt = integral_pt()->nweight();
00294  
00295  //Loop over the integration points
00296  for(unsigned ipt=0;ipt<n_intpt;ipt++)
00297   {
00298    //Get the integral weight
00299    double w = integral_pt()->weight(ipt);
00300    
00301    //Only need to call the local derivatives
00302    dshape_local_at_knot(ipt,psi,dpsids);
00303 
00304    //Calculate the Eulerian and Lagrangian coordinates 
00305    Vector<double> interpolated_x(n_dim,0.0);
00306 
00307    //Also calculate the surface Vectors (derivatives wrt local coordinates)
00308    DenseMatrix<double> interpolated_A(n_dim-1,n_dim,0.0);   
00309   
00310    //Calculate displacements and derivatives
00311    for(unsigned l=0;l<n_node;l++) 
00312     {
00313      //Loop over positional dofs
00314      for(unsigned k=0;k<n_position_type;k++)
00315       {
00316        //Loop over displacement components (deformed position)
00317        for(unsigned i=0;i<n_dim;i++)
00318         {
00319          const double x_local = nodal_position(l,i);
00320          //Calculate the Eulerian and Lagrangian positions
00321          interpolated_x[i] += x_local*psi(l,k);
00322 
00323          //Loop over LOCAL derivative directions, to calculate the tangent(s)
00324          for(unsigned j=0;j<n_dim-1;j++)
00325           {
00326            interpolated_A(j,i) += x_local*dpsids(l,j);
00327           }
00328         }
00329       }
00330     }
00331 
00332    //Now find the local metric tensor from the tangent Vectors
00333    DenseMatrix<double> A(n_dim-1);
00334    for(unsigned i=0;i<n_dim-1;i++)
00335     {
00336      for(unsigned j=0;j<n_dim-1;j++)
00337       {
00338        //Initialise surface metric tensor to zero
00339        A(i,j) = 0.0;
00340        //Take the dot product
00341        for(unsigned k=0;k<n_dim;k++)
00342         { 
00343          A(i,j) += interpolated_A(i,k)*interpolated_A(j,k);
00344         }
00345       }
00346     }
00347 
00348    //Get the outer unit normal
00349    Vector<double> interpolated_normal(n_dim);
00350    outer_unit_normal(ipt,interpolated_normal);
00351    
00352    //Find the determinant of the metric tensor
00353    double Adet =0.0;
00354    switch(n_dim)
00355     {
00356     case 2:
00357      Adet = A(0,0);
00358      break;
00359     case 3:
00360      Adet = A(0,0)*A(1,1) - A(0,1)*A(1,0);
00361      break;
00362     default:
00363      throw 
00364       OomphLibError("Wrong dimension in LinearElasticityTractionElement",
00365                     "LinearElasticityTractionElement::fill_in_contribution_to_residuals()",
00366                     OOMPH_EXCEPTION_LOCATION);
00367     }
00368 
00369    //Premultiply the weights and the square-root of the determinant of 
00370    //the metric tensor
00371    double W = w*sqrt(Adet);
00372 
00373    //Now calculate the load
00374    Vector<double> traction(n_dim);
00375    get_traction(ipt,
00376                 interpolated_x,
00377                 interpolated_normal,
00378                 traction);
00379    
00380    //=====LOAD TERMS  FROM PRINCIPLE OF VIRTUAL DISPLACEMENTS========
00381        
00382    //Loop over the test functions, nodes of the element
00383    for(unsigned l=0;l<n_node;l++)
00384     {
00385      //Loop over the displacement components
00386      for(unsigned i=0;i<n_dim;i++)
00387       {
00388        local_eqn = this->nodal_local_eqn(l,u_nodal_index[i]);
00389          /*IF it's not a boundary condition*/
00390          if(local_eqn >= 0)
00391           {
00392            //Add the loading terms to the residuals
00393            residuals[local_eqn] -= traction[i]*psi(l)*W;
00394           }
00395       } //End of if not boundary condition
00396     } //End of loop over shape functions
00397   } //End of loop over integration points
00398 
00399 }
00400 
00401 
00402 
00403 
00404 
00405 }
00406 
00407 #endif

Generated on Mon Aug 10 11:23:47 2009 by  doxygen 1.4.7