LCOV - code coverage report
Current view: top level - src/bcs - NodalBC.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 419b9d Lines: 66 71 93.0 %
Date: 2025-08-08 20:01:16 Functions: 8 8 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 "NodalBC.h"
      11             : 
      12             : #include "Assembly.h"
      13             : #include "MooseVariableFE.h"
      14             : #include "SystemBase.h"
      15             : #include "NonlinearSystemBase.h"
      16             : #include "FEProblemBase.h"
      17             : 
      18             : InputParameters
      19      325779 : NodalBC::validParams()
      20             : {
      21      325779 :   InputParameters params = NodalBCBase::validParams();
      22             : 
      23      325779 :   return params;
      24             : }
      25             : 
      26       69208 : NodalBC::NodalBC(const InputParameters & parameters)
      27             :   : NodalBCBase(parameters),
      28             :     MooseVariableInterface<Real>(this,
      29             :                                  true,
      30             :                                  "variable",
      31             :                                  Moose::VarKindType::VAR_SOLVER,
      32             :                                  Moose::VarFieldType::VAR_FIELD_STANDARD),
      33      138400 :     _var(*mooseVariable()),
      34       69200 :     _current_node(_var.node()),
      35      138408 :     _u(_var.dofValues())
      36             : {
      37       69200 :   addMooseVariableDependency(mooseVariable());
      38             : 
      39       69200 :   _save_in.resize(_save_in_strings.size());
      40       69200 :   _diag_save_in.resize(_diag_save_in_strings.size());
      41             : 
      42       69299 :   for (unsigned int i = 0; i < _save_in_strings.size(); i++)
      43             :   {
      44          99 :     MooseVariable * var = &_subproblem.getStandardVariable(_tid, _save_in_strings[i]);
      45             : 
      46          99 :     if (var->feType() != _var.feType())
      47           0 :       paramError(
      48             :           "save_in",
      49             :           "saved-in auxiliary variable is incompatible with the object's nonlinear variable: ",
      50           0 :           moose::internal::incompatVarMsg(*var, _var));
      51             : 
      52          99 :     _save_in[i] = var;
      53          99 :     var->sys().addVariableToZeroOnResidual(_save_in_strings[i]);
      54          99 :     addMooseVariableDependency(var);
      55             :   }
      56             : 
      57       69200 :   _has_save_in = _save_in.size() > 0;
      58             : 
      59       69221 :   for (unsigned int i = 0; i < _diag_save_in_strings.size(); i++)
      60             :   {
      61          21 :     MooseVariable * var = &_subproblem.getStandardVariable(_tid, _diag_save_in_strings[i]);
      62             : 
      63          21 :     if (var->feType() != _var.feType())
      64           0 :       paramError(
      65             :           "diag_save_in",
      66             :           "saved-in auxiliary variable is incompatible with the object's nonlinear variable: ",
      67           0 :           moose::internal::incompatVarMsg(*var, _var));
      68             : 
      69          21 :     _diag_save_in[i] = var;
      70          21 :     var->sys().addVariableToZeroOnJacobian(_diag_save_in_strings[i]);
      71          21 :     addMooseVariableDependency(var);
      72             :   }
      73             : 
      74       69200 :   _has_diag_save_in = _diag_save_in.size() > 0;
      75       69200 : }
      76             : 
      77             : void
      78    62508692 : NodalBC::computeResidual()
      79             : {
      80    62508692 :   if (_var.isNodalDefined())
      81             :   {
      82    60781139 :     const Real res = computeQpResidual();
      83    60781139 :     setResidual(_sys, res, _var);
      84             : 
      85    60781139 :     if (_has_save_in)
      86         756 :       for (unsigned int i = 0; i < _save_in.size(); i++)
      87         378 :         _save_in[i]->sys().solution().set(_save_in[i]->nodalDofIndex(), res);
      88             :   }
      89    62508692 : }
      90             : 
      91             : void
      92     8806381 : NodalBC::computeJacobian()
      93             : {
      94             :   // We call the user's computeQpJacobian() function and store the
      95             :   // results in the _assembly object. We can't store them directly in
      96             :   // the element stiffness matrix, as they will only be inserted after
      97             :   // all the assembly is done.
      98     8806381 :   if (_var.isNodalDefined())
      99             :   {
     100     8663141 :     const Real cached_val = computeQpJacobian();
     101     8663141 :     const dof_id_type cached_row = _var.nodalDofIndex();
     102             : 
     103             :     // Cache the user's computeQpJacobian() value for later use.
     104     8663141 :     addJacobianElement(_fe_problem.assembly(0, _sys.number()),
     105             :                        cached_val,
     106             :                        cached_row,
     107             :                        cached_row,
     108             :                        /*scaling_factor=*/1);
     109             : 
     110     8663141 :     if (_has_diag_save_in)
     111         102 :       for (unsigned int i = 0; i < _diag_save_in.size(); i++)
     112          51 :         _diag_save_in[i]->sys().solution().set(_diag_save_in[i]->nodalDofIndex(), cached_val);
     113             :   }
     114     8806381 : }
     115             : 
     116             : void
     117     8893085 : NodalBC::computeOffDiagJacobian(const unsigned int jvar_num)
     118             : {
     119     8893085 :   if (jvar_num == _var.number())
     120     8806381 :     computeJacobian();
     121             :   else
     122             :   {
     123       86704 :     if (!_var.isNodalDefined())
     124         660 :       return;
     125             : 
     126       86044 :     const Real cached_val = computeQpOffDiagJacobian(jvar_num);
     127             : 
     128       86044 :     if (cached_val == 0.)
     129             :       // there's no reason to cache this if it's zero, and it can even lead to new nonzero
     130             :       // allocations
     131       84023 :       return;
     132             : 
     133        2021 :     const dof_id_type cached_row = _var.nodalDofIndex();
     134             :     // Note: this only works for Lagrange variables...
     135        2021 :     const dof_id_type cached_col = _current_node->dof_number(_sys.number(), jvar_num, 0);
     136             : 
     137             :     // Cache the user's computeQpJacobian() value for later use.
     138        2021 :     addJacobianElement(_fe_problem.assembly(0, _sys.number()),
     139             :                        cached_val,
     140             :                        cached_row,
     141             :                        cached_col,
     142             :                        /*scaling_factor=*/1);
     143             :   }
     144             : }
     145             : 
     146             : Real
     147     8650550 : NodalBC::computeQpJacobian()
     148             : {
     149     8650550 :   return 1.;
     150             : }
     151             : 
     152             : Real
     153       83924 : NodalBC::computeQpOffDiagJacobian(unsigned int /*jvar*/)
     154             : {
     155       83924 :   return 0.;
     156             : }
     157             : 
     158             : void
     159          54 : NodalBC::computeResidualAndJacobian()
     160             : {
     161          54 :   computeResidual();
     162             : 
     163         108 :   for (const auto & [ivariable, jvariable] : _fe_problem.couplingEntries(_tid, _sys.number()))
     164             :   {
     165          54 :     const unsigned int ivar = ivariable->number();
     166          54 :     const unsigned int jvar = jvariable->number();
     167             : 
     168          54 :     if (ivar != _var.number())
     169           0 :       continue;
     170             : 
     171          54 :     if (_is_implicit)
     172          54 :       computeOffDiagJacobian(jvar);
     173             :   }
     174             : 
     175             :   /// TODO: add nonlocal Jacobians and scalar Jacobians
     176          54 : }

Generated by: LCOV version 1.14