<commit_before>/** @file gsVisitorMass.h

    @brief Mass visitor for assmbling element mass matrix

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): <NAME>
*/

#pragma once

namespace gismo
{


/** 
    @brief The visitor computes element mass integrals
*/
template <class T>
class gsVisitorMass
{
public:

    gsVisitorMass()
    { }

    static void initialize(const gsBasis<T> & basis, 
                           gsQuadRule<T> & rule, 
                           unsigned & evFlags )
    {
        gsVector<index_t> numQuadNodes( basis.dim() );
        for (int i = 0; i < basis.dim(); ++i)
            numQuadNodes[i] = basis.degree(i) + 1;
        
        // Setup Quadrature
        rule = gsGaussRule<T>(numQuadNodes);// harmless slicing occurs here

        // Set Geometry evaluation flags
        evFlags = NEED_VALUE|NEED_MEASURE;
    }


    // Evaluate on element.
    inline void evaluate(gsBasis<T> const       & basis, // to do: more unknowns
                         gsGeometryEvaluator<T> & geoEval,
                         // todo: add element here for efficiency
                         gsMatrix<T>            & quNodes)
    {
        // Compute the active basis functions
        // Assumes actives are the same for all quadrature points on the current element
        basis.active_into(quNodes.col(0) , actives);
        const index_t numActive = actives.rows();
 
        // Evaluate basis functions on element
        basis.eval_into(quNodes, basisData);

        // Compute geometry related values
        geoEval.evaluateAt(quNodes);

        // Initialize local matrix/rhs
        localMat.resize(numActive, numActive);
        localMat.setZero();
    }

    inline void assemble(gsDomainIterator<T>    & element, 
                         gsGeometryEvaluator<T> & geoEval,
                         gsVector<T> const      & quWeights)
    {
        for (index_t k = 0; k < quWeights.rows(); ++k) // loop over quadrature nodes
        {
            // Multiply quadrature weight by the geometry measure
            const T weight = quWeights[k] * geoEval.measure(k);
        
            localMat.noalias() += weight * ( basisData.col(k) * basisData.col(k).transpose() );
        }
    }
    
    void localToGlobal(const gsDofMapper     & mapper,
                       const gsMatrix<T>     & eliminatedDofs,
                       const int               patchIndex,
                       gsSparseMatrix<T>     & sysMatrix,
                       gsMatrix<T>           & rhsMatrix )
    {
        mapper.localToGlobal(actives, patchIndex, actives);

        const index_t numActive = actives.rows();

        for (index_t i = 0; i < numActive; ++i)
        {
            const int ii = actives(i,0); // N_i
            
            if ( mapper.is_free_index(ii) )
            {
                for (index_t j = 0; j < numActive; ++j)
                {
                    const int jj = actives(j,0); // N_j
                    if ( mapper.is_free_index(jj) )
                        if ( jj <= ii ) // only store lower triangular part
                            sysMatrix.coeffRef(ii, jj) += localMat(i, j); // N_i*N_j
                }
            }
        }
    }

protected:

    // Basis values
    gsMatrix<T>      basisData;
    gsMatrix<unsigned> actives;

    // Local matrix
    gsMatrix<T> localMat;
};


} // namespace gismo

<commit_msg>test commit<commit_after>/** @file gsVisitorMass.h

    @brief Mass visitor for assmbling element mass matrix

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): <NAME>
*/

#pragma once

namespace gismo
{


/** 
    @brief The visitor computes element mass integrals
*/
template <class T>
class gsVisitorMass
{
public:

    gsVisitorMass()
    { }

    static void initialize(const gsBasis<T> & basis, 
                           gsQuadRule<T> & rule, 
                           unsigned & evFlags )
    {
        gsVector<index_t> numQuadNodes( basis.dim() );
        for (int i = 0; i < basis.dim(); ++i)
            numQuadNodes[i] = basis.degree(i) + 1;
        
        // Setup Quadrature
        rule = gsGaussRule<T>(numQuadNodes);// harmless slicing occurs here

        // Set Geometry evaluation flags
        evFlags = NEED_VALUE|NEED_MEASURE;
    }

    // Evaluate on element.
    inline void evaluate(gsBasis<T> const       & basis, // to do: more unknowns
                         gsGeometryEvaluator<T> & geoEval,
                         // todo: add element here for efficiency
                         gsMatrix<T>            & quNodes)
    {
        // Compute the active basis functions
        // Assumes actives are the same for all quadrature points on the current element
        basis.active_into(quNodes.col(0) , actives);
        const index_t numActive = actives.rows();
 
        // Evaluate basis functions on element
        basis.eval_into(quNodes, basisData);

        // Compute geometry related values
        geoEval.evaluateAt(quNodes);

        // Initialize local matrix/rhs
        localMat.setZero(numActive, numActive);
    }

    inline void assemble(gsDomainIterator<T>    & element, 
                         gsGeometryEvaluator<T> & geoEval,
                         gsVector<T> const      & quWeights)
    {
        for (index_t k = 0; k < quWeights.rows(); ++k) // loop over quadrature nodes
        {
            // Multiply quadrature weight by the geometry measure
            const T weight = quWeights[k] * geoEval.measure(k);
        
            localMat.noalias() += weight * ( basisData.col(k) * basisData.col(k).transpose() );
        }
    }
    
    void localToGlobal(const gsDofMapper     & mapper,
                       const gsMatrix<T>     & eliminatedDofs,
                       const int               patchIndex,
                       gsSparseMatrix<T>     & sysMatrix,
                       gsMatrix<T>           & rhsMatrix )
    {
        mapper.localToGlobal(actives, patchIndex, actives);

        const index_t numActive = actives.rows();

        for (index_t i = 0; i < numActive; ++i)
        {
            const int ii = actives(i,0); // N_i
            
            if ( mapper.is_free_index(ii) )
            {
                for (index_t j = 0; j < numActive; ++j)
                {
                    const int jj = actives(j,0); // N_j
                    if ( mapper.is_free_index(jj) )
                        if ( jj <= ii ) // only store lower triangular part
                            sysMatrix.coeffRef(ii, jj) += localMat(i, j); // N_i*N_j
                }
            }
        }
    }

protected:

    // Basis values
    gsMatrix<T>      basisData;
    gsMatrix<unsigned> actives;

    // Local matrix
    gsMatrix<T> localMat;
};


} // namespace gismo


{'fraction_non_alphanumeric': 0.09445528002229032, 'fraction_numerical': 0.0033435497353023124, 'mean_word_length': 1.5666785841973543, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4205208', 'n_tokens_mistral': 2164, 'n_tokens_neox': 2023, 'n_words': 568}