v0.16.0
Loading...
Searching...
No Matches
ThermalConvection.hpp
Go to the documentation of this file.
1/**
2 * @file ThermalConvection.hpp
3 * @author Andrei Shvarts (andrei.shvarts@glasgow.ac.uk)
4 * @brief Implementation of thermal convection bc
5 * @version 0.14.0
6 * @date 2024-08-23
7 */
8
9namespace ThermoElasticOps {
10
11template <CubitBC BC> struct ConvectionBcType {};
12
13template <CubitBC BC> struct GetConvectionParameters;
14
15template <> struct GetConvectionParameters<BLOCKSET> {
17
18 static MoFEMErrorCode getParameters(double &heat_transfer_coefficient,
19 double &ambient_temperature,
20 boost::shared_ptr<Range> &ents,
21 MoFEM::Interface &m_field, int ms_id,
22 Sev sev) {
23
25
26 auto cubit_meshset_ptr =
27 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
28 BLOCKSET);
29 auto *json_config = m_field.getInterface<JsonConfigManager>();
30 const auto params_from_json =
31 json_config->getParamsFromBlockset("CONVECTION", ms_id);
32 if (!params_from_json.empty()) {
33 heat_transfer_coefficient = params_from_json.at("heat_transfer_coefficient");
34 ambient_temperature = params_from_json.at("ambient_temperature");
35 } else {
36 std::vector<double> block_data;
37 CHKERR cubit_meshset_ptr->getAttributes(block_data);
38 if (block_data.size() < 2) {
39 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
40 "Expected that convection block has two attributes (heat "
41 "transfer coefficient and ambient temperature)");
42 }
43 heat_transfer_coefficient = block_data[0];
44 ambient_temperature = block_data[1];
45 }
46
47 MOFEM_LOG_CHANNEL("WORLD");
48 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "ConvectionBc")
49 << "Heat transfer coefficient " << heat_transfer_coefficient;
50 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "ConvectionBc")
51 << "Ambient temperature " << ambient_temperature;
52
53 ents = boost::make_shared<Range>();
54 CHKERR
55 m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
56 *(ents), true);
57
58 MOFEM_LOG_CHANNEL("SYNC");
59 MOFEM_TAG_AND_LOG("SYNC", Sev::noisy, "ConvectionBc") << *ents;
60 MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
61
63 }
64};
65
66} // namespace ThermoElasticOps
67
68template <AssemblyType A, typename EleOp>
69struct OpFluxRhsImpl<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1, A,
70 GAUSS, EleOp> : OpBaseImpl<A, EleOp> {
71
73
74 OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id, std::string field_name,
75 boost::shared_ptr<VectorDouble> t_ptr,
76 std::vector<boost::shared_ptr<ScalingMethod>> smv);
77
78protected:
81 boost::shared_ptr<VectorDouble> tPtr;
82 std::vector<boost::shared_ptr<ScalingMethod>> vecOfTimeScalingMethods;
83 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &data);
84};
85
86template <AssemblyType A, typename EleOp>
87struct OpFluxLhsImpl<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1, A,
88 GAUSS, EleOp> : OpBaseImpl<A, EleOp> {
89
91
92 OpFluxLhsImpl(MoFEM::Interface &m_field, int ms_id,
93 std::string row_field_name, std::string col_field_name);
94
95protected:
98 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
99 EntitiesFieldData::EntData &col_data);
100};
101
102template <AssemblyType A, typename EleOp>
103OpFluxRhsImpl<
105 EleOp>::OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
106 std::string field_name,
107 boost::shared_ptr<VectorDouble> t_ptr,
108 std::vector<boost::shared_ptr<ScalingMethod>> smv)
109 : OpBase(field_name, field_name, OpBase::OPROW), tPtr(t_ptr),
110 vecOfTimeScalingMethods(smv) {
113 this->heatTransferCoefficient, this->ambientTemperature,
114 this->entsPtr, m_field, ms_id, Sev::inform),
115 "Cannot read convection data from blockset");
116}
117
118template <AssemblyType A, typename EleOp>
119MoFEMErrorCode
121 GAUSS, EleOp>::iNtegrate(EntitiesFieldData::EntData
122 &row_data) {
124
125 // get integration weights
126 auto t_w = OpBase::getFTensor0IntegrationWeight();
127 // get base function values on rows
128 auto t_row_base = row_data.getFTensor0N();
129 // get temperature
130 auto t_temp = getFTensor0FromVec(*tPtr);
131
132 double s = 1;
133 for (auto &o : vecOfTimeScalingMethods) {
134 s *= o->getScale(OpBase::getTStime());
135 }
136
137 // loop over integration points
138 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
139 const auto alpha =
140 -t_w * heatTransferCoefficient * (t_temp - ambientTemperature * s);
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();
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::ConvectionBcType<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 : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL) {
172
173 this->sYmm = true;
174
177 this->heatTransferCoefficient, this->ambientTemperature,
178 this->entsPtr, m_field, ms_id, Sev::verbose),
179 "Cannot read convection data from blockset");
180}
181
182template <AssemblyType A, typename EleOp>
183MoFEMErrorCode
185 GAUSS,
186 EleOp>::iNtegrate(EntitiesFieldData::EntData &row_data,
187 EntitiesFieldData::EntData &col_data) {
188
190 // get integration weights
191 auto t_w = OpBase::getFTensor0IntegrationWeight();
192 // get base function values on rows
193 auto t_row_base = row_data.getFTensor0N();
194 // loop over integration points
195 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
196 // loop over rows base functions
197 int rr = 0;
198 for (; rr != OpBase::nbRows; rr++) {
199 const auto alpha = t_w * t_row_base;
200 // get column base functions values at gauss point gg
201 auto t_col_base = col_data.getFTensor0N(gg, 0);
202 // loop over columns
203 for (int cc = 0; cc != OpBase::nbCols; cc++) {
204 OpBase::locMat(rr, cc) += alpha * t_col_base;
205 ++t_col_base;
206 }
207 ++t_row_base;
208 }
209 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
210 ++t_row_base;
211 ++t_w; // move to another integration weight
212 }
213 // get normal vector
214 auto t_normal = OpBase::getFTensor1Normal();
215 // using L2 norm of normal vector for convenient area calculation for quads,
216 // tris etc.
217 OpBase::locMat *= -t_normal.l2() * heatTransferCoefficient;
218
219 EntityType fe_type = OpBase::getNumeredEntFiniteElementPtr()->getEntType();
220 if (fe_type == MBTRI) {
221 OpBase::locMat /= 2;
222 }
223
225}
226
227template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
228 IntegrationType I, typename OpBase>
229struct AddFluxToRhsPipelineImpl<
230
231 OpFluxRhsImpl<ThermoElasticOps::ConvectionBcType<BCTYPE>, BASE_DIM,
232 FIELD_DIM, A, I, OpBase>,
233 A, I, OpBase
234
235 > {
236
238
239 static MoFEMErrorCode add(
240
241 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
242 MoFEM::Interface &m_field, std::string field_name,
243 boost::shared_ptr<VectorDouble> u_ptr,
244 std::vector<boost::shared_ptr<ScalingMethod>> smv, std::string block_name,
245 Sev sev
246
247 ) {
249
250 using OP = OpFluxRhsImpl<ThermoElasticOps::ConvectionBcType<BLOCKSET>,
252
253 auto add_op = [&](auto &&meshset_vec_ptr) {
254 for (auto m : meshset_vec_ptr) {
255 MOFEM_TAG_AND_LOG("WORLD", sev, "OpConvectionRhs") << "Add " << *m;
256 pipeline.push_back(
257 new OP(m_field, m->getMeshsetId(), field_name, u_ptr, smv));
258 }
259 MOFEM_LOG_CHANNEL("WORLD");
260 };
261
262 switch (BCTYPE) {
263 case BLOCKSET:
264 add_op(
265
266 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
267 std::regex(
268
269 (boost::format("%s(.*)") % block_name).str()
270
271 ))
272
273 );
274
275 break;
276 default:
277 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
278 "Handling of bc type not implemented");
279 break;
280 }
282 }
283};
284
285template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
286 IntegrationType I, typename OpBase>
287struct AddFluxToLhsPipelineImpl<
288
289 OpFluxLhsImpl<ThermoElasticOps::ConvectionBcType<BCTYPE>, BASE_DIM,
290 FIELD_DIM, A, I, OpBase>,
291 A, I, OpBase
292
293 > {
294
296
297 static MoFEMErrorCode add(
298
299 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
300 MoFEM::Interface &m_field, std::string row_field_name,
301 std::string col_field_name, std::string block_name, Sev sev
302
303 ) {
305
306 using OP = OpFluxLhsImpl<ThermoElasticOps::ConvectionBcType<BLOCKSET>,
308
309 auto add_op = [&](auto &&meshset_vec_ptr) {
310 for (auto m : meshset_vec_ptr) {
311 MOFEM_TAG_AND_LOG("WORLD", sev, "OpConvectionLhs") << "Add " << *m;
312 pipeline.push_back(
313 new OP(m_field, m->getMeshsetId(), row_field_name, col_field_name));
314 }
315 MOFEM_LOG_CHANNEL("WORLD");
316 };
317
318 switch (BCTYPE) {
319 case BLOCKSET:
320 add_op(
321
322 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
323 std::regex(
324
325 (boost::format("%s(.*)") % block_name).str()
326
327 ))
328
329 );
330
331 break;
332 default:
333 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
334 "Handling of bc type not implemented");
335 break;
336 }
338 }
339};
#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, 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 > u_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 &heat_transfer_coefficient, double &ambient_temperature, boost::shared_ptr< Range > &ents, MoFEM::Interface &m_field, int ms_id, Sev sev)