LCOV - code coverage report
Current view: top level - src/indicators - InternalSideIndicatorBase.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 50 55 90.9 %
Date: 2025-07-17 01:28:37 Functions: 4 4 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 "InternalSideIndicatorBase.h"
      11             : 
      12             : // MOOSE includes
      13             : #include "Assembly.h"
      14             : #include "MooseTypes.h"
      15             : #include "MooseVariableFE.h"
      16             : #include "Problem.h"
      17             : #include "SubProblem.h"
      18             : #include "SystemBase.h"
      19             : 
      20             : #include "libmesh/dof_map.h"
      21             : #include "libmesh/dense_vector.h"
      22             : #include "libmesh/numeric_vector.h"
      23             : #include "libmesh/dense_subvector.h"
      24             : #include "libmesh/libmesh_common.h"
      25             : #include "libmesh/quadrature.h"
      26             : 
      27             : const BoundaryID InternalSideIndicatorBase::InternalBndId = 12345;
      28             : 
      29             : InputParameters
      30       58197 : InternalSideIndicatorBase::validParams()
      31             : {
      32       58197 :   InputParameters params = Indicator::validParams();
      33       58197 :   params.addRequiredParam<VariableName>(
      34             :       "variable", "The name of the variable that this side indicator applies to");
      35      174591 :   params.addParam<bool>("scale_by_flux_faces",
      36      116394 :                         false,
      37             :                         "Whether or not to scale the error values by "
      38             :                         "the number of flux faces.  This attempts to "
      39             :                         "not penalize elements on boundaries for "
      40             :                         "having less neighbors.");
      41             : 
      42       58197 :   params.addPrivateParam<BoundaryID>("_boundary_id", InternalSideIndicatorBase::InternalBndId);
      43       58197 :   return params;
      44           0 : }
      45             : 
      46         595 : InternalSideIndicatorBase::InternalSideIndicatorBase(const InputParameters & parameters)
      47             :   : Indicator(parameters),
      48             :     NeighborCoupleable(this, false, false),
      49             :     ScalarCoupleable(this),
      50         595 :     _field_var(_subproblem.getStandardVariable(_tid, name())),
      51         595 :     _current_elem(_assembly.elem()),
      52         595 :     _neighbor_elem(_assembly.neighbor()),
      53         595 :     _current_side(_assembly.side()),
      54         595 :     _current_side_elem(_assembly.sideElem()),
      55         595 :     _coord_sys(_assembly.coordSystem()),
      56         595 :     _qrule(_assembly.qRuleFace()),
      57         595 :     _q_point(_assembly.qPointsFace()),
      58         595 :     _JxW(_assembly.JxWFace()),
      59         595 :     _coord(_assembly.coordTransformation()),
      60         595 :     _boundary_id(parameters.get<BoundaryID>("_boundary_id")),
      61         595 :     _scale_by_flux_faces(parameters.get<bool>("scale_by_flux_faces")),
      62        1190 :     _normals(_assembly.normals())
      63             : {
      64         595 :   const std::vector<MooseVariableFieldBase *> & coupled_vars = getCoupledMooseVars();
      65         595 :   for (const auto & var : coupled_vars)
      66           0 :     addMooseVariableDependency(var);
      67             : 
      68             :   // Not supported with the base linear lagrange case
      69         595 :   if (_use_displaced_mesh)
      70           0 :     paramError("use_displaced_mesh",
      71             :                "Internal side indicators do not support using the displaced mesh at this time. "
      72             :                "They can be used on the undisplaced mesh in a Problem with displaced mesh");
      73             :   // Access into the solution vector assumes constant monomial
      74         595 :   if (_field_var.feType() != libMesh::FEType(CONSTANT, MONOMIAL))
      75           0 :     mooseError("Only constant monomial variables for the internal side indicator are supported");
      76         595 : }
      77             : 
      78             : void
      79     1570220 : InternalSideIndicatorBase::computeIndicator()
      80             : {
      81             :   // Derived class decides the contribution at each qp to the indicator value
      82     1570220 :   Real sum = 0;
      83     4438666 :   for (_qp = 0; _qp < _qrule->n_points(); _qp++)
      84     2868446 :     sum += _JxW[_qp] * _coord[_qp] * computeQpIntegral();
      85             : 
      86             :   // Contribution is added to the two elements
      87             :   {
      88     1570220 :     const auto sys_num = _field_var.sys().number();
      89     1570220 :     const auto var_num = _field_var.number();
      90     1570220 :     _solution.add(_current_elem->dof_number(sys_num, var_num, 0), sum * _current_elem->hmax());
      91     1570220 :     if (_field_var.hasBlocks(_neighbor_elem->subdomain_id()))
      92     1569861 :       _solution.add(_neighbor_elem->dof_number(sys_num, var_num, 0), sum * _neighbor_elem->hmax());
      93             :   }
      94     1570220 : }
      95             : 
      96             : void
      97      783545 : InternalSideIndicatorBase::finalize()
      98             : {
      99      783545 :   unsigned int n_flux_faces = 0;
     100             : 
     101      783545 :   if (_scale_by_flux_faces)
     102             :   {
     103        5448 :     if (isVarFV())
     104           0 :       paramError("scale_by_flux_faces", "Unsupported at this time for finite volume variables");
     105             : 
     106             :     // Figure out the total number of sides contributing to the error.
     107             :     // We'll scale by this so boundary elements are less penalized
     108       28536 :     for (unsigned int side = 0; side < _current_elem->n_sides(); side++)
     109       23088 :       if (_current_elem->neighbor_ptr(side) != nullptr)
     110       20328 :         n_flux_faces++;
     111             :   }
     112             :   else
     113      778097 :     n_flux_faces = 1;
     114             : 
     115             :   // The 0 is because CONSTANT MONOMIALS only have one coefficient per element
     116      783545 :   Real value = _field_var.dofValues()[0];
     117             : 
     118             :   {
     119      783545 :     const auto sys_num = _field_var.sys().number();
     120      783545 :     const auto var_num = _field_var.number();
     121             : 
     122      783545 :     _solution.set(_current_elem->dof_number(sys_num, var_num, 0),
     123      783545 :                   std::sqrt(value) / static_cast<Real>(n_flux_faces));
     124             :   }
     125      783545 : }

Generated by: LCOV version 1.14