v0.16.0
Loading...
Searching...
No Matches
ThermalRadiation.hpp
Go to the documentation of this file.
1/**
2 * @file ThermalRadiation.hpp
3 * @author Andrei Shvarts (andrei.shvarts@glasgow.ac.uk)
4 * @brief Implementation of thermal radiation bc
5 * @version 0.14.0
6 * @date 2024-08-23
7 */
8
9namespace ThermoElasticOps {
10
11template <CubitBC BC> struct RadiationBcType {};
12
13template <CubitBC BC> struct GetRadiationParameters;
14
15template <> struct GetRadiationParameters<BLOCKSET> {
17
18 static MoFEMErrorCode
19 getParameters(double &stefan_boltzmann_constant, double &emissivity_parameter,
20 double &ambient_temperature, boost::shared_ptr<Range> &ents,
21 MoFEM::Interface &m_field, int ms_id, Sev sev) {
22
24
25 auto cubit_meshset_ptr =
26 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
27 BLOCKSET);
28 auto *json_config = m_field.getInterface<JsonConfigManager>();
29 const auto params_from_json =
30 json_config->getParamsFromBlockset("RADIATION", ms_id);
31 if (!params_from_json.empty()) {
32 stefan_boltzmann_constant =
33 params_from_json.at("stefan_boltzmann_constant");
34 emissivity_parameter = params_from_json.at("emissivity");
35 ambient_temperature = params_from_json.at("ambient_temperature");
36 } else {
37 std::vector<double> block_data;
38 CHKERR cubit_meshset_ptr->getAttributes(block_data);
39 if (block_data.size() < 3) {
40 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
41 "Expected that radiation block has three attributes "
42 "(Stefan–Boltzmann "
43 "constant, emissivity parameter, and ambient temperature)");
44 }
45 stefan_boltzmann_constant = block_data[0];
46 emissivity_parameter = block_data[1];
47 ambient_temperature = block_data[2];
48 }
49
50 MOFEM_LOG_CHANNEL("WORLD");
51 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "RadiationBc")
52 << "Stefan–Boltzmann constant " << stefan_boltzmann_constant;
53 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "RadiationBc")
54 << "Emissivity parameter " << emissivity_parameter;
55 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "RadiationBc")
56 << "Ambient temperature " << ambient_temperature;
57
58 ents = boost::make_shared<Range>();
59 CHKERR m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
60 *(ents), true);
61
62 MOFEM_LOG_CHANNEL("SYNC");
63 MOFEM_TAG_AND_LOG("SYNC", Sev::noisy, "RadiationBc") << *ents;
64 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
65
67 }
68};
69
70} // namespace ThermoElasticOps
71
72template <AssemblyType A, typename EleOp>
73struct OpFluxRhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1, A,
74 GAUSS, EleOp> : OpBaseImpl<A, EleOp> {
75
77
78 OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id, std::string field_name,
79 boost::shared_ptr<VectorDouble> t_ptr,
80 std::vector<boost::shared_ptr<ScalingMethod>> smv);
81
82protected:
86 boost::shared_ptr<VectorDouble> tPtr;
87 std::vector<boost::shared_ptr<ScalingMethod>> vecOfTimeScalingMethods;
88 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &data);
89};
90
91template <AssemblyType A, typename EleOp>
92struct OpFluxLhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1, A,
93 GAUSS, EleOp> : OpBaseImpl<A, EleOp> {
94
96
97 OpFluxLhsImpl(MoFEM::Interface &m_field, int ms_id,
98 std::string row_field_name, std::string col_field_name,
99 boost::shared_ptr<VectorDouble> t_ptr);
100
101protected:
105 boost::shared_ptr<VectorDouble>
106 tPtr; // pointer for boundary temperature field
107 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
108 EntitiesFieldData::EntData &col_data);
109};
110
111template <AssemblyType A, typename EleOp>
112OpFluxRhsImpl<
114 EleOp>::OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
115 std::string field_name,
116 boost::shared_ptr<VectorDouble> t_ptr,
117 std::vector<boost::shared_ptr<ScalingMethod>> smv)
118 : OpBase(field_name, field_name, OpBase::OPROW), tPtr(t_ptr),
119 vecOfTimeScalingMethods(smv) {
122 this->stefanBoltzmanConstant, this->emmisivityParameter,
123 this->ambientTemperature, this->entsPtr, m_field, ms_id, Sev::inform),
124 "Cannot read radiation data from blockset");
125}
126
127template <AssemblyType A, typename EleOp>
128MoFEMErrorCode
130 GAUSS, EleOp>::iNtegrate(EntitiesFieldData::EntData
131 &row_data) {
133
134 // get integration weights
135 auto t_w = OpBase::getFTensor0IntegrationWeight();
136 // get base function values on rows
137 auto t_row_base = row_data.getFTensor0N();
138 // get temperature
139 auto t_temp = getFTensor0FromVec(*tPtr);
140
141 double s = 1;
142 for (auto &o : vecOfTimeScalingMethods) {
143 s *= o->getScale(OpBase::getTStime());
144 }
145
146 // loop over integration points
147 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
148 const auto alpha = -t_w * (std::pow(static_cast<double>(t_temp), 4) -
149 std::pow(ambientTemperature * s, 4));
150
151 int rr = 0;
152 for (; rr != OpBase::nbRows; ++rr) {
153 OpBase::locF[rr] += (alpha * t_row_base);
154 ++t_row_base;
155 }
156
157 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
158 ++t_row_base;
159
160 ++t_w;
161 ++t_temp;
162 }
163
164 // get normal vector
165 auto t_normal = OpBase::getFTensor1Normal();
166 OpBase::locF *= t_normal.l2() * stefanBoltzmanConstant * emmisivityParameter;
167
168 EntityType fe_type = OpBase::getNumeredEntFiniteElementPtr()->getEntType();
169 if (fe_type == MBTRI) {
170 OpBase::locF /= 2;
171 }
172
174}
175
176template <AssemblyType A, typename EleOp>
177OpFluxLhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1, A, GAUSS,
178 EleOp>::OpFluxLhsImpl(MoFEM::Interface &m_field, int ms_id,
179 std::string row_field_name,
180 std::string col_field_name,
181 boost::shared_ptr<VectorDouble> t_ptr)
182 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL), tPtr(t_ptr) {
183
184 this->sYmm = true;
185
188 this->stefanBoltzmanConstant, this->emmisivityParameter,
189 this->ambientTemperature, this->entsPtr, m_field, ms_id,
190 Sev::verbose),
191 "Can not read radiation bc from blockset");
192}
193
194template <AssemblyType A, typename EleOp>
195MoFEMErrorCode
197 GAUSS,
198 EleOp>::iNtegrate(EntitiesFieldData::EntData &row_data,
199 EntitiesFieldData::EntData &col_data) {
200
202 // get integration weights
203 auto t_w = OpBase::getFTensor0IntegrationWeight();
204 // get base function values on rows
205 auto t_row_base = row_data.getFTensor0N();
206 // get temperature
207 auto t_temp = getFTensor0FromVec(*tPtr);
208 // loop over integration points
209 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
210 const auto alpha = t_w * 4 * std::pow(static_cast<double>(t_temp), 3);
211 ++t_w; // move to another integration weight
212 ++t_temp;
213 // loop over rows base functions
214 int rr = 0;
215 for (; rr != OpBase::nbRows; rr++) {
216 const auto beta = alpha * t_row_base;
217 // get column base functions values at gauss point gg
218 auto t_col_base = col_data.getFTensor0N(gg, 0);
219 // loop over columns
220 for (int cc = 0; cc != OpBase::nbCols; cc++) {
221 OpBase::locMat(rr, cc) += beta * t_col_base;
222 ++t_col_base;
223 }
224 ++t_row_base;
225 }
226 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
227 ++t_row_base;
228 }
229 // get normal vector
230 auto t_normal = OpBase::getFTensor1Normal();
231 // using L2 norm of normal vector for convenient area calculation for quads,
232 // tris etc.
234 -t_normal.l2() * stefanBoltzmanConstant * emmisivityParameter;
235
236 EntityType fe_type = OpBase::getNumeredEntFiniteElementPtr()->getEntType();
237 if (fe_type == MBTRI) {
238 OpBase::locMat /= 2;
239 }
240
242}
243
244template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
245 IntegrationType I, typename OpBase>
246struct AddFluxToRhsPipelineImpl<
247
248 OpFluxRhsImpl<ThermoElasticOps::RadiationBcType<BCTYPE>, BASE_DIM,
249 FIELD_DIM, A, I, OpBase>,
250 A, I, OpBase
251
252 > {
253
255
256 static MoFEMErrorCode add(
257
258 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
259 MoFEM::Interface &m_field, std::string field_name,
260 boost::shared_ptr<VectorDouble> T_ptr,
261 std::vector<boost::shared_ptr<ScalingMethod>> smv, std::string block_name,
262 Sev sev
263
264 ) {
266
267 using OP = OpFluxRhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>,
269
270 auto add_op = [&](auto &&meshset_vec_ptr) {
271 for (auto m : meshset_vec_ptr) {
272 MOFEM_TAG_AND_LOG("WORLD", sev, "OpRadiationRhs") << "Add " << *m;
273 pipeline.push_back(
274 new OP(m_field, m->getMeshsetId(), field_name, T_ptr, smv));
275 }
276 MOFEM_LOG_CHANNEL("WORLD");
277 };
278
279 switch (BCTYPE) {
280 case BLOCKSET:
281 add_op(
282
283 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
284 std::regex(
285
286 (boost::format("%s(.*)") % block_name).str()
287
288 ))
289
290 );
291
292 break;
293 default:
294 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
295 "Handling of bc type not implemented");
296 break;
297 }
299 }
300};
301
302template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
303 IntegrationType I, typename OpBase>
304struct AddFluxToLhsPipelineImpl<
305
306 OpFluxLhsImpl<ThermoElasticOps::RadiationBcType<BCTYPE>, BASE_DIM,
307 FIELD_DIM, A, I, OpBase>,
308 A, I, OpBase
309
310 > {
311
313
314 static MoFEMErrorCode add(
315
316 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
317 MoFEM::Interface &m_field, std::string row_field_name,
318 std::string col_field_name, boost::shared_ptr<VectorDouble> T_ptr,
319 std::string block_name, Sev sev
320
321 ) {
323
324 using OP = OpFluxLhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>,
326
327 auto add_op = [&](auto &&meshset_vec_ptr) {
328 for (auto m : meshset_vec_ptr) {
329 MOFEM_TAG_AND_LOG("WORLD", sev, "OpRadiationLhs") << "Add " << *m;
330 pipeline.push_back(new OP(m_field, m->getMeshsetId(), row_field_name,
331 col_field_name, T_ptr));
332 }
333 MOFEM_LOG_CHANNEL("WORLD");
334 };
335
336 switch (BCTYPE) {
337 case BLOCKSET:
338 add_op(
339
340 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
341 std::regex(
342
343 (boost::format("%s(.*)") % block_name).str()
344
345 ))
346
347 );
348
349 break;
350 default:
351 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
352 "Handling of bc type not implemented");
353 break;
354 }
356 }
357};
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
constexpr int FIELD_DIM
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
CubitBC
Types of sets and boundary conditions.
@ BLOCKSET
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr int BASE_DIM
IntegrationType
Form integrator integration types.
AssemblyType
[Storage and set boundary conditions]
@ GAUSS
Gaussian quadrature integration.
@ PETSC
Standard PETSc assembly.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
constexpr IntegrationType I
constexpr AssemblyType A
constexpr auto field_name
FTensor::Index< 'm', 3 > m
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, std::string row_field_name, std::string col_field_name, boost::shared_ptr< VectorDouble > T_ptr, std::string block_name, Sev sev)
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, std::string field_name, boost::shared_ptr< VectorDouble > T_ptr, std::vector< boost::shared_ptr< ScalingMethod > > smv, std::string block_name, Sev sev)
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
Deprecated interface functions.
VectorDouble locF
local entity vector
int nbRows
number of dofs on rows
int nbIntegrationPts
number of integration points
MatrixDouble locMat
local entity block matrix
int nbCols
number if dof on column
int nbRowBaseFunctions
number or row base functions
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
static MoFEMErrorCode getParameters(double &stefan_boltzmann_constant, double &emissivity_parameter, double &ambient_temperature, boost::shared_ptr< Range > &ents, MoFEM::Interface &m_field, int ms_id, Sev sev)