<commit_before>// local includes
#include "augment_sparsity_on_interface.h"

// libMesh includes
#include "libmesh/elem.h"
#include "libmesh/boundary_info.h"
#include "libmesh/elem_side_builder.h"

using namespace libMesh;

AugmentSparsityOnInterface::AugmentSparsityOnInterface(MeshBase & mesh,
                                                       boundary_id_type crack_boundary_lower,
                                                       boundary_id_type crack_boundary_upper) :
  _mesh(mesh),
  _crack_boundary_lower(crack_boundary_lower),
  _crack_boundary_upper(crack_boundary_upper),
  _initialized(false)
{
  this->mesh_reinit();
}

const ElementSideMap & AugmentSparsityOnInterface::get_lower_to_upper() const
{
  libmesh_assert(this->_initialized);
  return _lower_to_upper;
}

void AugmentSparsityOnInterface::mesh_reinit ()
{
  this->_initialized = true;

  // Loop over all elements (not just local elements) to make sure we find
  // "neighbor" elements on opposite sides of the crack.

  // Map from (elem, side) to vertex average
  std::map<std::pair<const Elem *, unsigned char>, Point> lower;
  std::map<std::pair<const Elem *, unsigned char>, Point> upper;

  // To avoid extraneous allocation when getting element side vertex averages
  std::unique_ptr<const Elem> side_elem;

  for (const auto & elem : _mesh.active_element_ptr_range())
    for (auto side : elem->side_index_range())
      if (elem->neighbor_ptr(side) == nullptr)
        {
          if (_mesh.get_boundary_info().has_boundary_id(elem, side, _crack_boundary_lower))
            {
              elem->build_side_ptr(side_elem, side);

              lower[std::make_pair(elem, side)] = side_elem->vertex_average();
            }

          if (_mesh.get_boundary_info().has_boundary_id(elem, side, _crack_boundary_upper))
            {
              elem->build_side_ptr(side_elem, side);

              upper[std::make_pair(elem, side)] = side_elem->vertex_average();
            }
        }

  // If we're doing a reinit on a distributed mesh then we may not see
  // all the vertex averages, or even a matching number of vertex averages.
  // std::size_t n_lower = lower.size();
  // std::size_t n_upper = upper.size();
  // libmesh_assert(n_lower == n_upper);

  // Clear _lower_to_upper. This map will be used for matrix assembly later on.
  _lower_to_upper.clear();

  // Clear _upper_to_lower. This map will be used for element ghosting
  // on distributed meshes, communication send_list construction in
  // parallel, and sparsity calculations
  _upper_to_lower.clear();

  // We do an N^2 search to find elements with matching vertex averages. This could be optimized,
  // e.g. by first sorting the vertex averages based on their (x,y,z) location.
  {
    for (const auto & lower_pr : lower)
      {
        const auto & lower_key = lower_pr.first;
        const Point & lower_val = lower_pr.second;

        // find closest vertex average in upper
        Real min_distance = std::numeric_limits<Real>::max();

        for (const auto & upper_pr : upper)
          {
            const auto & upper_key = upper_pr.first;
            const Point & upper_val = upper_pr.second;

            Real distance = (upper_val - lower_val).norm();
            if (distance < min_distance)
              {
                min_distance = distance;<commit_msg>Structured bindings in misc_ex9<commit_after>// local includes
#include "augment_sparsity_on_interface.h"

// libMesh includes
#include "libmesh/elem.h"
#include "libmesh/boundary_info.h"
#include "libmesh/elem_side_builder.h"

using namespace libMesh;

AugmentSparsityOnInterface::AugmentSparsityOnInterface(MeshBase & mesh,
                                                       boundary_id_type crack_boundary_lower,
                                                       boundary_id_type crack_boundary_upper) :
  _mesh(mesh),
  _crack_boundary_lower(crack_boundary_lower),
  _crack_boundary_upper(crack_boundary_upper),
  _initialized(false)
{
  this->mesh_reinit();
}

const ElementSideMap & AugmentSparsityOnInterface::get_lower_to_upper() const
{
  libmesh_assert(this->_initialized);
  return _lower_to_upper;
}

void AugmentSparsityOnInterface::mesh_reinit ()
{
  this->_initialized = true;

  // Loop over all elements (not just local elements) to make sure we find
  // "neighbor" elements on opposite sides of the crack.

  // Map from (elem, side) to vertex average
  std::map<std::pair<const Elem *, unsigned char>, Point> lower;
  std::map<std::pair<const Elem *, unsigned char>, Point> upper;

  // To avoid extraneous allocation when getting element side vertex averages
  std::unique_ptr<const Elem> side_elem;

  for (const auto & elem : _mesh.active_element_ptr_range())
    for (auto side : elem->side_index_range())
      if (elem->neighbor_ptr(side) == nullptr)
        {
          if (_mesh.get_boundary_info().has_boundary_id(elem, side, _crack_boundary_lower))
            {
              elem->build_side_ptr(side_elem, side);

              lower[std::make_pair(elem, side)] = side_elem->vertex_average();
            }

          if (_mesh.get_boundary_info().has_boundary_id(elem, side, _crack_boundary_upper))
            {
              elem->build_side_ptr(side_elem, side);

              upper[std::make_pair(elem, side)] = side_elem->vertex_average();
            }
        }

  // If we're doing a reinit on a distributed mesh then we may not see
  // all the vertex averages, or even a matching number of vertex averages.
  // std::size_t n_lower = lower.size();
  // std::size_t n_upper = upper.size();
  // libmesh_assert(n_lower == n_upper);

  // Clear _lower_to_upper. This map will be used for matrix assembly later on.
  _lower_to_upper.clear();

  // Clear _upper_to_lower. This map will be used for element ghosting
  // on distributed meshes, communication send_list construction in
  // parallel, and sparsity calculations
  _upper_to_lower.clear();

  // We do an N^2 search to find elements with matching vertex averages. This could be optimized,
  // e.g. by first sorting the vertex averages based on their (x,y,z) location.
  {
    for (const auto & [lower_key, lower_val] : lower)
      {
        // find closest vertex average in upper
        Real min_distance = std::numeric_limits<Real>::max();

        for (const auto & [upper_key, upper_val] : upper)
          {
            Real distance = (upper_val - lower_val).norm();
            if (distance < min_distance)
              {
                min_distance = distance;
{'fraction_non_alphanumeric': 0.09831546707503828, 'fraction_numerical': 0.0004594180704441041, 'mean_word_length': 2.855371900826446, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '831075', 'n_tokens_mistral': 1972, 'n_tokens_neox': 1896, 'n_words': 512}