Skip to content
Snippets Groups Projects
Select Git revision
  • 35b9cf4c8622f0136f0367e9f24b6d7b51b74159
  • master default
  • mooney-rivlin-zero
  • enable-linear-elasticity
  • releases/2.8
  • patrizio-convexity-test
  • relaxed-micromorphic-continuum
  • fix/comment
  • fix/mooney-rivlin-parameter
  • fix/hyperdual
  • feature/move-to-dune-functions-bases
  • releases/2.7
  • releases/2.6-1
  • releases/2.5-1
  • releases/2.4-1
  • releases/2.3-1
  • releases/2.2-1
  • releases/2.1-1
  • releases/2.0-1
  • subversion->git
20 results

feassembler.hh

Blame
  • user avatar
    Oliver Sander authored
    This code (with exceptions) really belongs into the dune-elasticity module.  It was in dune-gfe
    only for historical reasons.  This patch brings a driver program finite-strain-elasticity,
    a simple trust-region solver, and several new hyperelastic energies.
    
    Unfortunately, this patch is far from perfect:
    - It does not use Jonny's framework, but duplicates a lot of things.
      In particular my code that interfaces with adol-c exists in similar
      form already.  The two should be merged eventually.  Apologies.
    - Same for the material definitions
    - The trust region solver should be in dune-solvers.  However, it currently
      calls the FE assemblers, which should not be done within dune-solvers.
    
    I intend to address these issues eventually.  However, right now I need to do
    at least the first step and get the stuff out of dune-gfe.
    
    This is the first code in this module that uses the new dune-functions module.
    35b9cf4c
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    feassembler.hh 5.64 KiB
    #ifndef DUNE_ELASTICITY_ASSEMBLERS_FEASSEMBLER_HH
    #define DUNE_ELASTICITY_ASSEMBLERS_FEASSEMBLER_HH
    
    #include <dune/istl/bcrsmatrix.hh>
    #include <dune/common/fmatrix.hh>
    #include <dune/istl/matrixindexset.hh>
    #include <dune/istl/matrix.hh>
    
    #include "localfestiffness.hh"
    
    
    /** \brief A global FE assembler for problems involving functions that map into non-Euclidean spaces
     */
    template <class Basis, class VectorType>
    class FEAssembler {
    
        typedef typename Basis::GridView GridView;
        typedef typename GridView::template Codim<0>::template Partition<Dune::Interior_Partition>::Iterator ElementIterator;
    
        //! Dimension of the grid.
        enum { gridDim = GridView::dimension };
    
        //! Dimension of a tangent space
        enum { blocksize = VectorType::value_type::dimension };
    
        //!
        typedef Dune::FieldMatrix<double, blocksize, blocksize> MatrixBlock;
    
    public:
        const Basis basis_;
    
    protected:
    
        LocalFEStiffness<GridView,
                                 typename Basis::LocalFiniteElement,
                                 VectorType>* localStiffness_;
    
    public:
    
        /** \brief Constructor for a given grid */
        FEAssembler(const Basis& basis,
                    LocalFEStiffness<GridView,typename Basis::LocalFiniteElement, VectorType>* localStiffness)
            : basis_(basis),
              localStiffness_(localStiffness)
        {}
    
        /** \brief Assemble the tangent stiffness matrix and the functional gradient together
         *
         * This is more efficient than computing them separately, because you need the gradient
         * anyway to compute the Riemannian Hessian.
         */
        virtual void assembleGradientAndHessian(const VectorType& sol,
                                                Dune::BlockVector<Dune::FieldVector<double, blocksize> >& gradient,
                                                Dune::BCRSMatrix<MatrixBlock>& hessian,
                                                bool computeOccupationPattern=true) const;
    
        /** \brief Compute the energy of a deformation state */
        virtual double computeEnergy(const VectorType& sol) const;
    
        //protected:
        void getNeighborsPerVertex(Dune::MatrixIndexSet& nb) const;
    
    }; // end class
    
    
    
    template <class Basis, class TargetSpace>
    void FEAssembler<Basis,TargetSpace>::
    getNeighborsPerVertex(Dune::MatrixIndexSet& nb) const
    {
        int n = basis_.size();
    
        nb.resize(n, n);
    
        ElementIterator it    = basis_.getGridView().template begin<0,Dune::Interior_Partition>();
        ElementIterator endit = basis_.getGridView().template end<0,Dune::Interior_Partition>  ();
    
        for (; it!=endit; ++it) {
    
            const typename Basis::LocalFiniteElement& lfe = basis_.getLocalFiniteElement(*it);
    
            for (size_t i=0; i<lfe.localBasis().size(); i++) {
    
                for (size_t j=0; j<lfe.localBasis().size(); j++) {
    
                    int iIdx = basis_.index(*it,i);
                    int jIdx = basis_.index(*it,j);
    
                    nb.add(iIdx, jIdx);
    
                }
    
            }
    
        }
    
    }
    
    template <class Basis, class VectorType>
    void FEAssembler<Basis,VectorType>::
    assembleGradientAndHessian(const VectorType& sol,
                               Dune::BlockVector<Dune::FieldVector<double, blocksize> >& gradient,
                               Dune::BCRSMatrix<MatrixBlock>& hessian,
                               bool computeOccupationPattern) const
    {
        if (computeOccupationPattern) {
    
            Dune::MatrixIndexSet neighborsPerVertex;
            getNeighborsPerVertex(neighborsPerVertex);
            neighborsPerVertex.exportIdx(hessian);
    
        }
    
        hessian = 0;
    
        gradient.resize(sol.size());
        gradient = 0;
    
        ElementIterator it    = basis_.getGridView().template begin<0,Dune::Interior_Partition>();
        ElementIterator endit = basis_.getGridView().template end<0,Dune::Interior_Partition>  ();
    
        for( ; it != endit; ++it ) {
    
            const int numOfBaseFct = basis_.getLocalFiniteElement(*it).localBasis().size();
    
            // Extract local solution
            VectorType localSolution(numOfBaseFct);
            VectorType localPointLoads(numOfBaseFct);
    
            for (int i=0; i<numOfBaseFct; i++)
                localSolution[i]   = sol[basis_.index(*it,i)];
    
            VectorType localGradient(numOfBaseFct);
    
            // setup local matrix and gradient
            localStiffness_->assembleGradientAndHessian(*it, basis_.getLocalFiniteElement(*it), localSolution, localGradient);
    
            // Add element matrix to global stiffness matrix
            for(int i=0; i<numOfBaseFct; i++) {
    
                int row = basis_.index(*it,i);
    
                for (int j=0; j<numOfBaseFct; j++ ) {
    
                    int col = basis_.index(*it,j);
                    hessian[row][col] += localStiffness_->A_[i][j];
    
                }
            }
    
            // Add local gradient to global gradient
            for (int i=0; i<numOfBaseFct; i++)
                gradient[basis_.index(*it,i)] += localGradient[i];
    
        }
    
    }
    
    
    template <class Basis, class VectorType>
    double FEAssembler<Basis, VectorType>::
    computeEnergy(const VectorType& sol) const
    {
        double energy = 0;
    
        if (sol.size()!=basis_.size())
            DUNE_THROW(Dune::Exception, "Solution vector doesn't match the basis!");
    
        ElementIterator it    = basis_.getGridView().template begin<0,Dune::Interior_Partition>();
        ElementIterator endIt = basis_.getGridView().template end<0,Dune::Interior_Partition>();
    
        // Loop over all elements
        for (; it!=endIt; ++it) {
    
            // Number of degrees of freedom on this element
            size_t nDofs = basis_.getLocalFiniteElement(*it).localBasis().size();
    
            VectorType localSolution(nDofs);
    
            for (size_t i=0; i<nDofs; i++)
                localSolution[i]   = sol[basis_.index(*it,i)];
    
            energy += localStiffness_->energy(*it, basis_.getLocalFiniteElement(*it), localSolution);
    
        }
    
        return energy;
    
    }
    #endif