#ifndef NEO_HOOKE_OPERATOR_ASSEMBLER_HH #define NEO_HOOKE_OPERATOR_ASSEMBLER_HH #include #include #include #include #include #include #include #include #include /** \brief Assemble the second derivative of a neo-hookean material. * * Laursen: * \f[ * W(u)= \frac{\lambda}4(J^2-1)-(\frac{\lambda}2+\mu)log(J)+\mu tr(E(u)) * \f] * * Fischer/Wriggers: * \f[ * W(u)= \frac{\lambda}2(J-1)^2-2\mu)log(J)+\mu tr(E(u)) * \f] * * * - \f$D\varphi\f$: the deformation gradient * - \f$E\f$: the nonlinear strain tensor * - \f$E'_u(v)\f$: the linearized strain tensor at the point u in direction v * - \f$\sigma(u) = C:E(u)\f$: the second Piola-Kirchhoff stress tensor * - \f$C\f$: the Hooke tensor * - \f$Dv\f$: the gradient of the test function * */ template class NeoHookeOperatorAssembler : public LocalOperatorAssembler < GridType, TrialLocalFE, AnsatzLocalFE, Dune::FieldMatrix > { static const int dim = GridType::dimension; typedef typename GridType::ctype ctype; typedef VirtualGridFunction > GridFunction; public: typedef typename Dune::FieldMatrix T; typedef typename LocalOperatorAssembler < GridType, TrialLocalFE, AnsatzLocalFE, T >::Element Element; typedef typename LocalOperatorAssembler < GridType, TrialLocalFE, AnsatzLocalFE,T >::BoolMatrix BoolMatrix; typedef typename LocalOperatorAssembler < GridType, TrialLocalFE, AnsatzLocalFE,T >::LocalMatrix LocalMatrix; NeoHookeOperatorAssembler(ctype lambda, ctype mu, const Dune::shared_ptr displacement): lambda_(lambda), mu_(mu), displacement_(displacement) {} NeoHookeOperatorAssembler(ctype lambda, ctype mu): lambda_(lambda), mu_(mu) {} void indices(const Element& element, BoolMatrix& isNonZero, const TrialLocalFE& tFE, const AnsatzLocalFE& aFE) const { isNonZero = true; } void assemble(const Element& element, LocalMatrix& localMatrix, const TrialLocalFE& tFE, const AnsatzLocalFE& aFE) const { typedef Dune::FieldVector FVdim; typedef Dune::FieldMatrix FMdimdim; typedef typename TrialLocalFE::Traits::LocalBasisType::Traits::JacobianType JacobianType; int rows = tFE.localBasis().size(); int cols = aFE.localBasis().size(); localMatrix.setSize(rows,cols); localMatrix = 0.0; // get quadrature rule const int order = (element.type().isSimplex()) ? 4*(tFE.localBasis().order()) : 4*(tFE.localBasis().order()*dim); const Dune::template QuadratureRule& quad = QuadratureRuleCache::rule(element.type(), order, IsRefinedLocalFiniteElement::value(tFE) ); // store gradients of shape functions and base functions std::vector referenceGradients(tFE.localBasis().size()); std::vector gradients(tFE.localBasis().size()); // store entity geometry mapping const typename Element::Geometry geometry = element.geometry(); // loop over quadrature points for (size_t pt=0; pt < quad.size(); ++pt) { // get quadrature point const FVdim& quadPos = quad[pt].position(); // get transposed inverse of Jacobian of transformation const FMdimdim& invJacobian = geometry.jacobianInverseTransposed(quadPos); // get integration factor const ctype integrationElement = geometry.integrationElement(quadPos); // get gradients of shape functions tFE.localBasis().evaluateJacobian(quadPos, referenceGradients); // compute gradients of base functions for (size_t i=0; iisDefinedOn(element)) displacement_->evaluateDerivativeLocal(element, quadPos, localConfGrad); else displacement_->evaluateDerivative(geometry.global(quadPos),localConfGrad); // compute linearization of the determinante of the deformation gradient FMdimdim linDefDet; Dune::Elasticity::linearisedDefDet(localConfGrad,linDefDet); // compute deformation gradient of the configuration for (int i=0;i newConfig) { displacement_ = newConfig; } private: /** \brief Lame constant */ ctype lambda_; /** \brief Lame constant */ ctype mu_; /** \brief The configuration at which the linearized operator is evaluated.*/ Dune::shared_ptr displacement_; /** \brief Compute the matrix entry that arises from the second derivative of the determinant. * Note that it is assumed the defGrad is the deformation gradient and not the displacement gradient */ Dune::FieldMatrix hessDefDet(const Dune::FieldMatrix& defGrad, const Dune::FieldVector& testGrad, const Dune::FieldVector& ansatzGrad) const { Dune::FieldMatrix res(0); if (dim==2) { res[0][1] = testGrad[0]*ansatzGrad[1]-ansatzGrad[0]*testGrad[1]; res[1][0] = -res[0][1]; return res; } //compute the cross product Dune::FieldVector cross(0); for (int k=0; k for (int i=0; i