LCOV - code coverage report
Current view: top level - src/auxkernels - NearestNodeValueAux.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 24 50 48.0 %
Date: 2025-07-17 01:28:37 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          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             : }

Generated by: LCOV version 1.14