LCOV - code coverage report
Current view: top level - src/fvbcs - FVBoundaryScalarLagrangeMultiplierConstraint.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 28 46 60.9 %
Date: 2025-07-17 01:28:37 Functions: 3 4 75.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 "FVBoundaryScalarLagrangeMultiplierConstraint.h"
      11             : 
      12             : #include "MooseVariableScalar.h"
      13             : #include "MooseVariableFV.h"
      14             : #include "Assembly.h"
      15             : #include "SystemBase.h"
      16             : 
      17             : InputParameters
      18       14290 : FVBoundaryScalarLagrangeMultiplierConstraint::validParams()
      19             : {
      20       14290 :   InputParameters params = FVFluxBC::validParams();
      21       14290 :   params.addClassDescription(
      22             :       "Base class for imposing constraints using scalar Lagrange multipliers");
      23       14290 :   params.addParam<PostprocessorName>("phi0", "0", "The value that the constraint will enforce.");
      24       14290 :   params.addRequiredCoupledVar("lambda", "Lagrange multiplier variable");
      25       14290 :   return params;
      26           0 : }
      27             : 
      28          13 : FVBoundaryScalarLagrangeMultiplierConstraint::FVBoundaryScalarLagrangeMultiplierConstraint(
      29          13 :     const InputParameters & parameters)
      30             :   : FVFluxBC(parameters),
      31          13 :     _phi0(getPostprocessorValue("phi0")),
      32          13 :     _lambda_var(*getScalarVar("lambda", 0)),
      33          26 :     _lambda(adCoupledScalarValue("lambda"))
      34             : {
      35          13 : }
      36             : 
      37             : void
      38           0 : FVBoundaryScalarLagrangeMultiplierConstraint::computeResidual(const FaceInfo & fi)
      39             : {
      40           0 :   _face_info = &fi;
      41           0 :   _normal = fi.normal();
      42           0 :   _face_type = fi.faceType(std::make_pair(_var.number(), _var.sys().number()));
      43             : 
      44             :   // For FV flux kernels, the normal is always oriented outward from the lower-id
      45             :   // element's perspective.  But for BCs, there is only a Jacobian
      46             :   // contribution to one element (one side of the face).  Because of this, we
      47             :   // make an exception and orient the normal to point outward from whichever
      48             :   // side of the face the BC's variable is defined on; we flip it if this
      49             :   // variable is defined on the neighbor side of the face (instead of elem) since
      50             :   // the FaceInfo normal polarity is always oriented with respect to the lower-id element.
      51           0 :   if (_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
      52           0 :     _normal = -_normal;
      53             : 
      54             :   // Primal
      55           0 :   prepareVectorTag(_assembly, _var.number());
      56             :   mooseAssert(_local_re.size() == 1, "We should only have a single dof");
      57             :   mooseAssert(_lambda.size() == 1 && _lambda_var.order() == 1,
      58             :               "The lambda variable should be first order");
      59           0 :   _local_re(0) += MetaPhysicL::raw_value(_lambda[0]) * fi.faceArea() * fi.faceCoord();
      60           0 :   accumulateTaggedLocalResidual();
      61             : 
      62             :   // LM
      63           0 :   const auto lm_r = MetaPhysicL::raw_value(computeQpResidual()) * fi.faceArea() * fi.faceCoord();
      64             :   mooseAssert(_lambda_var.dofIndices().size() == 1, "We should only have a single dof");
      65           0 :   addResiduals(_assembly,
      66           0 :                std::array<Real, 1>{{lm_r}},
      67           0 :                _lambda_var.dofIndices(),
      68           0 :                _lambda_var.scalingFactor());
      69           0 : }
      70             : 
      71             : void
      72         160 : FVBoundaryScalarLagrangeMultiplierConstraint::computeJacobian(const FaceInfo & fi)
      73             : {
      74         160 :   _face_info = &fi;
      75         160 :   _normal = fi.normal();
      76         160 :   _face_type = fi.faceType(std::make_pair(_var.number(), _var.sys().number()));
      77             : 
      78             :   // For FV flux kernels, the normal is always oriented outward from the lower-id
      79             :   // element's perspective.  But for BCs, there is only a Jacobian
      80             :   // contribution to one element (one side of the face).  Because of this, we
      81             :   // make an exception and orient the normal to point outward from whichever
      82             :   // side of the face the BC's variable is defined on; we flip it if this
      83             :   // variable is defined on the neighbor side of the face (instead of elem) since
      84             :   // the FaceInfo normal polarity is always oriented with respect to the lower-id element.
      85         160 :   if (_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
      86           0 :     _normal = -_normal;
      87             : 
      88         160 :   const auto & dof_indices = (_face_type == FaceInfo::VarFaceNeighbors::ELEM)
      89         160 :                                  ? _var.dofIndices()
      90           0 :                                  : _var.dofIndicesNeighbor();
      91             : 
      92             :   mooseAssert(dof_indices.size() == 1, "We're currently built to use CONSTANT MONOMIALS");
      93             : 
      94             :   // Primal
      95             :   mooseAssert(_lambda.size() == 1 && _lambda_var.order() == 1,
      96             :               "The lambda variable should be first order");
      97         160 :   const auto primal_r = _lambda[0] * (fi.faceArea() * fi.faceCoord());
      98         320 :   addResidualsAndJacobian(
      99         320 :       _assembly, std::array<ADReal, 1>{{primal_r}}, dof_indices, _var.scalingFactor());
     100             : 
     101             :   // LM
     102         160 :   const auto lm_r = computeQpResidual() * (fi.faceArea() * fi.faceCoord());
     103             :   mooseAssert(_lambda_var.dofIndices().size() == 1, "We should only have one dof");
     104         640 :   addResidualsAndJacobian(_assembly,
     105         160 :                           std::array<ADReal, 1>{{lm_r}},
     106         160 :                           _lambda_var.dofIndices(),
     107         160 :                           _lambda_var.scalingFactor());
     108         480 : }

Generated by: LCOV version 1.14