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

Generated by: LCOV version 1.14