Skip to content
Snippets Groups Projects
Select Git revision
  • 2bcb14e88e5995215a88e1a1ca6a28f30a8e9adb
  • master default
  • dune-tkr-article
  • p/lh188/test-assembler-bug
  • mention-makefunction
  • temp/test-CI-with-subgrid-enabled
  • releases/2.5-1
  • releases/2.4-2
  • improve_grid
  • experimental/test-core-ci
  • feature/dune-functions-assemblers
  • feature/DG-Transferoperator-Assembler
  • debug/functionspacebasistest
  • releases/2.4-1
  • feature/dune-functions-assembler-with-skeleton
  • feature/elastictensor-interface
  • releases/2.3-2
  • maxka/conformingbasis
  • releases/2.3-1
  • subgridassembler-rework
  • releases/2.2-1
  • dune-tkr-article-patched
  • dune-tkr-article-base
  • subversion->git
24 results

surfmassmatrix.hh

Blame
  • Forked from agnumpde / dune-fufem
    Source project has a limited visibility.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    surfmassmatrix.hh 5.20 KiB
    #ifndef SURFACE_MASSMATRIX_HH
    #define SURFACE_MASSMATRIX_HH
    
    #if HAVE_DUNE_DISC
    
    /** \file
        \brief Contains a method which assembles the FE mass matrix of a boundary patch of a grid.
    */
    #include <dune/grid/common/genericreferenceelements.hh>
    #include <dune/grid/common/quadraturerules.hh>
    
    #include <dune/istl/matrix.hh>
    #include <dune/istl/bcrsmatrix.hh>
    #include <dune/istl/matrixindexset.hh>
    
    #include <dune/disc/shapefunctions/lagrangeshapefunctions.hh>
    
    #include "boundarypatch.hh"
    
    template <class GridView, int blocksize>
    void assembleSurfaceMassMatrix(const BoundaryPatchBase<GridView>& boundary,
                                   Dune::BCRSMatrix<Dune::FieldMatrix<double,blocksize,blocksize> >& matrix)
    {
        using namespace Dune;
    
        const int dim = GridView::dimension;
        const GridView& gridView = boundary.gridView();
        const typename GridView::IndexSet& indexSet = gridView.indexSet();
    
        std::vector<int> globalToLocal;
        boundary.makeGlobalToLocal(globalToLocal);
    
        // /////////////////////////////////////////////////
        //   Compute matrix occupation structure
        // /////////////////////////////////////////////////
    
        MatrixIndexSet indices(boundary.numVertices(), boundary.numVertices());
    
        typename BoundaryPatchBase<GridView>::iterator it    = boundary.begin();
        typename BoundaryPatchBase<GridView>::iterator endIt = boundary.end();
    
        for (; it!=endIt; ++it) {
    
            const GenericReferenceElement<double,dim>& refElement = GenericReferenceElements<double, dim>::general(it->inside()->type());
            int nDofs = refElement.size(it->indexInInside(),1,dim);
            
            for (int i=0; i<nDofs; i++) {
                int faceIdxi = refElement.subEntity(it->indexInInside(), 1, i, dim);
                int globalRow = globalToLocal[indexSet.subIndex(*it->inside(), faceIdxi, dim)];
                
                for (int j=0; j<nDofs; j++) {
                    int faceIdxj = refElement.subEntity(it->indexInInside(), 1, j, dim);
                    int globalCol = globalToLocal[indexSet.subIndex(*it->inside(), faceIdxj, dim)];
                    
                    indices.add(globalRow,globalCol);
                    
                }
                
            } 
    
        }
    
    
        // /////////////////////////////////////////////////
        //   Compute matrix values
        // /////////////////////////////////////////////////
    
        indices.exportIdx(matrix);
        matrix = 0;
    
        for (it=boundary.begin(); it!=endIt; ++it) {
    
            const typename BoundaryPatchBase<GridView>::iterator::Intersection::Geometry& segmentGeometry = it->geometry();
    
                const GenericReferenceElement<double,dim>& refElement = GenericReferenceElements<double, dim>::general(it->inside()->type());
                int nDofs = refElement.size(it->indexInInside(),1,dim);
    
                // Local matrix
                Matrix<FieldMatrix<double,1,1> > scalarMat(nDofs, nDofs);
                scalarMat = 0;
    
                int quadOrder = 2*dim;
    
                // Get quadrature rule
                const QuadratureRule<double, dim-1>& quad = QuadratureRules<double, dim-1>::rule(segmentGeometry.type(), quadOrder);
    
                // Get set of shape functions on this segment
                // TODO: We should really use the new shape functions here, since we use the new
                // local indices below!!! This only works since intervall, triangle and square nodes numbering
                // remains the same.
                const typename LagrangeShapeFunctionSetContainer<double,double,dim-1>::value_type& sfs
                    = LagrangeShapeFunctions<double,double,dim-1>::general(segmentGeometry.type(),1);
    
                /* Loop over all integration points */
                for (int ip=0; ip<quad.size(); ip++) {
                    
                    // Local position of the quadrature point
                    const FieldVector<double,dim-1>& quadPos = quad[ip].position();
                    
                    const double integrationElement = segmentGeometry.integrationElement(quadPos);
    
                    // Evaluate base functions
                    double v[nDofs];
    
                    for(int i=0; i<nDofs; i++)
                        v[i] = sfs[i].evaluateFunction(0,quadPos);
    
                    for(int i=0; i<nDofs; i++) 
                        for (int j=0; j<=i; j++ ) 
                            scalarMat[i][j] += ( v[i] * v[j] ) * quad[ip].weight() * integrationElement;
                
                }
    
                // Make the matrix symmetric
                for(int i=0; i<nDofs; i++)
                    for (int j=nDofs-1; j>i; j--)
                        scalarMat[i][j] = scalarMat[j][i];
    
                for (int i=0; i<nDofs; i++) {
                    int faceIdxi = refElement.subEntity(it->indexInInside(), 1, i, dim);
                    int globalRow = globalToLocal[indexSet.subIndex(*it->inside(), faceIdxi, dim)];
                    
                    for (int j=0; j<nDofs; j++) {
                        int faceIdxj = refElement.subEntity(it->indexInInside(), 1, j, dim);
                        int globalCol = globalToLocal[indexSet.subIndex(*it->inside(), faceIdxj, dim)];
    
                        for (int k=0; k<blocksize; k++)
                            matrix[globalRow][globalCol][k][k] += scalarMat[i][j];
    
                    }
    
                } 
    
        }
    
    }
    
    #else 
        #warning surfmassmatrix.hh was included but dune-disc is not present !
    #endif // end of #if HAVE_DUNE_DISC
    
    #endif