LCOV - code coverage report
Current view: top level - src/linearfvkernels - LinearFVFluxKernel.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 90 91 98.9 %
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 "LinearFVFluxKernel.h"
      11             : #include "LinearFVBoundaryCondition.h"
      12             : 
      13             : InputParameters
      14       45559 : LinearFVFluxKernel::validParams()
      15             : {
      16       45559 :   InputParameters params = LinearFVKernel::validParams();
      17      136677 :   params.addParam<bool>("force_boundary_execution",
      18       91118 :                         false,
      19             :                         "Whether to force execution of this object on all external boundaries.");
      20       45559 :   params.registerSystemAttributeName("LinearFVFluxKernel");
      21       45559 :   return params;
      22           0 : }
      23             : 
      24        1382 : LinearFVFluxKernel::LinearFVFluxKernel(const InputParameters & params)
      25             :   : LinearFVKernel(params),
      26             :     FaceArgProducerInterface(),
      27        1382 :     _current_face_info(nullptr),
      28        1382 :     _current_face_type(FaceInfo::VarFaceNeighbors::NEITHER),
      29        1382 :     _cached_matrix_contribution(false),
      30        1382 :     _cached_rhs_contribution(false),
      31        1382 :     _force_boundary_execution(getParam<bool>("force_boundary_execution")),
      32        1382 :     _dof_indices(2, 0),
      33        1382 :     _matrix_contribution(2, 2),
      34        2764 :     _rhs_contribution(2, 0.0)
      35             : {
      36        1382 : }
      37             : 
      38             : void
      39     2881612 : LinearFVFluxKernel::addMatrixContribution()
      40             : {
      41             :   // If we are on an internal face, we populate the four entries in the system matrix
      42             :   // which touch the face
      43     2881612 :   if (_current_face_type == FaceInfo::VarFaceNeighbors::BOTH)
      44             :   {
      45             :     // The dof ids of the variable corresponding to the element and neighbor
      46     2679070 :     _dof_indices(0) = _current_face_info->elemInfo()->dofIndices()[_sys_num][_var_num];
      47     2679070 :     _dof_indices(1) = _current_face_info->neighborInfo()->dofIndices()[_sys_num][_var_num];
      48             : 
      49             :     // Compute the entries which will go to the neighbor (offdiagonal) and element
      50             :     // (diagonal).
      51     2679070 :     const auto elem_matrix_contribution = computeElemMatrixContribution();
      52     2679070 :     const auto neighbor_matrix_contribution = computeNeighborMatrixContribution();
      53             : 
      54             :     // Populate matrix
      55     2679070 :     if (hasBlocks(_current_face_info->elemInfo()->subdomain_id()))
      56             :     {
      57     2679063 :       _matrix_contribution(0, 0) = elem_matrix_contribution;
      58     2679063 :       _matrix_contribution(0, 1) = neighbor_matrix_contribution;
      59             :     }
      60             : 
      61     2679070 :     if (hasBlocks(_current_face_info->neighborInfo()->subdomain_id()))
      62             :     {
      63     2679047 :       _matrix_contribution(1, 0) = -elem_matrix_contribution;
      64     2679047 :       _matrix_contribution(1, 1) = -neighbor_matrix_contribution;
      65             :     }
      66             : 
      67             :     // We add the contributions to every tagged matrix
      68     5358140 :     for (auto & matrix : _matrices)
      69     2679070 :       (*matrix).add_matrix(_matrix_contribution, _dof_indices.get_values());
      70             :   }
      71             :   // We are at a block boundary where the variable is not defined on one of the adjacent cells.
      72             :   // We check if we have a boundary condition here
      73      202542 :   else if (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
      74        3906 :            _current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
      75             :   {
      76             :     mooseAssert(
      77             :         _current_face_info->boundaryIDs().size() == 1,
      78             :         "We should only have one boundary on every face. Current face center: " +
      79             :             Moose::stringify(_current_face_info->faceCentroid()) +
      80             :             " boundaries specified: " + Moose::stringify(_current_face_info->boundaryIDs()));
      81             : 
      82             :     LinearFVBoundaryCondition * bc_pointer =
      83      202542 :         _var.getBoundaryCondition(*_current_face_info->boundaryIDs().begin());
      84             : 
      85      202542 :     if (bc_pointer || _force_boundary_execution)
      86             :     {
      87      195982 :       if (bc_pointer)
      88      195982 :         bc_pointer->setupFaceData(_current_face_info, _current_face_type);
      89      195982 :       const auto matrix_contribution = computeBoundaryMatrixContribution(*bc_pointer);
      90             : 
      91             :       // We allow internal (for the mesh) boundaries too, so we have to check on which side we
      92             :       // are on (assuming that this is a boundary for the variable)
      93      195982 :       if (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM)
      94             :       {
      95      192076 :         const auto dof_id_elem = _current_face_info->elemInfo()->dofIndices()[_sys_num][_var_num];
      96             : 
      97             :         // We add the contributions to every tagged matrix
      98      384152 :         for (auto & matrix : _matrices)
      99      192076 :           (*matrix).add(dof_id_elem, dof_id_elem, matrix_contribution);
     100             :       }
     101        3906 :       else if (_current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
     102             :       {
     103             :         const auto dof_id_neighbor =
     104        3906 :             _current_face_info->neighborInfo()->dofIndices()[_sys_num][_var_num];
     105             : 
     106             :         // We add the contributions to every tagged matrix
     107        7812 :         for (auto & matrix : _matrices)
     108        3906 :           (*matrix).add(dof_id_neighbor, dof_id_neighbor, matrix_contribution);
     109             :       }
     110             :     }
     111             :   }
     112     2881612 : }
     113             : 
     114             : void
     115     2881612 : LinearFVFluxKernel::addRightHandSideContribution()
     116             : {
     117             :   // If we are on an internal face, we populate the two entries in the right hand side
     118             :   // which touch the face
     119     2881612 :   if (_current_face_type == FaceInfo::VarFaceNeighbors::BOTH)
     120             :   {
     121             :     // The dof ids of the variable corresponding to the element and neighbor
     122     2679070 :     _dof_indices(0) = _current_face_info->elemInfo()->dofIndices()[_sys_num][_var_num];
     123     2679070 :     _dof_indices(1) = _current_face_info->neighborInfo()->dofIndices()[_sys_num][_var_num];
     124             : 
     125             :     // Compute the entries which will go to the neighbor and element positions.
     126     2679070 :     const auto elem_rhs_contribution = computeElemRightHandSideContribution();
     127     2679070 :     const auto neighbor_rhs_contribution = computeNeighborRightHandSideContribution();
     128             : 
     129             :     // Populate right hand side
     130     2679070 :     if (hasBlocks(_current_face_info->elemInfo()->subdomain_id()))
     131     2679063 :       _rhs_contribution(0) = elem_rhs_contribution;
     132     2679070 :     if (hasBlocks(_current_face_info->neighborInfo()->subdomain_id()))
     133     2679047 :       _rhs_contribution(1) = neighbor_rhs_contribution;
     134             : 
     135             :     // We add the contributions to every tagged vector
     136     5358140 :     for (auto & vector : _vectors)
     137     2679070 :       (*vector).add_vector(_rhs_contribution.get_values().data(), _dof_indices.get_values());
     138             :   }
     139             :   // We are at a block boundary where the variable is not defined on one of the adjacent cells.
     140             :   // We check if we have a boundary condition here
     141      202542 :   else if (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
     142        3906 :            _current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
     143             :   {
     144             :     mooseAssert(_current_face_info->boundaryIDs().size() == 1,
     145             :                 "We should only have one boundary on every face.");
     146             :     LinearFVBoundaryCondition * bc_pointer =
     147      202542 :         _var.getBoundaryCondition(*_current_face_info->boundaryIDs().begin());
     148             : 
     149      202542 :     if (bc_pointer || _force_boundary_execution)
     150             :     {
     151      195982 :       if (bc_pointer)
     152      195982 :         bc_pointer->setupFaceData(_current_face_info, _current_face_type);
     153             : 
     154      195982 :       const auto rhs_contribution = computeBoundaryRHSContribution(*bc_pointer);
     155             : 
     156             :       // We allow internal (for the mesh) boundaries too, so we have to check on which side we
     157             :       // are on (assuming that this is a boundary for the variable)
     158      195982 :       if (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM)
     159             :       {
     160      192076 :         const auto dof_id_elem = _current_face_info->elemInfo()->dofIndices()[_sys_num][_var_num];
     161             :         // We add the contributions to every tagged vector
     162      384152 :         for (auto & vector : _vectors)
     163      192076 :           (*vector).add(dof_id_elem, rhs_contribution);
     164             :       }
     165        3906 :       else if (_current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
     166             :       {
     167             :         const auto dof_id_neighbor =
     168        3906 :             _current_face_info->neighborInfo()->dofIndices()[_sys_num][_var_num];
     169             :         // We add the contributions to every tagged matrix
     170        7812 :         for (auto & vector : _vectors)
     171        3906 :           (*vector).add(dof_id_neighbor, rhs_contribution);
     172             :       }
     173             :     }
     174             :   }
     175     2881612 : }
     176             : 
     177             : bool
     178     3060200 : LinearFVFluxKernel::hasFaceSide(const FaceInfo & fi, bool fi_elem_side) const
     179             : {
     180     3060200 :   const auto ft = fi.faceType(std::make_pair(_var_num, _sys_num));
     181     3060200 :   if (fi_elem_side)
     182     1530100 :     return ft == FaceInfo::VarFaceNeighbors::ELEM || ft == FaceInfo::VarFaceNeighbors::BOTH;
     183             :   else
     184     1530100 :     return ft == FaceInfo::VarFaceNeighbors::NEIGHBOR || ft == FaceInfo::VarFaceNeighbors::BOTH;
     185             : }
     186             : 
     187             : Moose::FaceArg
     188      141994 : LinearFVFluxKernel::singleSidedFaceArg(const FaceInfo * fi,
     189             :                                        const Moose::FV::LimiterType limiter_type,
     190             :                                        const bool correct_skewness) const
     191             : {
     192             :   mooseAssert(fi, "FaceInfo should not be null!");
     193      141994 :   return makeFace(*fi, limiter_type, true, correct_skewness);
     194             : }
     195             : 
     196             : void
     197     2881612 : LinearFVFluxKernel::setupFaceData(const FaceInfo * face_info)
     198             : {
     199     2881612 :   _cached_matrix_contribution = false;
     200     2881612 :   _cached_rhs_contribution = false;
     201     2881612 :   _current_face_info = face_info;
     202     2881612 :   _current_face_type = _current_face_info->faceType(std::make_pair(_var_num, _sys_num));
     203     2881612 :   _matrix_contribution.zero();
     204     2881612 :   _dof_indices.zero();
     205     2881612 :   _rhs_contribution.zero();
     206     2881612 : }

Generated by: LCOV version 1.14