LCOV - code coverage report
Current view: top level - src/linearfvkernels - LinearFVTurbulentDiffusion.C (source / functions) Hit Total Coverage
Test: idaholab/moose navier_stokes: 9fc4b0 Lines: 91 101 90.1 %
Date: 2025-08-14 10:14:56 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://www.mooseframework.org
       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 "LinearFVTurbulentDiffusion.h"
      11             : #include "Assembly.h"
      12             : #include "SubProblem.h"
      13             : #include "LinearFVAdvectionDiffusionBC.h"
      14             : #include "NavierStokesMethods.h"
      15             : #include "NS.h"
      16             : 
      17             : registerMooseObject("NavierStokesApp", LinearFVTurbulentDiffusion);
      18             : 
      19             : InputParameters
      20         352 : LinearFVTurbulentDiffusion::validParams()
      21             : {
      22         352 :   InputParameters params = LinearFVDiffusion::validParams();
      23         352 :   params.addClassDescription(
      24             :       "Represents the matrix and right hand side contributions of a "
      25             :       "diffusion term for a turbulent variable in a partial differential equation.");
      26             : 
      27         704 :   params.addParam<MooseFunctorName>(
      28         704 :       "scaling_coeff", 1.0, "The scaling coefficient for the diffusion term.");
      29             : 
      30         704 :   params.addParam<std::vector<BoundaryName>>(
      31             :       "walls", {}, "Boundaries that correspond to solid walls.");
      32         352 :   return params;
      33           0 : }
      34             : 
      35         176 : LinearFVTurbulentDiffusion::LinearFVTurbulentDiffusion(const InputParameters & params)
      36             :   : LinearFVDiffusion(params),
      37         176 :     _scaling_coeff(getFunctor<Real>("scaling_coeff")),
      38         528 :     _wall_boundary_names(getParam<std::vector<BoundaryName>>("walls"))
      39             : {
      40         176 :   if (_use_nonorthogonal_correction)
      41           0 :     _var.computeCellGradients();
      42         176 : }
      43             : 
      44             : void
      45         880 : LinearFVTurbulentDiffusion::initialSetup()
      46             : {
      47         880 :   LinearFVDiffusion::initialSetup();
      48        1760 :   NS::getWallBoundedElements(
      49         880 :       _wall_boundary_names, _fe_problem, _subproblem, blockIDs(), _wall_bounded);
      50         880 : }
      51             : 
      52             : Real
      53     3750000 : LinearFVTurbulentDiffusion::computeElemMatrixContribution()
      54             : {
      55     3750000 :   const auto face_arg = makeCDFace(*_current_face_info);
      56     3750000 :   return computeFluxMatrixContribution() / _scaling_coeff(face_arg, determineState());
      57             : }
      58             : 
      59             : Real
      60     3750000 : LinearFVTurbulentDiffusion::computeNeighborMatrixContribution()
      61             : {
      62     3750000 :   const auto face_arg = makeCDFace(*_current_face_info);
      63     3750000 :   return -computeFluxMatrixContribution() / _scaling_coeff(face_arg, determineState());
      64             : }
      65             : 
      66             : Real
      67     3750000 : LinearFVTurbulentDiffusion::computeElemRightHandSideContribution()
      68             : {
      69     3750000 :   const auto face_arg = makeCDFace(*_current_face_info);
      70     3750000 :   return computeFluxRHSContribution() / _scaling_coeff(face_arg, determineState());
      71             : }
      72             : 
      73             : Real
      74     3750000 : LinearFVTurbulentDiffusion::computeNeighborRightHandSideContribution()
      75             : {
      76     3750000 :   const auto face_arg = makeCDFace(*_current_face_info);
      77     3750000 :   return -computeFluxRHSContribution() / _scaling_coeff(face_arg, determineState());
      78             : }
      79             : 
      80             : Real
      81      699424 : LinearFVTurbulentDiffusion::computeBoundaryMatrixContribution(const LinearFVBoundaryCondition & bc)
      82             : {
      83             :   const auto * const diff_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc);
      84             :   mooseAssert(diff_bc, "This should be a valid BC!");
      85             : 
      86      699424 :   auto grad_contrib = diff_bc->computeBoundaryGradientMatrixContribution() * _current_face_area;
      87             :   // If the boundary condition does not include the diffusivity contribution then
      88             :   // add it here.
      89      699424 :   if (!diff_bc->includesMaterialPropertyMultiplier())
      90             :   {
      91      699424 :     const auto face_arg = singleSidedFaceArg(_current_face_info);
      92      699424 :     grad_contrib *= _diffusion_coeff(face_arg, determineState());
      93             :   }
      94             : 
      95      699424 :   return grad_contrib;
      96             : }
      97             : 
      98             : Real
      99      699424 : LinearFVTurbulentDiffusion::computeBoundaryRHSContribution(const LinearFVBoundaryCondition & bc)
     100             : {
     101             :   const auto * const diff_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc);
     102             :   mooseAssert(diff_bc, "This should be a valid BC!");
     103             : 
     104      699424 :   const auto face_arg = singleSidedFaceArg(_current_face_info);
     105      699424 :   auto grad_contrib = diff_bc->computeBoundaryGradientRHSContribution() * _current_face_area;
     106             : 
     107             :   // If the boundary condition does not include the diffusivity contribution then
     108             :   // add it here.
     109      699424 :   if (!diff_bc->includesMaterialPropertyMultiplier())
     110      699424 :     grad_contrib *= _diffusion_coeff(face_arg, determineState());
     111             : 
     112             :   // We add the nonorthogonal corrector for the face here. Potential idea: we could do
     113             :   // this in the boundary condition too. For now, however, we keep it like this.
     114      699424 :   if (_use_nonorthogonal_correction)
     115             :   {
     116             :     const auto correction_vector =
     117             :         _current_face_info->normal() -
     118           0 :         1 / (_current_face_info->normal() * _current_face_info->eCN()) * _current_face_info->eCN();
     119             : 
     120           0 :     grad_contrib += _diffusion_coeff(face_arg, determineState()) *
     121           0 :                     _var.gradSln(*_current_face_info->elemInfo()) * correction_vector *
     122           0 :                     _current_face_area;
     123             :   }
     124             : 
     125      699424 :   return grad_contrib;
     126             : }
     127             : 
     128             : void
     129     5033872 : LinearFVTurbulentDiffusion::addMatrixContribution()
     130             : {
     131             :   // Coumputing bounding map
     132     5033872 :   const Elem * elem = _current_face_info->elemPtr();
     133             :   const auto bounded_elem = _wall_bounded.find(elem) != _wall_bounded.end();
     134     8848160 :   const Elem * neighbor = _current_face_info->neighborPtr();
     135             :   const auto bounded_neigh = _wall_bounded.find(neighbor) != _wall_bounded.end();
     136             : 
     137             :   // If we are on an internal face, we populate the four entries in the system matrix
     138             :   // which touch the face
     139     5033872 :   if (_current_face_type == FaceInfo::VarFaceNeighbors::BOTH)
     140             :   {
     141             :     // The dof ids of the variable corresponding to the element and neighbor
     142     3750000 :     _dof_indices(0) = _current_face_info->elemInfo()->dofIndices()[_sys_num][_var_num];
     143     3750000 :     _dof_indices(1) = _current_face_info->neighborInfo()->dofIndices()[_sys_num][_var_num];
     144             : 
     145             :     // Compute the entries which will go to the neighbor (offdiagonal) and element
     146             :     // (diagonal).
     147     3750000 :     const auto elem_matrix_contribution = computeElemMatrixContribution();
     148     3750000 :     const auto neighbor_matrix_contribution = computeNeighborMatrixContribution();
     149             : 
     150             :     // Populate matrix
     151     3750000 :     if (hasBlocks(_current_face_info->elemInfo()->subdomain_id()) && !(bounded_elem))
     152             :     {
     153     3364580 :       _matrix_contribution(0, 0) = elem_matrix_contribution;
     154     3364580 :       _matrix_contribution(0, 1) = neighbor_matrix_contribution;
     155             :     }
     156             : 
     157     3750000 :     if (hasBlocks(_current_face_info->neighborInfo()->subdomain_id()) && !(bounded_neigh))
     158             :     {
     159     3368820 :       _matrix_contribution(1, 0) = -elem_matrix_contribution;
     160     3368820 :       _matrix_contribution(1, 1) = -neighbor_matrix_contribution;
     161             :     }
     162     3750000 :     (*_linear_system.matrix).add_matrix(_matrix_contribution, _dof_indices.get_values());
     163             :   }
     164             :   // We are at a block boundary where the variable is not defined on one of the adjacent cells.
     165             :   // We check if we have a boundary condition here
     166     1283872 :   else if (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
     167             :            _current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
     168             :   {
     169             :     mooseAssert(_current_face_info->boundaryIDs().size() == 1,
     170             :                 "We should only have one boundary on every face.");
     171             : 
     172             :     LinearFVBoundaryCondition * bc_pointer =
     173     1283872 :         _var.getBoundaryCondition(*_current_face_info->boundaryIDs().begin());
     174             : 
     175     1283872 :     if (bc_pointer || _force_boundary_execution)
     176             :     {
     177             :       if (bc_pointer)
     178      699424 :         bc_pointer->setupFaceData(_current_face_info, _current_face_type);
     179      699424 :       const auto matrix_contribution = computeBoundaryMatrixContribution(*bc_pointer);
     180             : 
     181             :       // We allow internal (for the mesh) boundaries too, so we have to check on which side we
     182             :       // are on (assuming that this is a boundary for the variable)
     183      699424 :       if ((_current_face_type == FaceInfo::VarFaceNeighbors::ELEM) && !(bounded_elem))
     184             :       {
     185      597832 :         const auto dof_id_elem = _current_face_info->elemInfo()->dofIndices()[_sys_num][_var_num];
     186      597832 :         (*_linear_system.matrix).add(dof_id_elem, dof_id_elem, matrix_contribution);
     187             :       }
     188      101592 :       else if ((_current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR) && !(bounded_neigh))
     189             :       {
     190             :         const auto dof_id_neighbor =
     191           0 :             _current_face_info->neighborInfo()->dofIndices()[_sys_num][_var_num];
     192           0 :         (*_linear_system.matrix).add(dof_id_neighbor, dof_id_neighbor, matrix_contribution);
     193             :       }
     194             :     }
     195             :   }
     196     5033872 : }
     197             : 
     198             : void
     199     5033872 : LinearFVTurbulentDiffusion::addRightHandSideContribution()
     200             : {
     201             :   // Coumputing bounding map
     202     5033872 :   const Elem * elem = _current_face_info->elemPtr();
     203             :   const auto bounded_elem = _wall_bounded.find(elem) != _wall_bounded.end();
     204     8848160 :   const Elem * neighbor = _current_face_info->neighborPtr();
     205             :   const auto bounded_neigh = _wall_bounded.find(neighbor) != _wall_bounded.end();
     206             : 
     207             :   // If we are on an internal face, we populate the two entries in the right hand side
     208             :   // which touch the face
     209     5033872 :   if (_current_face_type == FaceInfo::VarFaceNeighbors::BOTH)
     210             :   {
     211             :     // The dof ids of the variable corresponding to the element and neighbor
     212     3750000 :     _dof_indices(0) = _current_face_info->elemInfo()->dofIndices()[_sys_num][_var_num];
     213     3750000 :     _dof_indices(1) = _current_face_info->neighborInfo()->dofIndices()[_sys_num][_var_num];
     214             : 
     215             :     // Compute the entries which will go to the neighbor and element positions.
     216     3750000 :     const auto elem_rhs_contribution = computeElemRightHandSideContribution();
     217     3750000 :     const auto neighbor_rhs_contribution = computeNeighborRightHandSideContribution();
     218             : 
     219             :     // Populate right hand side
     220     3750000 :     if (hasBlocks(_current_face_info->elemInfo()->subdomain_id()))
     221     3750000 :       _rhs_contribution(0) = elem_rhs_contribution;
     222     3750000 :     if (hasBlocks(_current_face_info->neighborInfo()->subdomain_id()))
     223     3750000 :       _rhs_contribution(1) = neighbor_rhs_contribution;
     224             : 
     225     3750000 :     (*_linear_system.rhs)
     226     3750000 :         .add_vector(_rhs_contribution.get_values().data(), _dof_indices.get_values());
     227             :   }
     228             :   // We are at a block boundary where the variable is not defined on one of the adjacent cells.
     229             :   // We check if we have a boundary condition here
     230     1283872 :   else if (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
     231             :            _current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
     232             :   {
     233             :     mooseAssert(_current_face_info->boundaryIDs().size() == 1,
     234             :                 "We should only have one boundary on every face.");
     235             :     LinearFVBoundaryCondition * bc_pointer =
     236     1283872 :         _var.getBoundaryCondition(*_current_face_info->boundaryIDs().begin());
     237             : 
     238     1283872 :     if (bc_pointer || _force_boundary_execution)
     239             :     {
     240             :       if (bc_pointer)
     241      699424 :         bc_pointer->setupFaceData(_current_face_info, _current_face_type);
     242             : 
     243      699424 :       const auto rhs_contribution = computeBoundaryRHSContribution(*bc_pointer);
     244             : 
     245             :       // We allow internal (for the mesh) boundaries too, so we have to check on which side we
     246             :       // are on (assuming that this is a boundary for the variable)
     247      699424 :       if ((_current_face_type == FaceInfo::VarFaceNeighbors::ELEM) && !(bounded_elem))
     248             :       {
     249      597832 :         const auto dof_id_elem = _current_face_info->elemInfo()->dofIndices()[_sys_num][_var_num];
     250      597832 :         (*_linear_system.rhs).add(dof_id_elem, rhs_contribution);
     251             :       }
     252      101592 :       else if ((_current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR) && !(bounded_neigh))
     253             :       {
     254             :         const auto dof_id_neighbor =
     255           0 :             _current_face_info->neighborInfo()->dofIndices()[_sys_num][_var_num];
     256           0 :         (*_linear_system.rhs).add(dof_id_neighbor, rhs_contribution);
     257             :       }
     258             :     }
     259             :   }
     260     5033872 : }

Generated by: LCOV version 1.14