<commit_before>#ifndef DUNE_DIRICHLETCONSTRAINTS_HH
#define DUNE_DIRICHLETCONSTRAINTS_HH

#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/discretefunction/projection/heterogenous.hh>

#include <dune/fem/function/common/scalarproducts.hh>
#include <dune/multiscale/common/traits.hh>
#include <dune/multiscale/msfem/msfem_traits.hh>
#include <dune/multiscale/problems/selector.hh>

namespace Dune {
namespace Multiscale {

template <class DomainSpace, class RangeSpace = DomainSpace>
class DirichletConstraints {
public:
  typedef Dune::Stuff::GridboundaryInterface<typename DomainSpace::GridType::LeafGridView> BoundaryType;
  typedef DomainSpace DomainSpaceType;
  typedef RangeSpace RangeSpaceType;

  //! type of grid partition
  typedef typename DomainSpaceType::GridPartType GridPartType;
  //! type of grid
  typedef typename DomainSpaceType::GridType GridType;

  // types for boundary treatment
  // ----------------------------
  typedef typename DomainSpaceType::MapperType MapperType;
  typedef Fem::SlaveDofs<DomainSpaceType, MapperType> SlaveDofsType;
  typedef typename SlaveDofsType::SingletonKey SlaveDofsKeyType;
  typedef Fem::SingletonList<SlaveDofsKeyType, SlaveDofsType> SlaveDofsProviderType;

  DirichletConstraints(const BoundaryType& boundary, const DomainSpaceType& domain_space)
    : boundary_(boundary)
    , domain_space_(domain_space)
    , slaveDofs_(getSlaveDofs(domain_space_))
    , dirichletBlocks_()
    // mark DoFs on the Dirichlet boundary
    , hasDirichletDofs_(false)
    , sequence_(-1) {}

  /*! treatment of Dirichlet-DoFs for given discrete function
   *
   *   \note A LagrangeDomainSpace is implicitly assumed.
   *
   *   \param[in]  u   discrete function providing the constraints
   *   \param[out] w   discrete function the constraints are applied to
   */
  template <class DiscreteFunctionType>
  void operator()(const DiscreteFunctionType& u, DiscreteFunctionType& w) const {
    updateDirichletDofs();

    // if Dirichlet Dofs have been found, treat them
    if (hasDirichletDofs_) {
      typedef typename DiscreteFunctionType::ConstDofIteratorType ConstDofIteratorType;

      ConstDofIteratorType uIt = u.dbegin();
      auto wIt = w.dbegin();

      constexpr auto localBlockSize = DiscreteFunctionType::DiscreteFunctionSpaceType::localBlockSize;
      // loop over all blocks
      for (auto blockDof : DSC::valueRange(u.space().blockMapper().size())) {
        if (dirichletBlocks_[blockDof]) {
          // copy dofs of the block
          for (unsigned int l = 0; l < localBlockSize; ++l, ++wIt, ++uIt) {
            assert(uIt != u.dend());
            assert(wIt != w.dend());
            (*wIt) = (*uIt);
          }
        } else {
          // increase dof iterators anyway
          for (unsigned int l = 0; l < localBlockSize; ++l, ++wIt, ++uIt) {
          }
        }
      }
    }
  }

  /*! treatment of Dirichlet-DoFs for given discrete function
 *
 *   \note A LagrangeDomainSpace is implicitly assumed.
 *
 *   \param[in]  val a value that will be used to set all dirichlet dofs
 *   \param[out] w   discrete function the constraints are applied to
 */
  template <class DiscreteFunctionType>
  void setValue(const typename DiscreteFunctionType::RangeFieldType val, DiscreteFunctionType& w) const {
    updateDirichletDofs();

    // if Dirichlet Dofs have been found, treat them
    if (hasDirichletDofs_) {
      auto wIt = w.dbegin();

      const auto localBlockSize = DiscreteFunctionType::DiscreteFunctionSpaceType::localBlockSize;
      // loop over all blocks
      const auto blocks = w.space().blockMapper().size();
      for (unsigned int blockDof = 0; blockDof < blocks; ++blockDof) {
        if (dirichletBlocks_[blockDof]) {
          // copy dofs of the block
          for (unsigned int l = 0; l < localBlockSize; ++l, ++wIt) {
            assert(wIt != w.dend());
            (*wIt) = val;
          }
        } else {
          // increase dof iterators anyway
          for (unsigned int l = 0; l < localBlockSize; ++l, ++wIt) {
          }
        }
      }
    }
  }

  /*! treatment of Dirichlet-DoFs for given discrete function
   *
   *   \note A LagrangeDomainSpace is implicitly assumed.
   *
   *   \param[in]  u   discrete function providing the constraints
   *   \param[out] w   discrete function the constraints are applied to
   */
  template <class GridFunctionType, class DiscreteFunctionType>
  void operator()(const GridFunctionType& u, DiscreteFunctionType& w) const {
    apply(u, w);
  }

  /*! treatment of Dirichlet-DoFs for solution and right-hand-side
   *
   *   delete rows for dirichlet-DoFs, setting diagonal element to 1.
   *
   *   \note A LagrangeDomainSpace is implicitly assumed.
   *
   *   \param[out] linearOperator  linear operator to be adjusted
   */
  template <class LinearOperator>
  void applyToOperator(LinearOperator& linearOperator) const {
    updateDirichletDofs();
    // if Dirichlet Dofs have been found, treat them
    if (hasDirichletDofs_) {
      for (const auto& entity : domain_space_) {
        // adjust linear operator
        dirichletDofsCorrectOnEntity(linearOperator, entity);
      }
    }
  }

protected:
  template <class GridFunctionType, class DiscreteFunctionType>
  void apply(const GridFunctionType& u, DiscreteFunctionType& w) const {
    updateDirichletDofs();
    // if Dirichlet Dofs have been found, treat them
    if (hasDirichletDofs_) {
      for (const auto& entity : domain_space_) {
        dirichletDofTreatment(entity, u, w);
      }
    }
  }

  /*! treatment of Dirichlet-DoFs for one entity
   *
   *   delete rows for dirichlet-DoFs, setting diagonal element to 1.
   *
   *   \note A LagrangeDomainSpace is implicitly assumed.
   *
   *   \param[in]  entity  entity to perform Dirichlet treatment on
   */
  template <class LinearOperator, class EntityType>
  void dirichletDofsCorrectOnEntity(LinearOperator& linearOperator, const EntityType& entity) const {
    // get slave dof structure (for parallel runs)   /*@LST0S@*/
    auto& slave_dofs = this->slaveDofs();
    const auto numSlaveDofs = slave_dofs.size();
    const auto& lagrangePointSet = domain_space_.lagrangePointSet(entity);
    LocalMatrixType localMatrix = linearOperator.localMatrix(entity, entity);

    // get number of basis functions
    const auto localBlocks = lagrangePointSet.size();
    const auto localBlockSize = DomainSpaceType::localBlockSize;

    // map local to global dofs
    std::vector<std::size_t> globalDofs(localBlockSize);
    std::vector<std::size_t> globalBlockDofs(localBlocks);

    domain_space_.mapper().map(entity, globalDofs);
    domain_space_.blockMapper().map(entity, globalBlockDofs);

    // counter for all local dofs (i.e. localBlockDof * localBlockSize + ... )
    int localDof = 0;<commit_msg>fix for acaa34d4089d195b853726e7db48a24f59adc583<commit_after>#ifndef DUNE_DIRICHLETCONSTRAINTS_HH
#define DUNE_DIRICHLETCONSTRAINTS_HH

#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/discretefunction/projection/heterogenous.hh>

#include <dune/fem/function/common/scalarproducts.hh>
#include <dune/multiscale/common/traits.hh>
#include <dune/multiscale/msfem/msfem_traits.hh>
#include <dune/multiscale/problems/selector.hh>

namespace Dune {
namespace Multiscale {

template <class DomainSpace, class RangeSpace = DomainSpace>
class DirichletConstraints {
public:
  typedef Dune::Stuff::GridboundaryInterface<typename DomainSpace::GridType::LeafGridView> BoundaryType;
  typedef DomainSpace DomainSpaceType;
  typedef RangeSpace RangeSpaceType;

  //! type of grid partition
  typedef typename DomainSpaceType::GridPartType GridPartType;
  //! type of grid
  typedef typename DomainSpaceType::GridType GridType;

  // types for boundary treatment
  // ----------------------------
  typedef typename DomainSpaceType::MapperType MapperType;
  typedef Fem::SlaveDofs<DomainSpaceType, MapperType> SlaveDofsType;
  typedef typename SlaveDofsType::SingletonKey SlaveDofsKeyType;
  typedef Fem::SingletonList<SlaveDofsKeyType, SlaveDofsType> SlaveDofsProviderType;

  DirichletConstraints(const BoundaryType& boundary, const DomainSpaceType& domain_space)
    : boundary_(boundary)
    , domain_space_(domain_space)
    , slaveDofs_(getSlaveDofs(domain_space_))
    , dirichletBlocks_()
    // mark DoFs on the Dirichlet boundary
    , hasDirichletDofs_(false)
    , sequence_(-1) {}

  /*! treatment of Dirichlet-DoFs for given discrete function
   *
   *   \note A LagrangeDomainSpace is implicitly assumed.
   *
   *   \param[in]  u   discrete function providing the constraints
   *   \param[out] w   discrete function the constraints are applied to
   */
  template <class DiscreteFunctionType>
  void operator()(const DiscreteFunctionType& u, DiscreteFunctionType& w) const {
    updateDirichletDofs();

    // if Dirichlet Dofs have been found, treat them
    if (hasDirichletDofs_) {
      typedef typename DiscreteFunctionType::ConstDofIteratorType ConstDofIteratorType;

      ConstDofIteratorType uIt = u.dbegin();
      auto wIt = w.dbegin();

      constexpr auto localBlockSize = DiscreteFunctionType::DiscreteFunctionSpaceType::localBlockSize;
      // loop over all blocks
      for (auto blockDof : DSC::valueRange(u.space().blockMapper().size())) {
        if (dirichletBlocks_[blockDof]) {
          // copy dofs of the block
          for (unsigned int l = 0; l < localBlockSize; ++l, ++wIt, ++uIt) {
            assert(uIt != u.dend());
            assert(wIt != w.dend());
            (*wIt) = (*uIt);
          }
        } else {
          // increase dof iterators anyway
          for (unsigned int l = 0; l < localBlockSize; ++l, ++wIt, ++uIt) {
          }
        }
      }
    }
  }

  /*! treatment of Dirichlet-DoFs for given discrete function
 *
 *   \note A LagrangeDomainSpace is implicitly assumed.
 *
 *   \param[in]  val a value that will be used to set all dirichlet dofs
 *   \param[out] w   discrete function the constraints are applied to
 */
  template <class DiscreteFunctionType>
  void setValue(const typename DiscreteFunctionType::RangeFieldType val, DiscreteFunctionType& w) const {
    updateDirichletDofs();

    // if Dirichlet Dofs have been found, treat them
    if (hasDirichletDofs_) {
      auto wIt = w.dbegin();

      const auto localBlockSize = DiscreteFunctionType::DiscreteFunctionSpaceType::localBlockSize;
      // loop over all blocks
      const auto blocks = w.space().blockMapper().size();
      for (unsigned int blockDof = 0; blockDof < blocks; ++blockDof) {
        if (dirichletBlocks_[blockDof]) {
          // copy dofs of the block
          for (unsigned int l = 0; l < localBlockSize; ++l, ++wIt) {
            assert(wIt != w.dend());
            (*wIt) = val;
          }
        } else {
          // increase dof iterators anyway
          for (unsigned int l = 0; l < localBlockSize; ++l, ++wIt) {
          }
        }
      }
    }
  }

  /*! treatment of Dirichlet-DoFs for given discrete function
   *
   *   \note A LagrangeDomainSpace is implicitly assumed.
   *
   *   \param[in]  u   discrete function providing the constraints
   *   \param[out] w   discrete function the constraints are applied to
   */
  template <class GridFunctionType, class DiscreteFunctionType>
  void operator()(const GridFunctionType& u, DiscreteFunctionType& w) const {
    apply(u, w);
  }

  /*! treatment of Dirichlet-DoFs for solution and right-hand-side
   *
   *   delete rows for dirichlet-DoFs, setting diagonal element to 1.
   *
   *   \note A LagrangeDomainSpace is implicitly assumed.
   *
   *   \param[out] linearOperator  linear operator to be adjusted
   */
  template <class LinearOperator>
  void applyToOperator(LinearOperator& linearOperator) const {
    updateDirichletDofs();
    // if Dirichlet Dofs have been found, treat them
    if (hasDirichletDofs_) {
      for (const auto& entity : domain_space_) {
        // adjust linear operator
        dirichletDofsCorrectOnEntity(linearOperator, entity);
      }
    }
  }

protected:
  template <class GridFunctionType, class DiscreteFunctionType>
  void apply(const GridFunctionType& u, DiscreteFunctionType& w) const {
    updateDirichletDofs();
    // if Dirichlet Dofs have been found, treat them
    if (hasDirichletDofs_) {
      for (const auto& entity : domain_space_) {
        dirichletDofTreatment(entity, u, w);
      }
    }
  }

  /*! treatment of Dirichlet-DoFs for one entity
   *
   *   delete rows for dirichlet-DoFs, setting diagonal element to 1.
   *
   *   \note A LagrangeDomainSpace is implicitly assumed.
   *
   *   \param[in]  entity  entity to perform Dirichlet treatment on
   */
  template <class LinearOperator, class EntityType>
  void dirichletDofsCorrectOnEntity(LinearOperator& linearOperator, const EntityType& entity) const {
    // get slave dof structure (for parallel runs)   /*@LST0S@*/
    auto& slave_dofs = this->slaveDofs();
    const auto numSlaveDofs = slave_dofs.size();
    const auto& lagrangePointSet = domain_space_.lagrangePointSet(entity);
    auto localMatrix = linearOperator.localMatrix(entity, entity);

    // get number of basis functions
    const auto localBlocks = lagrangePointSet.size();
    const auto localBlockSize = DomainSpaceType::localBlockSize;

    // map local to global dofs
    std::vector<std::size_t> globalDofs(localBlockSize);
    std::vector<std::size_t> globalBlockDofs(localBlocks);

    domain_space_.mapper().map(entity, globalDofs);
    domain_space_.blockMapper().map(entity, globalBlockDofs);

    // counter for all local dofs (i.e. localBlockDof * localBlockSize + ... )
    int localDof = 0;
{'fraction_non_alphanumeric': 0.09881249083712065, 'fraction_numerical': 0.003298636563553731, 'mean_word_length': 3.2781436186892443, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 41, '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': '7240852', 'n_tokens_mistral': 4210, 'n_tokens_neox': 3972, 'n_words': 1099}