LCOV - code coverage report
Current view: top level - src/constraints - XFEMSingleVariableConstraint.C (source / functions) Hit Total Coverage
Test: idaholab/moose xfem: #31405 (292dce) with base fef103 Lines: 80 83 96.4 %
Date: 2025-09-04 07:58:55 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 "XFEMSingleVariableConstraint.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "Assembly.h"
      14             : #include "ElementPairInfo.h"
      15             : #include "FEProblem.h"
      16             : #include "GeometricCutUserObject.h"
      17             : #include "XFEM.h"
      18             : #include "Function.h"
      19             : 
      20             : #include "libmesh/quadrature.h"
      21             : 
      22             : registerMooseObject("XFEMApp", XFEMSingleVariableConstraint);
      23             : 
      24             : InputParameters
      25         384 : XFEMSingleVariableConstraint::validParams()
      26             : {
      27         384 :   InputParameters params = ElemElemConstraint::validParams();
      28         768 :   params.addParam<Real>("alpha",
      29         768 :                         100,
      30             :                         "Stabilization parameter in Nitsche's formulation and penalty factor "
      31             :                         "in the Penalty Method. In Nitsche's formulation this should be as "
      32             :                         "small as possible while the method is still stable; while in the "
      33             :                         "Penalty Method you want this to be quite large (e.g. 1e6).");
      34         768 :   params.addParam<FunctionName>("jump", 0, "Jump at the interface. Can be a Real or FunctionName.");
      35         768 :   params.addParam<FunctionName>(
      36         768 :       "jump_flux", 0, "Flux jump at the interface. Can be a Real or FunctionName.");
      37         768 :   params.addParam<UserObjectName>(
      38             :       "geometric_cut_userobject",
      39             :       "Name of GeometricCutUserObject associated with this constraint.");
      40         768 :   params.addParam<bool>(
      41             :       "use_penalty",
      42         768 :       false,
      43             :       "Use the Penalty instead of Nitsche (Nitsche only works for simple diffusion problems).");
      44         384 :   params.addClassDescription("Enforce constraints on the value or flux associated with a variable "
      45             :                              "at an XFEM interface.");
      46         384 :   return params;
      47           0 : }
      48             : 
      49         192 : XFEMSingleVariableConstraint::XFEMSingleVariableConstraint(const InputParameters & parameters)
      50             :   : ElemElemConstraint(parameters),
      51         384 :     _alpha(getParam<Real>("alpha")),
      52         192 :     _jump(getFunction("jump")),
      53         192 :     _jump_flux(getFunction("jump_flux")),
      54         576 :     _use_penalty(getParam<bool>("use_penalty"))
      55             : {
      56         576 :   _xfem = std::dynamic_pointer_cast<XFEM>(_fe_problem.getXFEM());
      57         192 :   if (_xfem == nullptr)
      58           0 :     mooseError("Problem casting to XFEM in XFEMSingleVariableConstraint");
      59             : 
      60             :   const UserObject * uo =
      61         384 :       &(_fe_problem.getUserObjectBase(getParam<UserObjectName>("geometric_cut_userobject")));
      62             : 
      63         192 :   if (dynamic_cast<const GeometricCutUserObject *>(uo) == nullptr)
      64           0 :     mooseError("UserObject casting to GeometricCutUserObject in XFEMSingleVariableConstraint");
      65             : 
      66         192 :   _interface_id = _xfem->getGeometricCutID(dynamic_cast<const GeometricCutUserObject *>(uo));
      67         192 : }
      68             : 
      69         576 : XFEMSingleVariableConstraint::~XFEMSingleVariableConstraint() {}
      70             : 
      71             : void
      72       62132 : XFEMSingleVariableConstraint::reinitConstraintQuadrature(const ElementPairInfo & element_pair_info)
      73             : {
      74       62132 :   _interface_normal = element_pair_info._elem1_normal;
      75       62132 :   ElemElemConstraint::reinitConstraintQuadrature(element_pair_info);
      76       62132 : }
      77             : 
      78             : Real
      79      964160 : XFEMSingleVariableConstraint::computeQpResidual(Moose::DGResidualType type)
      80             : {
      81             :   Real r = 0;
      82             : 
      83      964160 :   switch (type)
      84             :   {
      85      482080 :     case Moose::Element:
      86      482080 :       if (!_use_penalty)
      87             :       {
      88      418288 :         r -= (0.5 * _grad_u[_qp] * _interface_normal +
      89      418288 :               0.5 * _grad_u_neighbor[_qp] * _interface_normal) *
      90      418288 :              _test[_i][_qp];
      91      418288 :         r -= (_u[_qp] - _u_neighbor[_qp]) * 0.5 * _grad_test[_i][_qp] * _interface_normal;
      92      418288 :         r += 0.5 * _grad_test[_i][_qp] * _interface_normal * _jump.value(_t, _u[_qp]);
      93             :       }
      94      482080 :       r += 0.5 * _test[_i][_qp] * _jump_flux.value(_t, _u[_qp]);
      95      482080 :       r += _alpha * (_u[_qp] - _u_neighbor[_qp] - _jump.value(_t, _u[_qp])) * _test[_i][_qp];
      96      482080 :       break;
      97             : 
      98      482080 :     case Moose::Neighbor:
      99      482080 :       if (!_use_penalty)
     100             :       {
     101      418288 :         r += (0.5 * _grad_u[_qp] * _interface_normal +
     102      418288 :               0.5 * _grad_u_neighbor[_qp] * _interface_normal) *
     103      418288 :              _test_neighbor[_i][_qp];
     104      418288 :         r -= (_u[_qp] - _u_neighbor[_qp]) * 0.5 * _grad_test_neighbor[_i][_qp] * _interface_normal;
     105      418288 :         r += 0.5 * _grad_test_neighbor[_i][_qp] * _interface_normal *
     106      418288 :              _jump.value(_t, _u_neighbor[_qp]);
     107             :       }
     108      482080 :       r += 0.5 * _test_neighbor[_i][_qp] * _jump_flux.value(_t, _u_neighbor[_qp]);
     109      482080 :       r -= _alpha * (_u[_qp] - _u_neighbor[_qp] - _jump.value(_t, _u_neighbor[_qp])) *
     110      482080 :            _test_neighbor[_i][_qp];
     111      482080 :       break;
     112             :   }
     113      964160 :   return r;
     114             : }
     115             : 
     116             : Real
     117     1788416 : XFEMSingleVariableConstraint::computeQpJacobian(Moose::DGJacobianType type)
     118             : {
     119             :   Real r = 0;
     120             : 
     121     1788416 :   switch (type)
     122             :   {
     123      447104 :     case Moose::ElementElement:
     124      447104 :       if (!_use_penalty)
     125      395008 :         r += -0.5 * _grad_phi[_j][_qp] * _interface_normal * _test[_i][_qp] -
     126      395008 :              _phi[_j][_qp] * 0.5 * _grad_test[_i][_qp] * _interface_normal;
     127      447104 :       r += _alpha * _phi[_j][_qp] * _test[_i][_qp];
     128      447104 :       break;
     129             : 
     130      447104 :     case Moose::ElementNeighbor:
     131      447104 :       if (!_use_penalty)
     132      395008 :         r += -0.5 * _grad_phi_neighbor[_j][_qp] * _interface_normal * _test[_i][_qp] +
     133      395008 :              _phi_neighbor[_j][_qp] * 0.5 * _grad_test[_i][_qp] * _interface_normal;
     134      447104 :       r -= _alpha * _phi_neighbor[_j][_qp] * _test[_i][_qp];
     135      447104 :       break;
     136             : 
     137      447104 :     case Moose::NeighborElement:
     138      447104 :       if (!_use_penalty)
     139      395008 :         r += 0.5 * _grad_phi[_j][_qp] * _interface_normal * _test_neighbor[_i][_qp] -
     140      395008 :              _phi[_j][_qp] * 0.5 * _grad_test_neighbor[_i][_qp] * _interface_normal;
     141      447104 :       r -= _alpha * _phi[_j][_qp] * _test_neighbor[_i][_qp];
     142      447104 :       break;
     143             : 
     144      447104 :     case Moose::NeighborNeighbor:
     145      447104 :       if (!_use_penalty)
     146      395008 :         r += 0.5 * _grad_phi_neighbor[_j][_qp] * _interface_normal * _test_neighbor[_i][_qp] +
     147      395008 :              _phi_neighbor[_j][_qp] * 0.5 * _grad_test_neighbor[_i][_qp] * _interface_normal;
     148      447104 :       r += _alpha * _phi_neighbor[_j][_qp] * _test_neighbor[_i][_qp];
     149      447104 :       break;
     150             :   }
     151             : 
     152     1788416 :   return r;
     153             : }

Generated by: LCOV version 1.14