v0.15.4
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 std::vector<double> block_data;
29 CHKERR cubit_meshset_ptr->getAttributes(block_data);
30 if (block_data.size() < 3) {
31 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
32 "Expected that radiation block has three attributes "
33 "(Stefan–Boltzmann "
34 "constant, emissivity parameter, and ambient temperature)");
35 }
36 stefan_boltzmann_constant = block_data[0];
37 emissivity_parameter = block_data[1];
38 ambient_temperature = block_data[2];
39
40 MOFEM_LOG_CHANNEL("WORLD");
41 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "RadiationBc")
42 << "Stefan–Boltzmann constant " << stefan_boltzmann_constant;
43 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "RadiationBc")
44 << "Emissivity parameter " << emissivity_parameter;
45 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "RadiationBc")
46 << "Ambient temperature " << ambient_temperature;
47
48 ents = boost::make_shared<Range>();
49 CHKERR m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
50 *(ents), true);
51
52 MOFEM_LOG_CHANNEL("SYNC");
53 MOFEM_TAG_AND_LOG("SYNC", Sev::noisy, "RadiationBc") << *ents;
54 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
55
57 }
58};
59
60} // namespace ThermoElasticOps
61
62template <AssemblyType A, typename EleOp>
63struct OpFluxRhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1, A,
64 GAUSS, EleOp> : OpBaseImpl<A, EleOp> {
65
67
68 OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id, std::string field_name,
69 boost::shared_ptr<VectorDouble> t_ptr,
70 std::vector<boost::shared_ptr<ScalingMethod>> smv);
71
72protected:
76 boost::shared_ptr<VectorDouble> tPtr;
77 std::vector<boost::shared_ptr<ScalingMethod>> vecOfTimeScalingMethods;
78 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &data);
79};
80
81template <AssemblyType A, typename EleOp>
82struct OpFluxLhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1, A,
83 GAUSS, EleOp> : OpBaseImpl<A, EleOp> {
84
86
87 OpFluxLhsImpl(MoFEM::Interface &m_field, int ms_id,
88 std::string row_field_name, std::string col_field_name,
89 boost::shared_ptr<VectorDouble> t_ptr);
90
91protected:
95 boost::shared_ptr<VectorDouble>
96 tPtr; // pointer for boundary temperature field
97 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
98 EntitiesFieldData::EntData &col_data);
99};
100
101template <AssemblyType A, typename EleOp>
102OpFluxRhsImpl<
104 EleOp>::OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
105 std::string field_name,
106 boost::shared_ptr<VectorDouble> t_ptr,
107 std::vector<boost::shared_ptr<ScalingMethod>> smv)
108 : OpBase(field_name, field_name, OpBase::OPROW), tPtr(t_ptr),
109 vecOfTimeScalingMethods(smv) {
112 this->stefanBoltzmanConstant, this->emmisivityParameter,
113 this->ambientTemperature, this->entsPtr, m_field, ms_id, Sev::inform),
114 "Cannot read radiation data from blockset");
115}
116
117template <AssemblyType A, typename EleOp>
118MoFEMErrorCode
120 GAUSS, EleOp>::iNtegrate(EntitiesFieldData::EntData
121 &row_data) {
123
124 // get integration weights
125 auto t_w = OpBase::getFTensor0IntegrationWeight();
126 // get base function values on rows
127 auto t_row_base = row_data.getFTensor0N();
128 // get temperature
129 auto t_temp = getFTensor0FromVec(*tPtr);
130
131 double s = 1;
132 for (auto &o : vecOfTimeScalingMethods) {
133 s *= o->getScale(OpBase::getTStime());
134 }
135
136 // loop over integration points
137 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
138 const auto alpha = -t_w * (std::pow(static_cast<double>(t_temp), 4) -
139 std::pow(ambientTemperature * s, 4));
140
141 int rr = 0;
142 for (; rr != OpBase::nbRows; ++rr) {
143 OpBase::locF[rr] += (alpha * t_row_base);
144 ++t_row_base;
145 }
146
147 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
148 ++t_row_base;
149
150 ++t_w;
151 ++t_temp;
152 }
153
154 // get normal vector
155 auto t_normal = OpBase::getFTensor1Normal();
156 OpBase::locF *= t_normal.l2() * stefanBoltzmanConstant * emmisivityParameter;
157
158 EntityType fe_type = OpBase::getNumeredEntFiniteElementPtr()->getEntType();
159 if (fe_type == MBTRI) {
160 OpBase::locF /= 2;
161 }
162
164}
165
166template <AssemblyType A, typename EleOp>
167OpFluxLhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1, A, GAUSS,
168 EleOp>::OpFluxLhsImpl(MoFEM::Interface &m_field, int ms_id,
169 std::string row_field_name,
170 std::string col_field_name,
171 boost::shared_ptr<VectorDouble> t_ptr)
172 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL), tPtr(t_ptr) {
173
174 this->sYmm = true;
175
178 this->stefanBoltzmanConstant, this->emmisivityParameter,
179 this->ambientTemperature, this->entsPtr, m_field, ms_id,
180 Sev::verbose),
181 "Can not read radiation bc from blockset");
182}
183
184template <AssemblyType A, typename EleOp>
185MoFEMErrorCode
187 GAUSS,
188 EleOp>::iNtegrate(EntitiesFieldData::EntData &row_data,
189 EntitiesFieldData::EntData &col_data) {
190
192 // get integration weights
193 auto t_w = OpBase::getFTensor0IntegrationWeight();
194 // get base function values on rows
195 auto t_row_base = row_data.getFTensor0N();
196 // get temperature
197 auto t_temp = getFTensor0FromVec(*tPtr);
198 // loop over integration points
199 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
200 const auto alpha = t_w * 4 * std::pow(static_cast<double>(t_temp), 3);
201 ++t_w; // move to another integration weight
202 ++t_temp;
203 // loop over rows base functions
204 int rr = 0;
205 for (; rr != OpBase::nbRows; rr++) {
206 const auto beta = alpha * t_row_base;
207 // get column base functions values at gauss point gg
208 auto t_col_base = col_data.getFTensor0N(gg, 0);
209 // loop over columns
210 for (int cc = 0; cc != OpBase::nbCols; cc++) {
211 OpBase::locMat(rr, cc) += beta * t_col_base;
212 ++t_col_base;
213 }
214 ++t_row_base;
215 }
216 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
217 ++t_row_base;
218 }
219 // get normal vector
220 auto t_normal = OpBase::getFTensor1Normal();
221 // using L2 norm of normal vector for convenient area calculation for quads,
222 // tris etc.
224 -t_normal.l2() * stefanBoltzmanConstant * emmisivityParameter;
225
226 EntityType fe_type = OpBase::getNumeredEntFiniteElementPtr()->getEntType();
227 if (fe_type == MBTRI) {
228 OpBase::locMat /= 2;
229 }
230
232}
233
234template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
235 IntegrationType I, typename OpBase>
236struct AddFluxToRhsPipelineImpl<
237
238 OpFluxRhsImpl<ThermoElasticOps::RadiationBcType<BCTYPE>, BASE_DIM,
239 FIELD_DIM, A, I, OpBase>,
240 A, I, OpBase
241
242 > {
243
245
246 static MoFEMErrorCode add(
247
248 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
249 MoFEM::Interface &m_field, std::string field_name,
250 boost::shared_ptr<VectorDouble> T_ptr,
251 std::vector<boost::shared_ptr<ScalingMethod>> smv, std::string block_name,
252 Sev sev
253
254 ) {
256
257 using OP = OpFluxRhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>,
259
260 auto add_op = [&](auto &&meshset_vec_ptr) {
261 for (auto m : meshset_vec_ptr) {
262 MOFEM_TAG_AND_LOG("WORLD", sev, "OpRadiationRhs") << "Add " << *m;
263 pipeline.push_back(
264 new OP(m_field, m->getMeshsetId(), field_name, T_ptr, smv));
265 }
266 MOFEM_LOG_CHANNEL("WORLD");
267 };
268
269 switch (BCTYPE) {
270 case BLOCKSET:
271 add_op(
272
273 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
274 std::regex(
275
276 (boost::format("%s(.*)") % block_name).str()
277
278 ))
279
280 );
281
282 break;
283 default:
284 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
285 "Handling of bc type not implemented");
286 break;
287 }
289 }
290};
291
292template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
293 IntegrationType I, typename OpBase>
294struct AddFluxToLhsPipelineImpl<
295
296 OpFluxLhsImpl<ThermoElasticOps::RadiationBcType<BCTYPE>, BASE_DIM,
297 FIELD_DIM, A, I, OpBase>,
298 A, I, OpBase
299
300 > {
301
303
304 static MoFEMErrorCode add(
305
306 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
307 MoFEM::Interface &m_field, std::string row_field_name,
308 std::string col_field_name, boost::shared_ptr<VectorDouble> T_ptr,
309 std::string block_name, Sev sev
310
311 ) {
313
314 using OP = OpFluxLhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>,
316
317 auto add_op = [&](auto &&meshset_vec_ptr) {
318 for (auto m : meshset_vec_ptr) {
319 MOFEM_TAG_AND_LOG("WORLD", sev, "OpRadiationLhs") << "Add " << *m;
320 pipeline.push_back(new OP(m_field, m->getMeshsetId(), row_field_name,
321 col_field_name, T_ptr));
322 }
323 MOFEM_LOG_CHANNEL("WORLD");
324 };
325
326 switch (BCTYPE) {
327 case BLOCKSET:
328 add_op(
329
330 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
331 std::regex(
332
333 (boost::format("%s(.*)") % block_name).str()
334
335 ))
336
337 );
338
339 break;
340 default:
341 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
342 "Handling of bc type not implemented");
343 break;
344 }
346 }
347};
#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)