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 "NearestNodeValueAux.h" 11 : 12 : #include "SystemBase.h" 13 : #include "NearestNodeLocator.h" 14 : 15 : registerMooseObject("MooseApp", NearestNodeValueAux); 16 : 17 : InputParameters 18 14290 : NearestNodeValueAux::validParams() 19 : { 20 14290 : InputParameters params = AuxKernel::validParams(); 21 14290 : params.addClassDescription("Retrieves a field value from the closest node on the paired boundary " 22 : "and stores it on this boundary or block."); 23 14290 : params.set<bool>("_dual_restrictable") = true; 24 14290 : params.addRequiredParam<BoundaryName>("paired_boundary", "The boundary to get the value from."); 25 14290 : params.addRequiredCoupledVar("paired_variable", "The variable to get the value of."); 26 14290 : params.set<bool>("use_displaced_mesh") = true; 27 14290 : return params; 28 0 : } 29 : 30 13 : NearestNodeValueAux::NearestNodeValueAux(const InputParameters & parameters) 31 : : AuxKernel(parameters), 32 13 : _nearest_node( 33 13 : getNearestNodeLocator(parameters.get<BoundaryName>("paired_boundary"), boundaryNames()[0])), 34 13 : _serialized_solution(_nl_sys.currentSolution()), 35 26 : _paired_variable(coupled("paired_variable")) 36 : { 37 13 : if (boundaryNames().size() > 1) 38 0 : mooseError("NearestNodeValueAux can only be used with one boundary at a time!"); 39 : 40 : // Check that the paired variable is from the solution system 41 13 : if (_subproblem.hasAuxiliaryVariable("paired_variable")) 42 0 : paramError("paired_variable", "Paired variable should not be auxiliary"); 43 : // Check that the paired variable is nodal 44 13 : if (!getVar("paired_variable", 0)->hasDoFsOnNodes()) 45 0 : paramError("paired_variable", "Paired variable does not have degrees of freedom on nodes"); 46 : 47 : // TODO: avoid the runtime checks by making sure the paired variable is defined on the boundaries 48 13 : } 49 : 50 : Real 51 424 : NearestNodeValueAux::computeValue() 52 : { 53 424 : if (isNodal()) 54 : { 55 : // Assumes the variable you are coupling to is from the nonlinear system for now. 56 424 : const Node * nearest = _nearest_node.nearestNode(_current_node->id()); 57 424 : if (nearest == nullptr) 58 0 : mooseError("Could not locate the nearest node from node: ", _current_node->get_info()); 59 424 : dof_id_type dof_number = nearest->dof_number(_nl_sys.number(), _paired_variable, 0); 60 424 : if (dof_number == libMesh::DofObject::invalid_id) 61 0 : mooseError("Paired variable does not seem to be defined on nearest node: ", 62 0 : nearest->get_info()); 63 424 : return (*_serialized_solution)(dof_number); 64 : } 65 : else 66 : { 67 : // Get a value for all the nodes on the boundary, then average them for the centroid value 68 0 : Real average = 0; 69 0 : Real sum_inv_dist = 0; 70 0 : for (const auto & node : _current_elem->node_ref_range()) 71 : { 72 0 : const Node * nearest = _nearest_node.nearestNode(node.id()); 73 : // Some of the element's nodes wont be on the boundary 74 0 : if (!nearest) 75 0 : continue; 76 0 : const auto dof_number = nearest->dof_number(_nl_sys.number(), _paired_variable, 0); 77 0 : const auto distance = _nearest_node.distance(node.id()); 78 : 79 0 : if (dof_number == libMesh::DofObject::invalid_id) 80 0 : mooseError("Paired variable does not seem to be defined on nearest node: ", 81 0 : nearest->get_info()); 82 : 83 : // inverse distance weighting should be a fine default 84 0 : if (distance > 0) 85 : { 86 0 : average += (*_serialized_solution)(dof_number) / distance; 87 0 : sum_inv_dist += 1. / distance; 88 : } 89 : // if node and nearest nodes coincide, weight with 1 90 : else 91 : { 92 0 : average += (*_serialized_solution)(dof_number); 93 0 : sum_inv_dist += 1.; 94 : } 95 : } 96 : 97 0 : if (sum_inv_dist > 0) 98 0 : return average / sum_inv_dist; 99 : else 100 0 : return 0.; 101 : } 102 : }