LCOV - code coverage report
Current view: top level - src/userobjects - UnobstructedPlanarViewFactor.C (source / functions) Hit Total Coverage
Test: idaholab/moose heat_transfer: #32971 (54bef8) with base c6cf66 Lines: 77 88 87.5 %
Date: 2026-05-29 20:37:03 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 "UnobstructedPlanarViewFactor.h"
      11             : #include "Assembly.h"
      12             : #include "MathUtils.h"
      13             : 
      14             : #include "libmesh/quadrature.h"
      15             : #include "libmesh/fe_base.h"
      16             : #include "libmesh/mesh_generation.h"
      17             : #include "libmesh/mesh.h"
      18             : #include "libmesh/string_to_enum.h"
      19             : #include "libmesh/quadrature_gauss.h"
      20             : #include "libmesh/point_locator_base.h"
      21             : #include "libmesh/elem.h"
      22             : 
      23             : registerMooseObject("HeatTransferApp", UnobstructedPlanarViewFactor);
      24             : 
      25             : InputParameters
      26         135 : UnobstructedPlanarViewFactor::validParams()
      27             : {
      28         135 :   InputParameters params = ViewFactorBase::validParams();
      29         135 :   params.addClassDescription(
      30             :       "Computes the view factors for planar faces in unubstructed radiative heat transfer.");
      31         135 :   return params;
      32           0 : }
      33             : 
      34          72 : UnobstructedPlanarViewFactor::UnobstructedPlanarViewFactor(const InputParameters & parameters)
      35             :   : ViewFactorBase(parameters),
      36          72 :     _boundary_info(nullptr),
      37             :     _current_remote_side(nullptr),
      38             :     _current_remote_fe(nullptr),
      39          72 :     _current_remote_JxW(nullptr),
      40          72 :     _current_remote_xyz(nullptr),
      41          72 :     _current_remote_normals(nullptr)
      42             : {
      43          72 :   _mesh.errorIfDistributedMesh("UnobstructedPlanarViewFactor");
      44             : 
      45          72 :   if (_mesh.dimension() == 1)
      46           0 :     mooseError("View factor calculations for 1D geometry makes no sense");
      47          72 :   else if (_mesh.dimension() == 2)
      48             :   {
      49          48 :     _exponent = 1;
      50          48 :     _divisor = 2;
      51             :   }
      52             :   else
      53             :   {
      54          24 :     _exponent = 2;
      55          24 :     _divisor = libMesh::pi;
      56             :   }
      57          72 : }
      58             : 
      59             : void
      60        1460 : UnobstructedPlanarViewFactor::execute()
      61             : {
      62        1460 :   ViewFactorBase::execute();
      63             : 
      64        1460 :   auto current_boundary_name = _mesh.getBoundaryName(_current_boundary_id);
      65        1460 :   if (_side_name_index.find(current_boundary_name) == _side_name_index.end())
      66           0 :     mooseError("Current boundary name: ",
      67             :                current_boundary_name,
      68             :                " with id ",
      69           0 :                _current_boundary_id,
      70             :                " not in boundary parameter.");
      71        1460 :   unsigned int index = _side_name_index.find(current_boundary_name)->second;
      72             : 
      73      106500 :   for (auto & side : _side_list)
      74             :   {
      75      105040 :     auto remote_boundary_name = _mesh.getBoundaryName(std::get<2>(side));
      76      105040 :     if (_side_name_index.find(remote_boundary_name) != _side_name_index.end() &&
      77       89200 :         std::get<2>(side) != _current_boundary_id)
      78             :     {
      79             :       // this is the remote side index
      80       71760 :       unsigned int remote_index = _side_name_index.find(remote_boundary_name)->second;
      81       71760 :       Real & vf = _view_factors[index][remote_index];
      82             : 
      83             :       // compute some important quantities on the face
      84       71760 :       reinitFace(std::get<0>(side), std::get<1>(side));
      85             : 
      86             :       // loop over pairs of the qps on the current side
      87      301680 :       for (unsigned int qp = 0; qp < _qrule->n_points(); ++qp)
      88             :       {
      89             :         // loop over the qps on the remote element
      90     1035360 :         for (unsigned int r_qp = 0; r_qp < _current_remote_JxW->size(); ++r_qp)
      91             :         {
      92      805440 :           Point r2r = (_q_point[qp] - (*_current_remote_xyz)[r_qp]);
      93      805440 :           Real distance = r2r.norm();
      94      805440 :           Real cos1 = r2r * _normals[qp] / distance;
      95      805440 :           Real cos2 = r2r * (*_current_remote_normals)[r_qp] / distance;
      96             : 
      97      805440 :           vf += _JxW[qp] * _coord[qp] * (*_current_remote_JxW)[r_qp] * _current_remote_coord[r_qp] *
      98      805440 :                 std::abs(cos1) * std::abs(cos2) / MathUtils::pow(distance, _exponent);
      99             :         }
     100             :       }
     101             :     }
     102             :   }
     103        1460 : }
     104             : 
     105             : void
     106          63 : UnobstructedPlanarViewFactor::initialize()
     107             : {
     108          63 :   ViewFactorBase::initialize();
     109             : 
     110             :   // get boundary info from the mesh
     111          63 :   _boundary_info = &_mesh.getMesh().get_boundary_info();
     112             : 
     113             :   // get a list of all sides
     114          63 :   _side_list = _boundary_info->build_active_side_list();
     115             : 
     116             :   // set view_factors to zero
     117         497 :   for (unsigned int j = 0; j < _n_sides; ++j)
     118             :   {
     119        3682 :     for (auto & vf : _view_factors[j])
     120        3248 :       vf = 0;
     121             :   }
     122          63 : }
     123             : 
     124             : void
     125           9 : UnobstructedPlanarViewFactor::threadJoinViewFactor(const UserObject & y)
     126             : {
     127             :   const auto & vf = static_cast<const UnobstructedPlanarViewFactor &>(y);
     128          71 :   for (unsigned int i = 0; i < _n_sides; ++i)
     129         526 :     for (unsigned int j = 0; j < _n_sides; ++j)
     130         464 :       _view_factors[i][j] += vf._view_factors[i][j];
     131           9 : }
     132             : 
     133             : void
     134          54 : UnobstructedPlanarViewFactor::finalizeViewFactor()
     135             : {
     136         426 :   for (unsigned int i = 0; i < _n_sides; ++i)
     137             :   {
     138         372 :     gatherSum(_view_factors[i]);
     139             : 
     140             :     // divide view_factor Fij by Ai and pi
     141        3156 :     for (auto & vf : _view_factors[i])
     142        2784 :       vf /= (_areas[i] * _divisor);
     143             :   }
     144          54 : }
     145             : 
     146             : void
     147       71760 : UnobstructedPlanarViewFactor::reinitFace(dof_id_type elem_id, unsigned int side)
     148             : {
     149       71760 :   const Elem * current_remote_elem = _mesh.getMesh().elem_ptr(elem_id);
     150      143520 :   _current_remote_side = current_remote_elem->build_side_ptr(side);
     151       71760 :   _current_remote_side_volume = _assembly.elementVolume(_current_remote_side.get());
     152             : 
     153       71760 :   Order order = current_remote_elem->default_order();
     154       71760 :   unsigned int dim = _mesh.getMesh().mesh_dimension();
     155      143520 :   _current_remote_fe = FEBase::build(dim, FEType(order));
     156       71760 :   libMesh::QGauss qface(dim - 1, FEType(order).default_quadrature_order());
     157       71760 :   _current_remote_fe->attach_quadrature_rule(&qface);
     158             : 
     159       71760 :   _current_remote_JxW = &_current_remote_fe->get_JxW();
     160       71760 :   _current_remote_normals = &_current_remote_fe->get_normals();
     161       71760 :   _current_remote_xyz = &_current_remote_fe->get_xyz();
     162             : 
     163       71760 :   _current_remote_fe->reinit(current_remote_elem, side);
     164             : 
     165             :   // set _coord
     166       71760 :   unsigned int n_points = _current_remote_xyz->size();
     167       71760 :   unsigned int rz_radial_coord = _subproblem.getAxisymmetricRadialCoord();
     168       71760 :   _current_remote_coord.resize(n_points);
     169       71760 :   switch (_assembly.coordSystem())
     170             :   {
     171             :     case Moose::COORD_XYZ:
     172      301680 :       for (unsigned int qp = 0; qp < n_points; qp++)
     173      229920 :         _current_remote_coord[qp] = 1.;
     174             :       break;
     175             : 
     176             :     case Moose::COORD_RZ:
     177           0 :       for (unsigned int qp = 0; qp < n_points; qp++)
     178           0 :         _current_remote_coord[qp] = 2 * M_PI * (*_current_remote_xyz)[qp](rz_radial_coord);
     179             :       break;
     180             : 
     181             :     case Moose::COORD_RSPHERICAL:
     182           0 :       for (unsigned int qp = 0; qp < n_points; qp++)
     183           0 :         _current_remote_coord[qp] =
     184           0 :             4 * M_PI * (*_current_remote_xyz)[qp](0) * (*_current_remote_xyz)[qp](0);
     185             :       break;
     186             : 
     187           0 :     default:
     188           0 :       mooseError("Unknown coordinate system");
     189             :       break;
     190             :   }
     191       71760 : }

Generated by: LCOV version 1.14