LCOV - code coverage report
Current view: top level - src/bcs - BoundaryIntegralValueConstraint.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 9a5f1f Lines: 70 72 97.2 %
Date: 2026-06-21 21:23:42 Functions: 12 12 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 "BoundaryIntegralValueConstraint.h"
      11             : 
      12             : #include "MooseVariableScalar.h"
      13             : 
      14             : #include <array>
      15             : 
      16             : registerMooseObject("MooseApp", BoundaryIntegralValueConstraint);
      17             : 
      18             : InputParameters
      19        3237 : BoundaryIntegralValueConstraint::validParams()
      20             : {
      21        3237 :   InputParameters params = IntegratedBC::validParams();
      22        6474 :   params.addClassDescription(
      23             :       "Enforces a prescribed average value for a finite element variable on a boundary using a "
      24             :       "scalar Lagrange multiplier.");
      25       12948 :   params.addParam<PostprocessorName>("phi0", "0", "The value that the constraint will enforce.");
      26        9711 :   params.addRequiredCoupledVar("lambda", "Lagrange multiplier scalar variable");
      27        3237 :   return params;
      28           0 : }
      29             : 
      30          92 : BoundaryIntegralValueConstraint::BoundaryIntegralValueConstraint(const InputParameters & parameters)
      31             :   : IntegratedBC(parameters),
      32          92 :     _phi0(getPostprocessorValue("phi0")),
      33         184 :     _lambda_var(*getScalarVar("lambda", 0)),
      34         276 :     _lambda(coupledScalarValue("lambda"))
      35             : {
      36          92 :   if (_lambda_var.order() != 1)
      37           0 :     paramError("lambda", "The lambda variable must be a first-order scalar variable.");
      38          92 : }
      39             : 
      40             : std::set<std::string>
      41          84 : BoundaryIntegralValueConstraint::additionalROVariables()
      42             : {
      43         252 :   return {_lambda_var.name()};
      44          84 : }
      45             : 
      46             : Real
      47       25856 : BoundaryIntegralValueConstraint::computeQpResidual()
      48             : {
      49       25856 :   return _lambda[0] * _test[_i][_qp];
      50             : }
      51             : 
      52             : void
      53        3232 : BoundaryIntegralValueConstraint::computeResidual()
      54             : {
      55        3232 :   IntegratedBC::computeResidual();
      56        3232 :   computeScalarResidual();
      57        3232 : }
      58             : 
      59             : void
      60         112 : BoundaryIntegralValueConstraint::computeOffDiagJacobian(const unsigned int jvar)
      61             : {
      62         112 :   if (jvar == _var.number())
      63         112 :     computeScalarFieldJacobian();
      64         112 : }
      65             : 
      66             : void
      67         112 : BoundaryIntegralValueConstraint::computeOffDiagJacobianScalar(const unsigned int jvar)
      68             : {
      69         112 :   if (jvar == _lambda_var.number())
      70             :   {
      71         112 :     computeScalarJacobian();
      72         112 :     computeFieldScalarJacobian();
      73             :   }
      74         112 : }
      75             : 
      76             : void
      77        1616 : BoundaryIntegralValueConstraint::computeResidualAndJacobian()
      78             : {
      79        1616 :   computeResidual();
      80             : 
      81        1616 :   if (_is_implicit)
      82             :   {
      83        1616 :     prepareShapes(_var.number());
      84        1616 :     IntegratedBC::computeJacobian();
      85        1616 :     computeScalarJacobian();
      86             : 
      87             :     // The residual-and-Jacobian-together path bypasses ComputeFullJacobianThread, so assemble the
      88             :     // scalar off-diagonal blocks here.
      89        1616 :     computeFieldScalarJacobian();
      90        1616 :     computeScalarFieldJacobian();
      91             :   }
      92        1616 : }
      93             : 
      94             : void
      95        3232 : BoundaryIntegralValueConstraint::computeScalarResidual()
      96             : {
      97             :   mooseAssert(_lambda_var.dofIndices().size() == 1, "The lambda variable should have one dof");
      98             : 
      99        3232 :   std::array<Real, 1> residual{{0.0}};
     100             : 
     101        9696 :   for (_qp = 0; _qp < _qrule->n_points(); _qp++)
     102        6464 :     residual[0] += _JxW[_qp] * _coord[_qp] * (_u[_qp] - _phi0);
     103             : 
     104        3232 :   addResiduals(_assembly, residual, _lambda_var.dofIndices(), _lambda_var.scalingFactor());
     105        3232 : }
     106             : 
     107             : void
     108        1728 : BoundaryIntegralValueConstraint::computeScalarJacobian()
     109             : {
     110             :   mooseAssert(_lambda_var.dofIndices().size() == 1, "The lambda variable should have one dof");
     111             : 
     112        1728 :   DenseMatrix<Real> zero(1, 1);
     113        1728 :   addJacobian(_assembly,
     114             :               zero,
     115        1728 :               _lambda_var.dofIndices(),
     116        1728 :               _lambda_var.dofIndices(),
     117        1728 :               _lambda_var.scalingFactor());
     118        1728 : }
     119             : 
     120             : void
     121        1728 : BoundaryIntegralValueConstraint::computeFieldScalarJacobian()
     122             : {
     123             :   mooseAssert(_lambda_var.dofIndices().size() == 1, "The lambda variable should have one dof");
     124             : 
     125        1728 :   DenseMatrix<Real> jacobian(_test.size(), 1);
     126             : 
     127        5184 :   for (_qp = 0; _qp < _qrule->n_points(); _qp++)
     128       17280 :     for (_i = 0; _i < _test.size(); _i++)
     129       13824 :       jacobian(_i, 0) += _JxW[_qp] * _coord[_qp] * _test[_i][_qp];
     130             : 
     131        1728 :   addJacobian(
     132        1728 :       _assembly, jacobian, _var.dofIndices(), _lambda_var.dofIndices(), _var.scalingFactor());
     133        1728 : }
     134             : 
     135             : void
     136        1728 : BoundaryIntegralValueConstraint::computeScalarFieldJacobian()
     137             : {
     138             :   mooseAssert(_lambda_var.dofIndices().size() == 1, "The lambda variable should have one dof");
     139             : 
     140        1728 :   DenseMatrix<Real> jacobian(1, _phi.size());
     141             : 
     142        5184 :   for (_qp = 0; _qp < _qrule->n_points(); _qp++)
     143       17280 :     for (_j = 0; _j < _phi.size(); _j++)
     144       13824 :       jacobian(0, _j) += _JxW[_qp] * _coord[_qp] * _phi[_j][_qp];
     145             : 
     146        1728 :   addJacobian(_assembly,
     147             :               jacobian,
     148        1728 :               _lambda_var.dofIndices(),
     149        1728 :               _var.dofIndices(),
     150        1728 :               _lambda_var.scalingFactor());
     151        1728 : }

Generated by: LCOV version 1.14