Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "NearestNodeThread.h" 11 : #include "MooseMesh.h" 12 : 13 : #include "libmesh/threads.h" 14 : #include "libmesh/node.h" 15 : 16 : #include <cmath> 17 : 18 189327 : NearestNodeThread::NearestNodeThread( 19 189327 : const MooseMesh & mesh, std::map<dof_id_type, std::vector<dof_id_type>> & neighbor_nodes) 20 189327 : : _max_patch_percentage(0.0), _mesh(mesh), _neighbor_nodes(neighbor_nodes) 21 : { 22 189327 : } 23 : 24 : // Splitting Constructor 25 16352 : NearestNodeThread::NearestNodeThread(NearestNodeThread & x, Threads::split /*split*/) 26 16352 : : _max_patch_percentage(x._max_patch_percentage), 27 16352 : _mesh(x._mesh), 28 16352 : _neighbor_nodes(x._neighbor_nodes) 29 : { 30 16352 : } 31 : 32 : /** 33 : * Save a patch of nodes that are close to each of the secondary nodes to speed the search algorithm 34 : * TODO: This needs to be updated at some point in time. If the hits into this data structure 35 : * approach "the end" 36 : * then it may be time to update 37 : */ 38 : void 39 205679 : NearestNodeThread::operator()(const NodeIdRange & range) 40 : { 41 1526084 : for (const auto & node_id : range) 42 : { 43 1320405 : const Node & node = _mesh.nodeRef(node_id); 44 : 45 1320405 : const Node * closest_node = NULL; 46 1320405 : Real closest_distance = std::numeric_limits<Real>::max(); 47 : 48 1320405 : const std::vector<dof_id_type> & neighbor_nodes = _neighbor_nodes[node_id]; 49 : 50 1320405 : unsigned int n_neighbor_nodes = neighbor_nodes.size(); 51 : 52 19080605 : for (unsigned int k = 0; k < n_neighbor_nodes; k++) 53 : { 54 17760200 : const Node * cur_node = &_mesh.nodeRef(neighbor_nodes[k]); 55 17760200 : Real distance = ((*cur_node) - node).norm(); 56 : 57 17760200 : if (distance < closest_distance) 58 : { 59 2556793 : Real patch_percentage = static_cast<Real>(k) / static_cast<Real>(n_neighbor_nodes); 60 : 61 : // Save off the maximum we had to go through the patch to find the closes node 62 2556793 : if (patch_percentage > _max_patch_percentage) 63 406960 : _max_patch_percentage = patch_percentage; 64 : 65 2556793 : closest_distance = distance; 66 2556793 : closest_node = cur_node; 67 : } 68 : } 69 : 70 1320405 : if (closest_distance == std::numeric_limits<Real>::max()) 71 : { 72 0 : for (unsigned int k = 0; k < n_neighbor_nodes; k++) 73 : { 74 0 : const Node * cur_node = &_mesh.nodeRef(neighbor_nodes[k]); 75 0 : if (std::isnan((*cur_node)(0)) || std::isinf((*cur_node)(0)) || 76 0 : std::isnan((*cur_node)(1)) || std::isinf((*cur_node)(1)) || 77 0 : std::isnan((*cur_node)(2)) || std::isinf((*cur_node)(2))) 78 : throw MooseException( 79 : "Failure in NearestNodeThread because solution contains inf or not-a-number " 80 : "entries. This is likely due to a failed factorization of the Jacobian " 81 0 : "matrix."); 82 : } 83 0 : mooseError("Unable to find nearest node!"); 84 : } 85 : 86 1320405 : NearestNodeLocator::NearestNodeInfo & info = _nearest_node_info[node.id()]; 87 : 88 1320405 : info._nearest_node = closest_node; 89 1320405 : info._distance = closest_distance; 90 : } 91 205679 : } 92 : 93 : void 94 16352 : NearestNodeThread::join(const NearestNodeThread & other) 95 : { 96 : // Did the other one go further through the patch than this one? 97 16352 : if (other._max_patch_percentage > _max_patch_percentage) 98 3707 : _max_patch_percentage = other._max_patch_percentage; 99 : 100 16352 : _nearest_node_info.insert(other._nearest_node_info.begin(), other._nearest_node_info.end()); 101 16352 : }