LCOV - code coverage report
Current view: top level - src/actions - RadiationTransferAction.C (source / functions) Hit Total Coverage
Test: idaholab/moose heat_transfer: #33390 (250e9c) with base 846a5c Lines: 283 299 94.6 %
Date: 2026-07-31 18:17:22 Functions: 24 24 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 "RadiationTransferAction.h"
      11             : #include "Factory.h"
      12             : #include "MooseMesh.h"
      13             : #include "MeshGeneratorMesh.h"
      14             : #include "FEProblemBase.h"
      15             : #include "PatchSidesetGenerator.h"
      16             : #include "ViewFactorRayBC.h"
      17             : #include "ViewFactorRayStudy.h"
      18             : 
      19             : registerMooseAction("HeatTransferApp", RadiationTransferAction, "append_mesh_generator");
      20             : registerMooseAction("HeatTransferApp", RadiationTransferAction, "add_user_object");
      21             : registerMooseAction("HeatTransferApp", RadiationTransferAction, "add_bc");
      22             : registerMooseAction("HeatTransferApp", RadiationTransferAction, "add_ray_boundary_condition");
      23             : registerMooseAction("HeatTransferApp", RadiationTransferAction, "add_aux_variable");
      24             : registerMooseAction("HeatTransferApp", RadiationTransferAction, "add_aux_kernel");
      25             : 
      26             : InputParameters
      27         432 : RadiationTransferAction::validParams()
      28             : {
      29         432 :   InputParameters params = Action::validParams();
      30         432 :   params.addClassDescription(
      31             :       "This action sets up the net radiation calculation between specified sidesets.");
      32             : 
      33         864 :   params.addRequiredParam<std::vector<BoundaryName>>(
      34             :       "boundary", "The boundaries that participate in the radiative exchange.");
      35             : 
      36         864 :   params.addParam<std::vector<BoundaryName>>(
      37             :       "adiabatic_boundary",
      38             :       {},
      39             :       "The adiabatic boundaries that participate in the radiative exchange.");
      40             : 
      41         864 :   params.addParam<std::vector<BoundaryName>>(
      42             :       "fixed_temperature_boundary",
      43             :       {},
      44             :       "The fixed temperature boundaries that participate in the radiative exchange.");
      45             : 
      46         864 :   params.addParam<std::vector<FunctionName>>(
      47             :       "fixed_boundary_temperatures", {}, "The temperatures of the fixed boundary.");
      48             : 
      49         864 :   params.addRequiredParam<std::vector<unsigned int>>("n_patches",
      50             :                                                      "Number of radiation patches per sideset.");
      51             :   MultiMooseEnum partitioning(
      52         432 :       "default=-3 metis=-2 parmetis=-1 linear=0 centroid hilbert_sfc morton_sfc", "default");
      53         432 :   partitioning.addValidName("grid");
      54         864 :   params.addParam<MultiMooseEnum>(
      55             :       "partitioners",
      56             :       partitioning,
      57             :       "Specifies a mesh partitioner to use when preparing the radiation patches.");
      58             : 
      59         432 :   MultiMooseEnum direction("x y z radial");
      60         864 :   params.addParam<MultiMooseEnum>("centroid_partitioner_directions",
      61             :                                   direction,
      62             :                                   "Specifies the sort direction if using the centroid partitioner. "
      63             :                                   "Available options: x, y, z, radial");
      64             : 
      65         864 :   params.addRequiredParam<VariableName>("temperature", "The coupled temperature variable.");
      66         864 :   params.addRequiredParam<std::vector<FunctionName>>("emissivity",
      67             :                                                      "Emissivities for each boundary.");
      68             : 
      69         864 :   MooseEnum view_factor_calculator("analytical ray_tracing", "ray_tracing");
      70         864 :   params.addParam<MooseEnum>(
      71             :       "view_factor_calculator", view_factor_calculator, "The view factor calculator being used.");
      72             : 
      73         864 :   params.addParam<bool>(
      74         864 :       "print_view_factor_info", false, "Flag to print information about computed view factors.");
      75        1296 :   params.addParam<bool>("normalize_view_factor",
      76         864 :                         true,
      77             :                         "Determines if view factors are normalized to sum to one (consistent with "
      78             :                         "their definition).");
      79             : 
      80             :   std::vector<BoundaryName> empty = {};
      81         864 :   params.addParam<std::vector<BoundaryName>>(
      82             :       "symmetry_boundary",
      83             :       empty,
      84             :       "The sidesets that represent symmetry lines/planes for the problem. These sidesets do not "
      85             :       "participate in the radiative exchange"
      86             :       "so they should not be listed in the sidesets parameter.");
      87             : 
      88         864 :   MooseEnum qtypes("GAUSS GRID", "GRID");
      89         864 :   params.addParam<MooseEnum>(
      90             :       "ray_tracing_face_type", qtypes, "The face quadrature rule type used for ray tracing.");
      91             : 
      92             :   MooseEnum qorders("CONSTANT FIRST SECOND THIRD FOURTH FIFTH SIXTH SEVENTH EIGHTH NINTH TENTH "
      93             :                     "ELEVENTH TWELFTH THIRTEENTH FOURTEENTH FIFTEENTH SIXTEENTH SEVENTEENTH "
      94             :                     "EIGHTTEENTH NINTEENTH TWENTIETH",
      95         864 :                     "CONSTANT");
      96         864 :   params.addParam<MooseEnum>(
      97             :       "ray_tracing_face_order", qorders, "The face quadrature rule order used for ray tracing.");
      98             : 
      99         864 :   params.addParam<unsigned int>(
     100             :       "polar_quad_order",
     101         864 :       16,
     102             :       "Order of the polar quadrature [polar angle is between ray and normal]. Must be even. Only "
     103             :       "used if view_factor_calculator = ray_tracing.");
     104         864 :   params.addParam<unsigned int>(
     105             :       "azimuthal_quad_order",
     106         864 :       8,
     107             :       "Order of the azimuthal quadrature per quadrant [azimuthal angle is measured in "
     108             :       "a plane perpendicular to the normal]. Only used if view_factor_calculator = "
     109             :       "ray_tracing.");
     110             : 
     111         864 :   params.addParam<bool>("add_heat_flux_aux", false, "If true, add a heat flux aux variable");
     112         864 :   params.addParam<VariableName>(
     113             :       "heat_flux_variable",
     114             :       "Heat flux aux variable name; this must be provided if 'add_heat_flux_aux' is true");
     115         864 :   params.addParam<std::vector<SubdomainName>>(
     116             :       "heat_flux_aux_block", "Subdomains to use for heat flux aux if 'add_heat_flux_aux' is true");
     117             : 
     118         432 :   return params;
     119         432 : }
     120             : 
     121         432 : RadiationTransferAction::RadiationTransferAction(const InputParameters & params)
     122             :   : Action(params),
     123         432 :     _boundary_names(getParam<std::vector<BoundaryName>>("boundary")),
     124         864 :     _view_factor_calculator(getParam<MooseEnum>("view_factor_calculator")),
     125        1296 :     _add_heat_flux_aux(getParam<bool>("add_heat_flux_aux"))
     126             : {
     127         432 :   const auto & symmetry_names = getParam<std::vector<BoundaryName>>("symmetry_boundary");
     128             : 
     129         432 :   if (_view_factor_calculator != "ray_tracing")
     130             :   {
     131         720 :     for (const auto & param_name : {"polar_quad_order",
     132             :                                     "azimuthal_quad_order",
     133             :                                     "ray_tracing_face_type",
     134         900 :                                     "ray_tracing_face_order"})
     135        1440 :       if (params.isParamSetByUser(param_name))
     136           0 :         paramWarning(param_name,
     137             :                      "Only used for view_factor_calculator = ray_tracing. It is ignored for this "
     138             :                      "calculation.");
     139             : 
     140         180 :     if (symmetry_names.size())
     141           0 :       paramError("symmetry_boundary",
     142             :                  "Symmetry boundaries are only supported with view_factor_calculator = "
     143             :                  "ray_tracing.");
     144             :   }
     145             :   else
     146             :   {
     147             :     // check that there is no overlap between sidesets and symmetry sidesets
     148        1470 :     for (const auto & name : _boundary_names)
     149        1218 :       if (std::find(symmetry_names.begin(), symmetry_names.end(), name) != symmetry_names.end())
     150           0 :         paramError("boundary",
     151             :                    "Boundary ",
     152             :                    name,
     153             :                    " is present in parameter boundary and symmetry_boundary.");
     154             :   }
     155             : 
     156         432 :   if (_add_heat_flux_aux)
     157             :   {
     158          84 :     if (isParamValid("heat_flux_variable"))
     159          42 :       _heat_flux_variable = getParam<VariableName>("heat_flux_variable");
     160             :     else
     161           0 :       paramError("heat_flux_variable",
     162             :                  "If 'add_heat_flux_aux' is true, then this parameter must be provided.");
     163             : 
     164          84 :     if (isParamValid("heat_flux_aux_block"))
     165         126 :       _heat_flux_aux_block = getParam<std::vector<SubdomainName>>("heat_flux_aux_block");
     166             :     else
     167           0 :       paramError("heat_flux_aux_block",
     168             :                  "If 'add_heat_flux_aux' is true, then this parameter must be provided.");
     169             :   }
     170             : 
     171         432 :   checkBoundaryParameterIsSubset("adiabatic_boundary");
     172         432 :   checkBoundaryParameterIsSubset("fixed_temperature_boundary");
     173         432 : }
     174             : 
     175             : void
     176         864 : RadiationTransferAction::checkBoundaryParameterIsSubset(const std::string & param) const
     177             : {
     178         864 :   const auto boundary_names = getParam<std::vector<BoundaryName>>(param);
     179        1686 :   for (const auto & bname : boundary_names)
     180         822 :     if (std::find(_boundary_names.begin(), _boundary_names.end(), bname) == _boundary_names.end())
     181           0 :       paramError(param, "The boundaries in '" + param + "' must be a subset of 'boundary'.");
     182         864 : }
     183             : 
     184             : void
     185         422 : RadiationTransferAction::act()
     186             : {
     187         422 :   if (_current_task == "append_mesh_generator")
     188          72 :     addMeshGenerator();
     189         350 :   else if (_current_task == "add_user_object")
     190             :   {
     191          70 :     addRadiationObject();
     192          70 :     addRayStudyObject();
     193          70 :     addViewFactorObject();
     194             :   }
     195         280 :   else if (_current_task == "add_bc")
     196          70 :     addRadiationBCs();
     197         210 :   else if (_current_task == "add_ray_boundary_condition")
     198          70 :     addRayBCs();
     199         140 :   else if (_current_task == "add_aux_variable" && _add_heat_flux_aux)
     200           7 :     addHeatFluxAuxVariable();
     201         133 :   else if (_current_task == "add_aux_kernel" && _add_heat_flux_aux)
     202           7 :     addHeatFluxAuxKernel();
     203         422 : }
     204             : 
     205             : void
     206          70 : RadiationTransferAction::addRadiationBCs() const
     207             : {
     208          70 :   InputParameters params = _factory.getValidParams("GrayLambertNeumannBC");
     209             : 
     210             :   // set boundary
     211          70 :   std::vector<std::vector<std::string>> radiation_patch_names = bcRadiationPatchNames();
     212             :   std::vector<BoundaryName> boundary_names;
     213         252 :   for (auto & e1 : radiation_patch_names)
     214         511 :     for (auto & e2 : e1)
     215         329 :       boundary_names.push_back(e2);
     216             : 
     217          70 :   params.set<std::vector<BoundaryName>>("boundary") = boundary_names;
     218             : 
     219             :   // set temperature variable
     220         210 :   params.set<NonlinearVariableName>("variable") = getParam<VariableName>("temperature");
     221             : 
     222             :   // set radiationuserobject
     223         140 :   params.set<UserObjectName>("surface_radiation_object_name") = radiationObjectName();
     224             : 
     225         140 :   _problem->addBoundaryCondition("GrayLambertNeumannBC", "gray_lamber_neumann_bc_" + _name, params);
     226          70 : }
     227             : 
     228             : void
     229          70 : RadiationTransferAction::addViewFactorObject() const
     230             : {
     231             :   // this userobject is only executed on initial
     232          70 :   ExecFlagEnum exec_enum = MooseUtils::getDefaultExecFlagEnum();
     233         210 :   exec_enum = {EXEC_INITIAL};
     234             : 
     235          70 :   if (_view_factor_calculator == "analytical")
     236             :   {
     237             :     // this branch adds the UnobstructedPlanarViewFactor
     238          28 :     InputParameters params = _factory.getValidParams("UnobstructedPlanarViewFactor");
     239          56 :     params.set<std::vector<BoundaryName>>("boundary") = radiationPatchBoundaryNames();
     240          28 :     params.set<ExecFlagEnum>("execute_on") = exec_enum;
     241             : 
     242          56 :     _problem->addUserObject("UnobstructedPlanarViewFactor", viewFactorObjectName(), params);
     243          28 :   }
     244          42 :   else if (_view_factor_calculator == "ray_tracing")
     245             :   {
     246             :     // this branch adds the ray tracing UO
     247          42 :     InputParameters params = _factory.getValidParams("RayTracingViewFactor");
     248          84 :     params.set<std::vector<BoundaryName>>("boundary") = radiationPatchBoundaryNames();
     249          42 :     params.set<ExecFlagEnum>("execute_on") = exec_enum;
     250          84 :     params.set<UserObjectName>("ray_study_name") = rayStudyName();
     251          84 :     params.set<bool>("print_view_factor_info") = getParam<bool>("print_view_factor_info");
     252          84 :     params.set<bool>("normalize_view_factor") = getParam<bool>("normalize_view_factor");
     253          84 :     _problem->addUserObject("RayTracingViewFactor", viewFactorObjectName(), params);
     254          42 :   }
     255         140 : }
     256             : 
     257             : void
     258          70 : RadiationTransferAction::addRayStudyObject() const
     259             : {
     260          70 :   if (_view_factor_calculator == "analytical")
     261          28 :     return;
     262             : 
     263          42 :   InputParameters params = _factory.getValidParams("ViewFactorRayStudy");
     264             : 
     265          84 :   params.set<std::vector<BoundaryName>>("boundary") = radiationPatchBoundaryNames();
     266             : 
     267             :   // set this object to be execute on initial only
     268          42 :   ExecFlagEnum exec_enum = MooseUtils::getDefaultExecFlagEnum();
     269          84 :   exec_enum = {EXEC_INITIAL};
     270          42 :   params.set<ExecFlagEnum>("execute_on") = exec_enum;
     271             : 
     272             :   // set face order
     273         126 :   params.set<MooseEnum>("face_order") = getParam<MooseEnum>("ray_tracing_face_order");
     274         126 :   params.set<MooseEnum>("face_type") = getParam<MooseEnum>("ray_tracing_face_type");
     275             : 
     276             :   // set angular quadrature
     277          84 :   params.set<unsigned int>("polar_quad_order") = getParam<unsigned int>("polar_quad_order");
     278          84 :   params.set<unsigned int>("azimuthal_quad_order") = getParam<unsigned int>("azimuthal_quad_order");
     279          84 :   _problem->addUserObject("ViewFactorRayStudy", rayStudyName(), params);
     280          84 : }
     281             : 
     282             : void
     283          70 : RadiationTransferAction::addRayBCs() const
     284             : {
     285          70 :   if (_view_factor_calculator == "analytical")
     286             :     return;
     287             : 
     288             :   {
     289          42 :     InputParameters params = _factory.getValidParams("ViewFactorRayBC");
     290          84 :     params.set<std::vector<BoundaryName>>("boundary") = radiationPatchBoundaryNames();
     291          42 :     params.set<RayTracingStudy *>("_ray_tracing_study") =
     292          42 :         &_problem->getUserObject<ViewFactorRayStudy>(rayStudyName());
     293          84 :     _problem->addObject<RayBoundaryConditionBase>("ViewFactorRayBC", rayBCName(), params);
     294          42 :   }
     295             : 
     296             :   // add symmetry BCs if applicable
     297          84 :   const auto & symmetry_names = getParam<std::vector<BoundaryName>>("symmetry_boundary");
     298          42 :   if (symmetry_names.size() > 0)
     299             :   {
     300           7 :     InputParameters params = _factory.getValidParams("ReflectRayBC");
     301           7 :     params.set<std::vector<BoundaryName>>("boundary") = symmetry_names;
     302           7 :     params.set<RayTracingStudy *>("_ray_tracing_study") =
     303           7 :         &_problem->getUserObject<ViewFactorRayStudy>(rayStudyName());
     304          14 :     _problem->addObject<RayBoundaryConditionBase>("ReflectRayBC", symmetryRayBCName(), params);
     305           7 :   }
     306             : }
     307             : 
     308             : UserObjectName
     309         133 : RadiationTransferAction::rayStudyName() const
     310             : {
     311         266 :   return "ray_study_uo_" + _name;
     312             : }
     313             : 
     314             : std::string
     315          42 : RadiationTransferAction::rayBCName() const
     316             : {
     317          42 :   return "ray_bc_" + _name;
     318             : }
     319             : 
     320             : std::string
     321           7 : RadiationTransferAction::symmetryRayBCName() const
     322             : {
     323           7 :   return "symmetry_ray_bc_" + _name;
     324             : }
     325             : 
     326             : UserObjectName
     327         140 : RadiationTransferAction::viewFactorObjectName() const
     328             : {
     329         280 :   return "view_factor_uo_" + _name;
     330             : }
     331             : 
     332             : UserObjectName
     333         147 : RadiationTransferAction::radiationObjectName() const
     334             : {
     335         294 :   return "view_factor_surface_radiation_" + _name;
     336             : }
     337             : 
     338             : void
     339          70 : RadiationTransferAction::addRadiationObject() const
     340             : {
     341          70 :   std::vector<std::vector<std::string>> radiation_patch_names = radiationPatchNames();
     342             : 
     343             :   // input parameter check
     344         210 :   std::vector<FunctionName> emissivity = getParam<std::vector<FunctionName>>("emissivity");
     345          70 :   if (emissivity.size() != _boundary_names.size())
     346           0 :     mooseError("emissivity parameter needs to be the same size as the boundary parameter.");
     347             : 
     348             :   // the action only sets up ViewFactorObjectSurfaceRadiation, because after splitting
     349             :   // faces auotmatically, it makes no sense to require view factor input by hand.
     350          70 :   InputParameters params = _factory.getValidParams("ViewFactorObjectSurfaceRadiation");
     351         210 :   params.set<std::vector<VariableName>>("temperature") = {getParam<VariableName>("temperature")};
     352             : 
     353             :   std::vector<FunctionName> extended_emissivity;
     354         385 :   for (unsigned int j = 0; j < _boundary_names.size(); ++j)
     355         896 :     for (unsigned int i = 0; i < nPatch(j); ++i)
     356         581 :       extended_emissivity.push_back(emissivity[j]);
     357          70 :   params.set<std::vector<FunctionName>>("emissivity") = extended_emissivity;
     358             : 
     359             :   // add boundary parameter
     360         140 :   params.set<std::vector<BoundaryName>>("boundary") = radiationPatchBoundaryNames();
     361             : 
     362             :   // add adiabatic_boundary parameter if required
     363         140 :   if (isParamValid("adiabatic_boundary"))
     364         140 :     params.set<std::vector<BoundaryName>>("adiabatic_boundary") = adiabaticPatchBoundaryNames();
     365             : 
     366             :   // add isothermal sidesets if required
     367         140 :   if (isParamValid("fixed_temperature_boundary"))
     368             :   {
     369         140 :     if (!isParamValid("fixed_boundary_temperatures"))
     370           0 :       mooseError("fixed_temperature_boundary is provided so fixed_boundary_temperatures must be "
     371             :                  "provided too");
     372             : 
     373             :     std::vector<BoundaryName> fixed_T_boundary_names =
     374         140 :         getParam<std::vector<BoundaryName>>("fixed_temperature_boundary");
     375             : 
     376             :     std::vector<FunctionName> fixed_T_funcs =
     377         210 :         getParam<std::vector<FunctionName>>("fixed_boundary_temperatures");
     378             : 
     379             :     // check length of fixed_boundary_temperatures
     380          70 :     if (fixed_T_funcs.size() != fixed_T_boundary_names.size())
     381           0 :       mooseError("Size of parameter fixed_boundary_temperatures and fixed_temperature_boundary "
     382             :                  "must be equal.");
     383             : 
     384             :     std::vector<BoundaryName> fixed_T_patch_names;
     385             :     std::vector<FunctionName> fixed_T_function_names;
     386         105 :     for (unsigned int k = 0; k < fixed_T_boundary_names.size(); ++k)
     387             :     {
     388             :       BoundaryName bnd_name = fixed_T_boundary_names[k];
     389             : 
     390             :       // find the right entry in _boundary_names
     391          35 :       auto it = std::find(_boundary_names.begin(), _boundary_names.end(), bnd_name);
     392             : 
     393             :       // check if entry was found: it must be found or an error would occur later
     394          35 :       if (it == _boundary_names.end())
     395           0 :         mooseError("Fixed temperature sideset ", bnd_name, " not present in boundary.");
     396             : 
     397             :       // this is the position in the _boundary_names vector; this is what
     398             :       // we are really after
     399             :       auto index = std::distance(_boundary_names.begin(), it);
     400             : 
     401             :       // collect the correct boundary names
     402         105 :       for (auto & e : radiation_patch_names[index])
     403             :       {
     404          70 :         fixed_T_patch_names.push_back(e);
     405          70 :         fixed_T_function_names.push_back(fixed_T_funcs[k]);
     406             :       }
     407             :     }
     408          70 :     params.set<std::vector<BoundaryName>>("fixed_temperature_boundary") = fixed_T_patch_names;
     409          70 :     params.set<std::vector<FunctionName>>("fixed_boundary_temperatures") = fixed_T_function_names;
     410          70 :   }
     411             : 
     412             :   // the view factor userobject name
     413         140 :   params.set<UserObjectName>("view_factor_object_name") = viewFactorObjectName();
     414             : 
     415             :   // this userobject needs to be executed on linear and timestep end
     416          70 :   ExecFlagEnum exec_enum = MooseUtils::getDefaultExecFlagEnum();
     417         210 :   exec_enum = {EXEC_LINEAR, EXEC_TIMESTEP_END};
     418          70 :   params.set<ExecFlagEnum>("execute_on") = exec_enum;
     419             : 
     420             :   // add the object
     421         140 :   _problem->addUserObject("ViewFactorObjectSurfaceRadiation", radiationObjectName(), params);
     422         280 : }
     423             : 
     424             : std::vector<std::vector<std::string>>
     425          70 : RadiationTransferAction::radiationPatchNames() const
     426             : {
     427          70 :   std::vector<std::vector<std::string>> radiation_patch_names(_boundary_names.size());
     428          70 :   std::vector<BoundaryID> boundary_ids = _mesh->getBoundaryIDs(_boundary_names);
     429         385 :   for (unsigned int j = 0; j < boundary_ids.size(); ++j)
     430             :   {
     431         315 :     boundary_id_type bid = boundary_ids[j];
     432         315 :     std::string base_name = _mesh->getBoundaryName(bid);
     433             :     std::vector<std::string> bnames;
     434         896 :     for (unsigned int i = 0; i < nPatch(j); ++i)
     435             :     {
     436         581 :       std::stringstream ss;
     437         581 :       ss << base_name << "_" << i;
     438         581 :       bnames.push_back(ss.str());
     439         581 :     }
     440         315 :     radiation_patch_names[j] = bnames;
     441         315 :   }
     442          70 :   return radiation_patch_names;
     443          70 : }
     444             : 
     445             : std::vector<std::vector<std::string>>
     446          70 : RadiationTransferAction::bcRadiationPatchNames() const
     447             : {
     448         140 :   auto ad_bnd_names = getParam<std::vector<BoundaryName>>("adiabatic_boundary");
     449         210 :   auto ft_bnd_names = getParam<std::vector<BoundaryName>>("fixed_temperature_boundary");
     450             :   std::vector<std::vector<std::string>> radiation_patch_names;
     451          70 :   std::vector<BoundaryID> boundary_ids = _mesh->getBoundaryIDs(_boundary_names);
     452         385 :   for (unsigned int j = 0; j < boundary_ids.size(); ++j)
     453             :   {
     454         315 :     boundary_id_type bid = boundary_ids[j];
     455             :     BoundaryName bnd_name = _boundary_names[j];
     456             : 
     457             :     // check if this sideset is adiabatic or isothermal
     458         315 :     auto it_a = std::find(ad_bnd_names.begin(), ad_bnd_names.end(), bnd_name);
     459         315 :     auto it_t = std::find(ft_bnd_names.begin(), ft_bnd_names.end(), bnd_name);
     460         315 :     if (it_a != ad_bnd_names.end() || it_t != ft_bnd_names.end())
     461             :       continue;
     462             : 
     463         182 :     std::string base_name = _mesh->getBoundaryName(bid);
     464             :     std::vector<std::string> bnames;
     465         511 :     for (unsigned int i = 0; i < nPatch(j); ++i)
     466             :     {
     467         329 :       std::stringstream ss;
     468         329 :       ss << base_name << "_" << i;
     469         329 :       bnames.push_back(ss.str());
     470         329 :     }
     471         182 :     radiation_patch_names.push_back(bnames);
     472         182 :   }
     473          70 :   return radiation_patch_names;
     474          70 : }
     475             : 
     476             : std::vector<BoundaryName>
     477         301 : RadiationTransferAction::patchBoundaryNames(
     478             :     const std::vector<BoundaryName> & boundary_names_or_ids) const
     479             : {
     480             :   std::vector<BoundaryName> patch_boundary_names;
     481         301 :   std::vector<BoundaryID> ids = _mesh->getBoundaryIDs(boundary_names_or_ids);
     482        1463 :   for (const auto i : index_range(boundary_names_or_ids))
     483             :   {
     484             :     const auto boundary_name_or_id = boundary_names_or_ids[i];
     485        1162 :     const auto it = std::find(_boundary_names.begin(), _boundary_names.end(), boundary_name_or_id);
     486             :     mooseAssert(it != _boundary_names.end(), boundary_name_or_id + " not found in 'boundary'.");
     487             :     const auto boundary_index = std::distance(_boundary_names.begin(), it);
     488        1162 :     const auto n_patches = nPatch(boundary_index);
     489        1162 :     const auto boundary_name = _mesh->getBoundaryName(ids[i]);
     490        3227 :     for (const auto j : make_range(n_patches))
     491             :     {
     492        2065 :       std::stringstream ss;
     493        2065 :       ss << boundary_name << "_" << j;
     494        2065 :       patch_boundary_names.push_back(ss.str());
     495        2065 :     }
     496             :   }
     497         301 :   return patch_boundary_names;
     498         301 : }
     499             : 
     500             : std::vector<BoundaryName>
     501         231 : RadiationTransferAction::radiationPatchBoundaryNames() const
     502             : {
     503         231 :   return patchBoundaryNames(_boundary_names);
     504             : }
     505             : 
     506             : std::vector<BoundaryName>
     507          70 : RadiationTransferAction::adiabaticPatchBoundaryNames() const
     508             : {
     509             :   std::vector<BoundaryName> patch_boundary_names;
     510         140 :   if (isParamValid("adiabatic_boundary"))
     511             :     patch_boundary_names =
     512         280 :         patchBoundaryNames(getParam<std::vector<BoundaryName>>("adiabatic_boundary"));
     513          70 :   return patch_boundary_names;
     514           0 : }
     515             : 
     516             : void
     517          72 : RadiationTransferAction::addMeshGenerator()
     518             : {
     519         144 :   std::vector<unsigned int> n_patches = getParam<std::vector<unsigned int>>("n_patches");
     520         144 :   MultiMooseEnum partitioners = getParam<MultiMooseEnum>("partitioners");
     521         144 :   if (!_pars.isParamSetByUser("partitioners"))
     522             :   {
     523          14 :     partitioners.clearSetValues();
     524          70 :     for (unsigned int j = 0; j < _boundary_names.size(); ++j)
     525         112 :       partitioners.setAdditionalValue("metis");
     526             :   }
     527             : 
     528         216 :   MultiMooseEnum direction = getParam<MultiMooseEnum>("centroid_partitioner_directions");
     529             : 
     530             :   // check input parameters
     531          72 :   if (_boundary_names.size() != n_patches.size())
     532           0 :     mooseError("n_patches parameter must have same length as boundary parameter.");
     533             : 
     534          72 :   if (_boundary_names.size() != partitioners.size())
     535           0 :     mooseError("partitioners parameter must have same length as boundary parameter.");
     536             : 
     537         395 :   for (unsigned int j = 0; j < partitioners.size(); ++j)
     538         323 :     if (partitioners[j] == "centroid" && direction.size() != _boundary_names.size())
     539           0 :       mooseError(
     540             :           "centroid partitioner is selected for at least one sideset. "
     541             :           "centroid_partitioner_directions parameter must have same length as boundary parameter.");
     542             : 
     543             :   // check if mesh is a MeshGeneratorMesh
     544          72 :   std::shared_ptr<MeshGeneratorMesh> mg_mesh = std::dynamic_pointer_cast<MeshGeneratorMesh>(_mesh);
     545          72 :   if (!mg_mesh)
     546           0 :     mooseError("This action adds MeshGenerator objects and therefore only works with a "
     547             :                "MeshGeneratorMesh.");
     548             : 
     549         395 :   for (unsigned int j = 0; j < _boundary_names.size(); ++j)
     550             :   {
     551         646 :     InputParameters params = _factory.getValidParams("PatchSidesetGenerator");
     552         646 :     params.set<BoundaryName>("boundary") = _boundary_names[j];
     553         323 :     params.set<unsigned int>("n_patches") = n_patches[j];
     554         323 :     params.set<MooseEnum>("partitioner") = partitioners[j];
     555             : 
     556         323 :     if (partitioners[j] == "centroid")
     557         352 :       params.set<MooseEnum>("centroid_partitioner_direction") = direction[j];
     558             : 
     559         646 :     _app.appendMeshGenerator("PatchSidesetGenerator", meshGeneratorName(j), params);
     560         323 :   }
     561          72 : }
     562             : 
     563             : unsigned int
     564        3465 : RadiationTransferAction::nPatch(unsigned int j) const
     565             : {
     566        3465 :   const MeshGenerator * mg = &_app.getMeshGenerator(meshGeneratorName(j));
     567        3465 :   const PatchSidesetGenerator * psg = dynamic_cast<const PatchSidesetGenerator *>(mg);
     568        3465 :   if (!psg)
     569           0 :     mooseError("Failed to convert mesh generator ", mg->name(), " to PatchSidesetGenerator.");
     570        3465 :   return psg->nPatches();
     571             : }
     572             : 
     573             : MeshGeneratorName
     574        3788 : RadiationTransferAction::meshGeneratorName(unsigned int j) const
     575             : {
     576        3788 :   std::stringstream ss;
     577        3788 :   ss << "patch_side_set_generator_" << _boundary_names[j];
     578        3788 :   return ss.str();
     579        3788 : }
     580             : 
     581             : void
     582           7 : RadiationTransferAction::addHeatFluxAuxVariable() const
     583             : {
     584           7 :   const std::string var_type = "MooseVariable";
     585           7 :   auto params = _factory.getValidParams(var_type);
     586           7 :   params.set<std::vector<SubdomainName>>("block") = _heat_flux_aux_block;
     587          14 :   params.set<MooseEnum>("order") = "CONSTANT";
     588          14 :   params.set<MooseEnum>("family") = "MONOMIAL";
     589           7 :   _problem->addAuxVariable(var_type, _heat_flux_variable, params);
     590          14 : }
     591             : 
     592             : void
     593           7 : RadiationTransferAction::addHeatFluxAuxKernel() const
     594             : {
     595           7 :   const std::string class_name = "GrayLambertRadiationHeatFluxAux";
     596           7 :   InputParameters params = _factory.getValidParams(class_name);
     597          14 :   params.set<AuxVariableName>("variable") = _heat_flux_variable;
     598          14 :   params.set<std::vector<BoundaryName>>("boundary") = radiationPatchBoundaryNames();
     599          14 :   params.set<UserObjectName>("surface_radiation_object") = radiationObjectName();
     600          28 :   params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
     601           7 :   _problem->addAuxKernel(class_name, "radiation_heat_flux_aux_kernel", params);
     602          21 : }

Generated by: LCOV version 1.14