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