LCOV - code coverage report
Current view: top level - src/bcs - IntegratedBC.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 97 101 96.0 %
Date: 2025-07-17 01:28:37 Functions: 7 7 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 "IntegratedBC.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "Assembly.h"
      14             : #include "SubProblem.h"
      15             : #include "SystemBase.h"
      16             : #include "MooseVariableFE.h"
      17             : #include "MooseVariableScalar.h"
      18             : #include "FEProblemBase.h"
      19             : 
      20             : #include "libmesh/quadrature.h"
      21             : 
      22             : InputParameters
      23      540683 : IntegratedBC::validParams()
      24             : {
      25      540683 :   InputParameters params = IntegratedBCBase::validParams();
      26      540683 :   return params;
      27             : }
      28             : 
      29        6682 : IntegratedBC::IntegratedBC(const InputParameters & parameters)
      30             :   : IntegratedBCBase(parameters),
      31             :     MooseVariableInterface<Real>(this,
      32             :                                  false,
      33             :                                  "variable",
      34             :                                  Moose::VarKindType::VAR_SOLVER,
      35             :                                  Moose::VarFieldType::VAR_FIELD_STANDARD),
      36       13354 :     _var(*mooseVariable()),
      37        6677 :     _normals(_assembly.normals()),
      38        6677 :     _phi(_assembly.phiFace(_var)),
      39        6677 :     _grad_phi(_assembly.gradPhiFace(_var)),
      40        6677 :     _test(_var.phiFace()),
      41        6677 :     _grad_test(_var.gradPhiFace()),
      42        6677 :     _u(_is_implicit ? _var.sln() : _var.slnOld()),
      43       13359 :     _grad_u(_is_implicit ? _var.gradSln() : _var.gradSlnOld())
      44             : {
      45        6677 :   addMooseVariableDependency(mooseVariable());
      46             : 
      47        6677 :   _save_in.resize(_save_in_strings.size());
      48        6677 :   _diag_save_in.resize(_diag_save_in_strings.size());
      49             : 
      50        6775 :   for (unsigned int i = 0; i < _save_in_strings.size(); i++)
      51             :   {
      52          98 :     MooseVariable * var = &_subproblem.getStandardVariable(_tid, _save_in_strings[i]);
      53             : 
      54          98 :     if (var->feType() != _var.feType())
      55           0 :       paramError(
      56             :           "save_in",
      57             :           "saved-in auxiliary variable is incompatible with the object's nonlinear variable: ",
      58           0 :           moose::internal::incompatVarMsg(*var, _var));
      59          98 :     _save_in[i] = var;
      60          98 :     var->sys().addVariableToZeroOnResidual(_save_in_strings[i]);
      61          98 :     addMooseVariableDependency(var);
      62             :   }
      63             : 
      64        6677 :   _has_save_in = _save_in.size() > 0;
      65             : 
      66        6726 :   for (unsigned int i = 0; i < _diag_save_in_strings.size(); i++)
      67             :   {
      68          49 :     MooseVariable * var = &_subproblem.getStandardVariable(_tid, _diag_save_in_strings[i]);
      69             : 
      70          49 :     if (var->feType() != _var.feType())
      71           0 :       paramError(
      72             :           "diag_save_in",
      73             :           "saved-in auxiliary variable is incompatible with the object's nonlinear variable: ",
      74           0 :           moose::internal::incompatVarMsg(*var, _var));
      75             : 
      76          49 :     _diag_save_in[i] = var;
      77          49 :     var->sys().addVariableToZeroOnJacobian(_diag_save_in_strings[i]);
      78          49 :     addMooseVariableDependency(var);
      79             :   }
      80             : 
      81        6677 :   _has_diag_save_in = _diag_save_in.size() > 0;
      82        6677 : }
      83             : 
      84             : void
      85     1932922 : IntegratedBC::computeResidual()
      86             : {
      87     1932922 :   prepareVectorTag(_assembly, _var.number());
      88             : 
      89     1932922 :   precalculateResidual();
      90             : 
      91     7331447 :   for (_qp = 0; _qp < _qrule->n_points(); _qp++)
      92             :   {
      93     5398525 :     precalculateQpResidual();
      94    52183169 :     for (_i = 0; _i < _test.size(); _i++)
      95    46784644 :       _local_re(_i) += _JxW[_qp] * _coord[_qp] * computeQpResidual();
      96             :   }
      97             : 
      98     1932922 :   accumulateTaggedLocalResidual();
      99             : 
     100     1932922 :   if (_has_save_in)
     101             :   {
     102        1254 :     libMesh::Threads::spin_mutex::scoped_lock lock(libMesh::Threads::spin_mtx);
     103        2668 :     for (unsigned int i = 0; i < _save_in.size(); i++)
     104        1414 :       _save_in[i]->sys().solution().add_vector(_local_re, _save_in[i]->dofIndices());
     105        1254 :   }
     106     1932922 : }
     107             : 
     108             : void
     109      215670 : IntegratedBC::computeJacobian()
     110             : {
     111      215670 :   prepareMatrixTag(_assembly, _var.number(), _var.number());
     112             : 
     113      215670 :   precalculateJacobian();
     114             : 
     115      889638 :   for (_qp = 0; _qp < _qrule->n_points(); _qp++)
     116             :   {
     117      673968 :     precalculateQpJacobian();
     118     6474553 :     for (_i = 0; _i < _test.size(); _i++)
     119    86764464 :       for (_j = 0; _j < _phi.size(); _j++)
     120    80963879 :         _local_ke(_i, _j) += _JxW[_qp] * _coord[_qp] * computeQpJacobian();
     121             :   }
     122             : 
     123      215670 :   accumulateTaggedLocalMatrix();
     124             : 
     125      215670 :   if (_has_diag_save_in)
     126             :   {
     127         158 :     unsigned int rows = _local_ke.m();
     128         158 :     DenseVector<Number> diag(rows);
     129         790 :     for (unsigned int i = 0; i < rows; i++)
     130         632 :       diag(i) = _local_ke(i, i);
     131             : 
     132         158 :     libMesh::Threads::spin_mutex::scoped_lock lock(libMesh::Threads::spin_mtx);
     133         316 :     for (unsigned int i = 0; i < _diag_save_in.size(); i++)
     134         158 :       _diag_save_in[i]->sys().solution().add_vector(diag, _diag_save_in[i]->dofIndices());
     135         158 :   }
     136      215670 : }
     137             : 
     138             : void
     139      108916 : IntegratedBC::computeOffDiagJacobian(const unsigned int jvar_num)
     140             : {
     141      108916 :   const auto & jvar = getVariable(jvar_num);
     142             : 
     143      108916 :   if (jvar_num == _var.number())
     144             :   {
     145       97106 :     computeJacobian();
     146       97106 :     return;
     147             :   }
     148             : 
     149       11810 :   prepareMatrixTag(_assembly, _var.number(), jvar_num);
     150             : 
     151       11810 :   precalculateOffDiagJacobian(jvar_num);
     152             : 
     153             :   // This (undisplaced) jvar could potentially yield the wrong phi size if this object is acting
     154             :   // on the displaced mesh, so we obtain the variable on the proper system
     155       11810 :   auto phi_size = jvar.dofIndices().size();
     156             :   mooseAssert(phi_size * jvar.count() == _local_ke.n(),
     157             :               "The size of the phi container does not match the number of local Jacobian columns");
     158             : 
     159       46108 :   for (_qp = 0; _qp < _qrule->n_points(); _qp++)
     160             :   {
     161       34298 :     precalculateQpOffDiagJacobian(jvar);
     162      360446 :     for (_i = 0; _i < _test.size(); _i++)
     163      877472 :       for (_j = 0; _j < phi_size; _j++)
     164      551324 :         _local_ke(_i, _j) += _JxW[_qp] * _coord[_qp] * computeQpOffDiagJacobian(jvar_num);
     165             :   }
     166             : 
     167       11810 :   accumulateTaggedLocalMatrix();
     168             : }
     169             : 
     170             : void
     171          64 : IntegratedBC::computeOffDiagJacobianScalar(const unsigned int jvar)
     172             : {
     173          64 :   prepareMatrixTag(_assembly, _var.number(), jvar);
     174             : 
     175          64 :   MooseVariableScalar & jv = _sys.getScalarVariable(_tid, jvar);
     176         176 :   for (_qp = 0; _qp < _qrule->n_points(); _qp++)
     177         528 :     for (_i = 0; _i < _test.size(); _i++)
     178         832 :       for (_j = 0; _j < jv.order(); _j++)
     179         416 :         _local_ke(_i, _j) += _JxW[_qp] * _coord[_qp] * computeQpOffDiagJacobianScalar(jvar);
     180             : 
     181          64 :   accumulateTaggedLocalMatrix();
     182          64 : }
     183             : 
     184             : void
     185         184 : IntegratedBC::computeResidualAndJacobian()
     186             : {
     187         184 :   computeResidual();
     188             : 
     189         824 :   for (const auto & [ivariable, jvariable] : _fe_problem.couplingEntries(_tid, _sys.number()))
     190             :   {
     191         640 :     const unsigned int ivar = ivariable->number();
     192         640 :     const unsigned int jvar = jvariable->number();
     193             : 
     194         640 :     if (ivar != _var.number())
     195         304 :       continue;
     196             : 
     197         336 :     if (_is_implicit)
     198             :     {
     199         336 :       prepareShapes(jvar);
     200         336 :       computeOffDiagJacobian(jvar);
     201             :     }
     202             :   }
     203             : 
     204             :   /// TODO: add nonlocal Jacobians and scalar Jacobians
     205         184 : }

Generated by: LCOV version 1.14