diff --git a/dune/elasticity/materials/Makefile.am b/dune/elasticity/materials/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..009170c3865ed1863e12dcc283b7f37445c29a18 --- /dev/null +++ b/dune/elasticity/materials/Makefile.am @@ -0,0 +1,8 @@ +SUBDIRS = + +materialsdir = $(includedir)/dune/elasticity/materials + +materials_HEADERS = geomexactstvenantkirchhoffmaterial.hh + +include $(top_srcdir)/am/global-rules + diff --git a/dune/elasticity/materials/geomexactstvenantkirchhoffmaterial.hh b/dune/elasticity/materials/geomexactstvenantkirchhoffmaterial.hh new file mode 100644 index 0000000000000000000000000000000000000000..309f8bd93a371c0a5a7c5c7d4469deceab5d65b1 --- /dev/null +++ b/dune/elasticity/materials/geomexactstvenantkirchhoffmaterial.hh @@ -0,0 +1,159 @@ +#ifndef GEOMETRICALLY_EXACT_ST_VENANT_KIRCHHOFF_MATERIAL +#define GEOMETRICALLY_EXACT_ST_VENANT_KIRCHHOFF_MATERIAL + +#include <dune/fufem/functiontools/quadraturerulecache.hh> + +#include <dune/fufem/symmetrictensor.hh> +#include <dune/fufem/functions/virtualgridfunction.hh> + +#include <dune/fufem/assemblers/localassemblers/geononlinstvenantfunctionalassembler.hh> +#include <dune/fufem/assemblers/localassemblers/geononlinlinearizedstvenantassembler.hh> + +/* \brief Class representing a hyperelastic geometrically exact St.Venant Kirchhoff material. + * + * \tparam Basis Global basis that is used for the spatial discretization. + * (This is not nice but I need a LocalFiniteElement for the local Hessian assembler :-( ) +*/ +template <class Basis> +class GeomExactStVenantMaterial +{ + typedef typename Basis::GridView::Grid GridType; + typedef typename GridType::ctype ctype; + + static const int dim = GridType::dimension; + static const int dimworld = GridType::dimensionworld; + + typedef typename Basis::LocalFiniteElement Lfe; + + typedef VirtualGridFunction<GridType, Dune::FieldVector<double,GridType::dimension> > GridFunction; + typedef typename GridType::template Codim<0>::Geometry::LocalCoordinate LocalCoordinate; + typedef typename GridType::template Codim<0>::LeafIterator ElementIterator; + +public: + typedef GeomNonlinElasticityFunctionalAssembler<GridType> LocalLinearization; + typedef GeomNonlinLinearizedStVenantAssembler<GridType, Lfe, Lfe> LocalHessian; + + GeomExactStVenantMaterial(const Basis& basis, ctype E, ctype nu) : + localLinearization_(E,nu), + localHessian_(E,nu), + basis_(basis), + E_(E), + nu_(nu) + {} + + //! Evaluate the strain energy + template <class CoeffType> + ctype energy(const CoeffType& coeff) + { + // make grid function + BasisGridFunction<Basis,CoeffType> configuration(basis_,coeff); + + ctype energy=0; + const GridType& grid = configuration.grid(); + + ElementIterator eIt = grid.template leafbegin<0>(); + ElementIterator eItEnd = grid.template leafend<0>(); + + for (;eIt != eItEnd; ++eIt) { + + // get quadrature rule + QuadratureRuleKey quad1(basis_.getLocalFiniteElement(*eIt)); + QuadratureRuleKey quadKey = quad1.derivative().square().square(); + + const Dune::template QuadratureRule<ctype, dim>& quad = QuadratureRuleCache<ctype, dim>::rule(quadKey); + + // loop over quadrature points + for (size_t pt=0; pt < quad.size(); ++pt) { + + // get quadrature point + const LocalCoordinate& quadPos = quad[pt].position(); + + // get integration factor + const ctype integrationElement = eIt->geometry().integrationElement(quadPos); + + // evaluate displacement gradient at the quadrature point + typename GridFunction::DerivativeType localConfGrad; + + if (configuration.isDefinedOn(*eIt)) + configuration.evaluateDerivativeLocal(*eIt, quadPos, localConfGrad); + else + configuration.evaluateDerivative(eIt->geometry().global(quadPos),localConfGrad); + + // Compute the nonlinear strain tensor from the deformation gradient + SymmetricTensor<dim> strain; + computeStrain(localConfGrad,strain); + + // and the stress + SymmetricTensor<dim> stress = hookeTimesStrain(strain); + + ctype z = quad[pt].weight()*integrationElement; + energy += (stress*strain)*z; + + } + } + + return 0.5*energy; + } + + //! Return the local assembler of the first derivative of the strain energy + LocalLinearization& firstDerivative() {return localLinearization_;} + + //! Return the local assembler of the second derivative of the strain energy + LocalHessian& secondDerivative() {return localHessian_;} + +private: + //! First derivative of the strain energy + LocalLinearization localLinearization_; + + //! Second derivative of the strain energy + LocalHessian localHessian_; + + //! Global basis used for the spatial discretization + const Basis& basis_; + + //! Elasticity modulus + const ctype E_; + //! Poisson ratio + const ctype nu_; + + + //! Compute nonlinear strain tensor from the deformation gradient. + void computeStrain(const Dune::FieldMatrix<ctype, dim, dim>& grad, SymmetricTensor<dim>& strain) const { + strain = 0; + for (int i=0; i<dim ; ++i) { + strain(i,i) +=grad[i][i]; + + for (int k=0;k<dim;++k) + strain(i,i) += 0.5*grad[k][i]*grad[k][i]; + + for (int j=i+1; j<dim; ++j) { + strain(i,j) += 0.5*(grad[i][j] + grad[j][i]); + for (int k=0;k<dim;++k) + strain(i,j) += 0.5*grad[k][i]*grad[k][j]; + } + } + } + + //! Compute linear elastic stress from the strain + SymmetricTensor<dim> hookeTimesStrain(const SymmetricTensor<dim>& strain) const { + + SymmetricTensor<dim> stress = strain; + stress *= E_/(1+nu_); + + // Compute the trace of the strain + ctype trace = 0; + for (int i=0; i<dim; i++) + trace += strain(i,i); + + ctype f = E_*nu_ / ((1+nu_)*(1-2*nu_)) * trace; + + for (int i=0; i<dim; i++) + stress(i,i) += f; + + return stress; + } + + +}; + +#endif