LCOV - code coverage report
Current view: top level - src/bcs - NodalBC.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 66 71 93.0 %
Date: 2025-07-17 01:28:37 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      315986 : NodalBC::validParams()
      20             : {
      21      315986 :   InputParameters params = NodalBCBase::validParams();
      22             : 
      23      315986 :   return params;
      24             : }
      25             : 
      26       64323 : 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      128630 :     _var(*mooseVariable()),
      34       64315 :     _current_node(_var.node()),
      35      128638 :     _u(_var.dofValues())
      36             : {
      37       64315 :   addMooseVariableDependency(mooseVariable());
      38             : 
      39       64315 :   _save_in.resize(_save_in_strings.size());
      40       64315 :   _diag_save_in.resize(_diag_save_in_strings.size());
      41             : 
      42       64407 :   for (unsigned int i = 0; i < _save_in_strings.size(); i++)
      43             :   {
      44          92 :     MooseVariable * var = &_subproblem.getStandardVariable(_tid, _save_in_strings[i]);
      45             : 
      46          92 :     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          92 :     _save_in[i] = var;
      53          92 :     var->sys().addVariableToZeroOnResidual(_save_in_strings[i]);
      54          92 :     addMooseVariableDependency(var);
      55             :   }
      56             : 
      57       64315 :   _has_save_in = _save_in.size() > 0;
      58             : 
      59       64335 :   for (unsigned int i = 0; i < _diag_save_in_strings.size(); i++)
      60             :   {
      61          20 :     MooseVariable * var = &_subproblem.getStandardVariable(_tid, _diag_save_in_strings[i]);
      62             : 
      63          20 :     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          20 :     _diag_save_in[i] = var;
      70          20 :     var->sys().addVariableToZeroOnJacobian(_diag_save_in_strings[i]);
      71          20 :     addMooseVariableDependency(var);
      72             :   }
      73             : 
      74       64315 :   _has_diag_save_in = _diag_save_in.size() > 0;
      75       64315 : }
      76             : 
      77             : void
      78    55984841 : NodalBC::computeResidual()
      79             : {
      80    55984841 :   if (_var.isNodalDefined())
      81             :   {
      82    54483529 :     const Real res = computeQpResidual();
      83    54483529 :     setResidual(_sys, res, _var);
      84             : 
      85    54483529 :     if (_has_save_in)
      86         672 :       for (unsigned int i = 0; i < _save_in.size(); i++)
      87         336 :         _save_in[i]->sys().solution().set(_save_in[i]->nodalDofIndex(), res);
      88             :   }
      89    55984841 : }
      90             : 
      91             : void
      92     7859273 : 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     7859273 :   if (_var.isNodalDefined())
      99             :   {
     100     7737767 :     const Real cached_val = computeQpJacobian();
     101     7737767 :     const dof_id_type cached_row = _var.nodalDofIndex();
     102             : 
     103             :     // Cache the user's computeQpJacobian() value for later use.
     104     7737767 :     addJacobianElement(_fe_problem.assembly(0, _sys.number()),
     105             :                        cached_val,
     106             :                        cached_row,
     107             :                        cached_row,
     108             :                        /*scaling_factor=*/1);
     109             : 
     110     7737767 :     if (_has_diag_save_in)
     111          90 :       for (unsigned int i = 0; i < _diag_save_in.size(); i++)
     112          45 :         _diag_save_in[i]->sys().solution().set(_diag_save_in[i]->nodalDofIndex(), cached_val);
     113             :   }
     114     7859273 : }
     115             : 
     116             : void
     117     7939251 : NodalBC::computeOffDiagJacobian(const unsigned int jvar_num)
     118             : {
     119     7939251 :   if (jvar_num == _var.number())
     120     7859273 :     computeJacobian();
     121             :   else
     122             :   {
     123       79978 :     if (!_var.isNodalDefined())
     124         660 :       return;
     125             : 
     126       79318 :     const Real cached_val = computeQpOffDiagJacobian(jvar_num);
     127             : 
     128       79318 :     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       77520 :       return;
     132             : 
     133        1798 :     const dof_id_type cached_row = _var.nodalDofIndex();
     134             :     // Note: this only works for Lagrange variables...
     135        1798 :     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        1798 :     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     7726575 : NodalBC::computeQpJacobian()
     148             : {
     149     7726575 :   return 1.;
     150             : }
     151             : 
     152             : Real
     153       77432 : NodalBC::computeQpOffDiagJacobian(unsigned int /*jvar*/)
     154             : {
     155       77432 :   return 0.;
     156             : }
     157             : 
     158             : void
     159          48 : NodalBC::computeResidualAndJacobian()
     160             : {
     161          48 :   computeResidual();
     162             : 
     163          96 :   for (const auto & [ivariable, jvariable] : _fe_problem.couplingEntries(_tid, _sys.number()))
     164             :   {
     165          48 :     const unsigned int ivar = ivariable->number();
     166          48 :     const unsigned int jvar = jvariable->number();
     167             : 
     168          48 :     if (ivar != _var.number())
     169           0 :       continue;
     170             : 
     171          48 :     if (_is_implicit)
     172          48 :       computeOffDiagJacobian(jvar);
     173             :   }
     174             : 
     175             :   /// TODO: add nonlocal Jacobians and scalar Jacobians
     176          48 : }

Generated by: LCOV version 1.14