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 "HSCoupler2D2DRadiationUserObject.h" 11 : #include "StoreVariableByElemIDSideUserObject.h" 12 : #include "MeshAlignment2D2D.h" 13 : #include "THMUtils.h" 14 : #include "HeatConductionNames.h" 15 : 16 : registerMooseObject("ThermalHydraulicsApp", HSCoupler2D2DRadiationUserObject); 17 : 18 : InputParameters 19 117 : HSCoupler2D2DRadiationUserObject::validParams() 20 : { 21 117 : InputParameters params = SideUserObject::validParams(); 22 : 23 234 : params.addRequiredParam<std::vector<Real>>("emissivities", "Emissivities of each surface"); 24 234 : params.addRequiredParam<std::vector<std::vector<Real>>>( 25 : "view_factors", "View factors between each surface, as a matrix"); 26 234 : params.addRequiredParam<bool>( 27 : "include_environment", 28 : "Whether or not to include an environment surrounding all of the surfaces."); 29 234 : params.addParam<Real>("T_environment", 0.0, "Environment temperature."); 30 234 : params.addRequiredParam<UserObjectName>( 31 : "temperature_uo", 32 : "StoreVariableByElemIDSideUserObjects containing the temperature values for each element"); 33 234 : params.addRequiredParam<MeshAlignment2D2D *>("mesh_alignment", "Mesh alignment object"); 34 : 35 117 : params.addClassDescription("Computes heat fluxes for HSCoupler2D2D."); 36 : 37 117 : return params; 38 0 : } 39 : 40 63 : HSCoupler2D2DRadiationUserObject::HSCoupler2D2DRadiationUserObject( 41 63 : const InputParameters & parameters) 42 : : SideUserObject(parameters), 43 : 44 63 : _emissivities(getParam<std::vector<Real>>("emissivities")), 45 126 : _view_factors(getParam<std::vector<std::vector<Real>>>("view_factors")), 46 126 : _include_environment(getParam<bool>("include_environment")), 47 126 : _T_environment(getParam<Real>("T_environment")), 48 63 : _temperature_uo(getUserObject<StoreVariableByElemIDSideUserObject>("temperature_uo")), 49 126 : _mesh_alignment(*getParam<MeshAlignment2D2D *>("mesh_alignment")), 50 63 : _n_hs(_emissivities.size()), 51 126 : _n_surfaces(_include_environment ? _n_hs + 1 : _n_hs) 52 : { 53 63 : } 54 : 55 : void 56 2736 : HSCoupler2D2DRadiationUserObject::initialize() 57 : { 58 : _elem_id_to_heat_flux.clear(); 59 2736 : } 60 : 61 : void 62 13680 : HSCoupler2D2DRadiationUserObject::execute() 63 : { 64 : using std::pow; 65 : 66 : // store element IDs corresponding to this side 67 : std::vector<dof_id_type> elem_ids; 68 13680 : elem_ids.push_back(_current_elem->id()); 69 13680 : const auto coupled_elem_ids = _mesh_alignment.getCoupledSecondaryElemIDs(elem_ids[0]); 70 13680 : elem_ids.insert(elem_ids.end(), coupled_elem_ids.begin(), coupled_elem_ids.end()); 71 : 72 : // store temperatures 73 : std::vector<std::vector<ADReal>> temperatures; 74 50480 : for (const auto & elem_id : elem_ids) 75 36800 : temperatures.push_back(_temperature_uo.getVariableValues(elem_id)); 76 : 77 : // loop over the quadrature points and compute the heat fluxes 78 13680 : const auto n_qp = _qrule->n_points(); 79 13680 : std::vector<std::vector<ADReal>> heat_fluxes(_n_hs, std::vector<ADReal>(n_qp, 0.0)); 80 41040 : for (unsigned int qp = 0; qp < n_qp; qp++) 81 : { 82 : // form matrix and RHS 83 27360 : DenseMatrix<ADReal> matrix(_n_surfaces, _n_surfaces); 84 27360 : DenseVector<ADReal> emittances(_n_surfaces); 85 110720 : for (unsigned int i = 0; i < _n_surfaces; ++i) 86 : { 87 83360 : if (_include_environment && i == _n_surfaces - 1) // environment surface 88 : { 89 9760 : emittances(i) = HeatConduction::Constants::sigma * pow(_T_environment, 4); 90 9760 : matrix(i, i) = 1.0; 91 : } 92 : else // heat structure surface 93 : { 94 : emittances(i) = 95 147200 : _emissivities[i] * HeatConduction::Constants::sigma * pow(temperatures[i][qp], 4); 96 73600 : matrix(i, i) = 1.0; 97 315840 : for (unsigned int j = 0; j < _n_surfaces; ++j) 98 242240 : matrix(i, j) -= (1 - _emissivities[i]) * _view_factors[i][j]; 99 : } 100 : } 101 : 102 : // solve for radiosities 103 27360 : DenseVector<ADReal> radiosities(_n_surfaces); 104 27360 : matrix.lu_solve(emittances, radiosities); 105 : 106 : // compute heat fluxes 107 100960 : for (unsigned int i = 0; i < _n_hs; ++i) 108 73600 : heat_fluxes[i][qp] = 109 220800 : 1.0 / (1.0 - _emissivities[i]) * (emittances(i) - _emissivities[i] * radiosities(i)); 110 27360 : } 111 : 112 : // store the heat fluxes by element ID 113 50480 : for (unsigned int i = 0; i < _n_hs; ++i) 114 36800 : _elem_id_to_heat_flux[elem_ids[i]] = heat_fluxes[i]; 115 13680 : } 116 : 117 : void 118 513 : HSCoupler2D2DRadiationUserObject::threadJoin(const UserObject & uo) 119 : { 120 : const auto & other_uo = static_cast<const HSCoupler2D2DRadiationUserObject &>(uo); 121 513 : for (auto & it : other_uo._elem_id_to_heat_flux) 122 0 : if (_elem_id_to_heat_flux.find(it.first) == _elem_id_to_heat_flux.end()) 123 0 : _elem_id_to_heat_flux[it.first] = it.second; 124 : else 125 : { 126 0 : auto & existing = _elem_id_to_heat_flux[it.first]; 127 0 : for (const auto qp : index_range(existing)) 128 0 : existing[qp] += it.second[qp]; 129 : } 130 513 : } 131 : 132 : void 133 2223 : HSCoupler2D2DRadiationUserObject::finalize() 134 : { 135 2223 : THM::allGatherADVectorMapSum(comm(), _elem_id_to_heat_flux); 136 2223 : } 137 : 138 : const std::vector<ADReal> & 139 289280 : HSCoupler2D2DRadiationUserObject::getHeatFlux(dof_id_type elem_id) const 140 : { 141 : Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx); 142 : 143 : auto it = _elem_id_to_heat_flux.find(elem_id); 144 289280 : if (it != _elem_id_to_heat_flux.end()) 145 289280 : return it->second; 146 : else 147 0 : mooseError(name(), ": Requested heat flux for element ", elem_id, " was not computed."); 148 : }