<commit_before>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "PenetrationLocator.h"

#include "Moose.h"
#include "MooseSystem.h"
#include "ArbitraryQuadrature.h"

#include "boundary_info.h"
#include "elem.h"
#include "plane.h"
#include "fe_interface.h"

PenetrationLocator::PenetrationLocator(MooseSystem & moose_system, Mesh & mesh, unsigned int master, unsigned int slave)
  :_moose_system(moose_system),
  _mesh(mesh),
  _master_boundary(master),
  _slave_boundary(slave)
{}


void
PenetrationLocator::detectPenetration()
{
  Moose::perf_log.push("detectPenetration()","Solve");

  // Data structures to hold the element boundary information
  std::vector< unsigned int > elem_list;
  std::vector< unsigned short int > side_list;
  std::vector< short int > id_list;

  // Retrieve the Element Boundary data structures from the mesh
  _mesh.boundary_info->build_side_list(elem_list, side_list, id_list);

  // Data strcutres to hold the Nodal Boundary conditions
  std::vector< unsigned int > node_list;
  std::vector< short int > node_boundary_list;
  _mesh.boundary_info->build_node_list_from_side_list();
  _mesh.boundary_info->build_node_list(node_list, node_boundary_list);

  const unsigned int n_nodes = node_list.size();
  const unsigned int n_elems = elem_list.size();

  for(unsigned int i=0; i<n_nodes; i++)
  {
    unsigned int boundary_id = node_boundary_list[i];

    if(boundary_id == _slave_boundary)
    {
      Node & node = _mesh.node(node_list[i]);
/*      
      if(node.processor_id() == libMesh::processor_id())
      {
*/
        // See if we already have info about this node
        if(_penetration_info[node.id()])
        {
          PenetrationInfo * info = _penetration_info[node.id()];

          Elem * elem = info->_elem;
          Elem * side = info->_side;

          // See if the same element still contains this point
          if(elem->contains_point(node))
          {
            Point closest_point;
            RealVectorValue normal;

            info->_distance = normDistance(*elem, *side, node, closest_point, normal);
            info->_normal = normal;
            
            mooseAssert(info->_distance >= 0, "Error in PenetrationLocator: Slave node contained in element but contact distance was negative!");
            
            info->_closest_point = closest_point;
//            _has_penetrated[node.id()] = true;

            // I hate continues but this is actually cleaner than anything I can think of
            continue;
          }
          else
          {
            Point closest_point;            
            RealVectorValue normal;

            // See if this element still has the same one across from it
            Real distance = normDistance(*elem, *side, node, closest_point, normal);

            if(std::abs(distance) < 999999999)
            {
              info->_normal = normal;
              info->_distance = distance;
              mooseAssert(info->_distance <= 0, "Error in PenetrationLocator: Slave node not contained in element but distance was positive!");

              info->_closest_point = closest_point;

              continue;
            }
            else
            {
              delete _penetration_info[node.id()];
              _penetration_info[node.id()] = NULL;
            }
          }
        } 
          
        Node * closest_node = NULL;
        
        Real closest_distance = 999999999;
        
        for(unsigned int k=0; k<n_nodes; k++)  
        {
          short int other_boundary_id = node_boundary_list[k];

          if(other_boundary_id == _master_boundary)
          {
            Node * cur_node = _mesh.node_ptr(node_list[k]);
                                             
            Real distance = ((*cur_node) - node).size();

            if(distance < closest_distance)
            {
              closest_distance = distance;
              closest_node = cur_node;
            }
          }
        }

        std::vector<unsigned int> & closest_elems = _moose_system.node_to_elem_map[closest_node->id()];

        for(unsigned int j=0; j<closest_elems.size(); j++)
        {          
          unsigned int elem_id = closest_elems[j];
          Elem * elem = _mesh.elem(elem_id);
            
          for(unsigned int m=0; m<n_elems; m++)
          {
            if(elem_list[m] == elem_id && id_list[m] == _master_boundary)
            {
              unsigned int side_num = side_list[m];
              
              Elem *side = (elem->build_side(side_num)).release();

              Point closest_point;
              RealVectorValue normal;
              
              Real distance = normDistance(*elem, *side, node, closest_point, normal);

              if(_penetration_info[node.id()] && std::abs(_penetration_info[node.id()]->_distance) > std::abs(distance))
              {
                delete _penetration_info[node.id()];
                _penetration_info[node.id()] = NULL;
              }
                
              if(std::abs(distance) < 999999999)
              {
//                if(distance > 0)
//                  _has_penetrated[node.id()] = true;
                

                _penetration_info[node.id()] =  new PenetrationInfo(&node,
                                                                    elem,
                                                                    side,
                                                                    normal,
                                                                    distance,
                                                                    closest_point);
              }
              else
              {
                delete side;
              }
            }
          }
        }
//      }
    }
  }        

  Moose::perf_log.pop("detectPenetration()","Solve");
}

Real
PenetrationLocator::penetrationDistance(unsigned int node_id)
{
  PenetrationInfo * info = _penetration_info[node_id];
  <commit_msg>fix small bug<commit_after>/****************************************************************/
/*               DO NOT MODIFY THIS HEADER                      */
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*           (c) 2010 Battelle Energy Alliance, LLC             */
/*                   ALL RIGHTS RESERVED                        */
/*                                                              */
/*          Prepared by Battelle Energy Alliance, LLC           */
/*            Under Contract No. DE-AC07-05ID14517              */
/*            With the U. S. Department of Energy               */
/*                                                              */
/*            See COPYRIGHT for full restrictions               */
/****************************************************************/

#include "PenetrationLocator.h"

#include "Moose.h"
#include "MooseSystem.h"
#include "ArbitraryQuadrature.h"

#include "boundary_info.h"
#include "elem.h"
#include "plane.h"
#include "fe_interface.h"

PenetrationLocator::PenetrationLocator(MooseSystem & moose_system, Mesh & mesh, unsigned int master, unsigned int slave)
  :_moose_system(moose_system),
  _mesh(mesh),
  _master_boundary(master),
  _slave_boundary(slave)
{}


void
PenetrationLocator::detectPenetration()
{
  Moose::perf_log.push("detectPenetration()","Solve");

  // Data structures to hold the element boundary information
  std::vector< unsigned int > elem_list;
  std::vector< unsigned short int > side_list;
  std::vector< short int > id_list;

  // Retrieve the Element Boundary data structures from the mesh
  _mesh.boundary_info->build_side_list(elem_list, side_list, id_list);

  // Data strcutres to hold the Nodal Boundary conditions
  std::vector< unsigned int > node_list;
  std::vector< short int > node_boundary_list;
  _mesh.boundary_info->build_node_list_from_side_list();
  _mesh.boundary_info->build_node_list(node_list, node_boundary_list);

  const unsigned int n_nodes = node_list.size();
  const unsigned int n_elems = elem_list.size();

  for(unsigned int i=0; i<n_nodes; i++)
  {
    unsigned int boundary_id = node_boundary_list[i];

    if(boundary_id == _slave_boundary)
    {
      Node & node = _mesh.node(node_list[i]);
/*      
      if(node.processor_id() == libMesh::processor_id())
      {
*/
        // See if we already have info about this node
        if(_penetration_info[node.id()])
        {
          PenetrationInfo * info = _penetration_info[node.id()];

          Elem * elem = info->_elem;
          Elem * side = info->_side;

          // See if the same element still contains this point
          if(elem->contains_point(node))
          {
            Point closest_point;
            RealVectorValue normal;

            info->_distance = normDistance(*elem, *side, node, closest_point, normal);
            info->_normal = normal;
            
            mooseAssert(info->_distance >= 0, "Error in PenetrationLocator: Slave node contained in element but contact distance was negative!");
            
            info->_closest_point = closest_point;
//            _has_penetrated[node.id()] = true;

            // I hate continues but this is actually cleaner than anything I can think of
            continue;
          }
          else
          {
            Point closest_point;            
            RealVectorValue normal;

            // See if this element still has the same one across from it
            Real distance = normDistance(*elem, *side, node, closest_point, normal);

            if(std::abs(distance) < 999999999)
            {
              info->_normal = normal;
              info->_distance = distance;
              mooseAssert(info->_distance <= 0, "Error in PenetrationLocator: Slave node not contained in element but distance was positive!");

              info->_closest_point = closest_point;

              continue;
            }
            else
            {
              delete _penetration_info[node.id()];
              _penetration_info[node.id()] = NULL;
            }
          }
        } 
          
        Node * closest_node = NULL;
        
        Real closest_distance = 999999999;
        
        for(unsigned int k=0; k<n_nodes; k++)  
        {
          short int other_boundary_id = node_boundary_list[k];

          if(other_boundary_id == _master_boundary)
          {
            Node * cur_node = _mesh.node_ptr(node_list[k]);
                                             
            Real distance = ((*cur_node) - node).size();

            if(distance < closest_distance)
            {
              closest_distance = distance;
              closest_node = cur_node;
            }
          }
        }

        std::vector<unsigned int> & closest_elems = _moose_system.node_to_elem_map[closest_node->id()];

        for(unsigned int j=0; j<closest_elems.size(); j++)
        {          
          unsigned int elem_id = closest_elems[j];
          Elem * elem = _mesh.elem(elem_id);
            
          for(unsigned int m=0; m<n_elems; m++)
          {
            if(elem_list[m] == elem_id && id_list[m] == _master_boundary)
            {
              unsigned int side_num = side_list[m];
              
              Elem *side = (elem->build_side(side_num)).release();

              Point closest_point;
              RealVectorValue normal;
              
              Real distance = normDistance(*elem, *side, node, closest_point, normal);

              if(_penetration_info[node.id()] && std::abs(_penetration_info[node.id()]->_distance) > std::abs(distance))
              {
                delete _penetration_info[node.id()];
                _penetration_info[node.id()] = NULL;
              }
                
              if(std::abs(distance) < 999999999 && (!_penetration_info[node.id()] || std::abs(_penetration_info[node.id()]->_distance) > std::abs(distance)))
              {
                _penetration_info[node.id()] =  new PenetrationInfo(&node,
                                                                    elem,
                                                                    side,
                                                                    normal,
                                                                    distance,
                                                                    closest_point);
              }
              else
              {
                delete side;
              }
            }
          }
        }
//      }
    }
  }        

  Moose::perf_log.pop("detectPenetration()","Solve");
}

Real
PenetrationLocator::penetrationDistance(unsigned int node_id)
{
  PenetrationInfo * info = _penetration_info[node_id];
  
{'fraction_non_alphanumeric': 0.11391195708091424, 'fraction_numerical': 0.006834717424854854, 'mean_word_length': 1.5270194986072423, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 56, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 6, 'word_list_counts': {'cursed_substrings.json': 36, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2220871', 'n_tokens_mistral': 3630, 'n_tokens_neox': 3442, 'n_words': 775}