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 173096 : NearestNodeThread::NearestNodeThread( 19 173096 : const MooseMesh & mesh, std::map<dof_id_type, std::vector<dof_id_type>> & neighbor_nodes) 20 173096 : : _max_patch_percentage(0.0), _mesh(mesh), _neighbor_nodes(neighbor_nodes) 21 : { 22 173096 : } 23 : 24 : // Splitting Constructor 25 16344 : NearestNodeThread::NearestNodeThread(NearestNodeThread & x, Threads::split /*split*/) 26 16344 : : _max_patch_percentage(x._max_patch_percentage), 27 16344 : _mesh(x._mesh), 28 16344 : _neighbor_nodes(x._neighbor_nodes) 29 : { 30 16344 : } 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 189440 : NearestNodeThread::operator()(const NodeIdRange & range) 40 : { 41 1383800 : for (const auto & node_id : range) 42 : { 43 1194360 : const Node & node = _mesh.nodeRef(node_id); 44 : 45 1194360 : const Node * closest_node = NULL; 46 1194360 : Real closest_distance = std::numeric_limits<Real>::max(); 47 : 48 1194360 : const std::vector<dof_id_type> & neighbor_nodes = _neighbor_nodes[node_id]; 49 : 50 1194360 : unsigned int n_neighbor_nodes = neighbor_nodes.size(); 51 : 52 17056623 : for (unsigned int k = 0; k < n_neighbor_nodes; k++) 53 : { 54 15862263 : const Node * cur_node = &_mesh.nodeRef(neighbor_nodes[k]); 55 15862263 : Real distance = ((*cur_node) - node).norm(); 56 : 57 15862263 : if (distance < closest_distance) 58 : { 59 2327618 : 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 2327618 : if (patch_percentage > _max_patch_percentage) 63 376479 : _max_patch_percentage = patch_percentage; 64 : 65 2327618 : closest_distance = distance; 66 2327618 : closest_node = cur_node; 67 : } 68 : } 69 : 70 1194360 : 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 0 : 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 1194360 : NearestNodeLocator::NearestNodeInfo & info = _nearest_node_info[node.id()]; 87 : 88 1194360 : info._nearest_node = closest_node; 89 1194360 : info._distance = closest_distance; 90 : } 91 189440 : } 92 : 93 : void 94 16344 : NearestNodeThread::join(const NearestNodeThread & other) 95 : { 96 : // Did the other one go further through the patch than this one? 97 16344 : if (other._max_patch_percentage > _max_patch_percentage) 98 3707 : _max_patch_percentage = other._max_patch_percentage; 99 : 100 16344 : _nearest_node_info.insert(other._nearest_node_info.begin(), other._nearest_node_info.end()); 101 16344 : }