v0.14.0
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  * @copyright Copyright (c) 2024
9  *
10  */
11 
12 namespace ThermoElasticOps {
13 
14 template <CubitBC BC> struct RadiationBcType {};
15 
16 template <CubitBC BC> struct GetRadiationParameters;
17 
18 template <> struct GetRadiationParameters<BLOCKSET> {
19  GetRadiationParameters() = delete;
20 
21  static MoFEMErrorCode
22  getParameters(double &stefan_boltzmann_constant, double &emissivity_parameter,
23  double &ambient_temperature, boost::shared_ptr<Range> &ents,
24  MoFEM::Interface &m_field, int ms_id, Sev sev) {
25 
27 
28  auto cubit_meshset_ptr =
29  m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(ms_id,
30  BLOCKSET);
31  std::vector<double> block_data;
32  CHKERR cubit_meshset_ptr->getAttributes(block_data);
33  if (block_data.size() < 3) {
34  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
35  "Expected that radiation block has three attributes "
36  "(Stefan–Boltzmann "
37  "constant, emissivity parameter, and ambient temperature)");
38  }
39  stefan_boltzmann_constant = block_data[0];
40  emissivity_parameter = block_data[1];
41  ambient_temperature = block_data[2];
42 
43  MOFEM_LOG_CHANNEL("WORLD");
44  MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "RadiationBc")
45  << "Stefan–Boltzmann constant " << stefan_boltzmann_constant;
46  MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "RadiationBc")
47  << "Emissivity parameter " << emissivity_parameter;
48  MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "RadiationBc")
49  << "Ambient temperature " << ambient_temperature;
50 
51  ents = boost::make_shared<Range>();
52  CHKERR m_field.get_moab().get_entities_by_handle(cubit_meshset_ptr->meshset,
53  *(ents), true);
54 
55  MOFEM_LOG_CHANNEL("SYNC");
56  MOFEM_TAG_AND_LOG("SYNC", Sev::noisy, "RadiationBc") << *ents;
57  MOFEM_LOG_SEVERITY_SYNC(m_field.get_comm(), Sev::noisy);
58 
60  }
61 };
62 
63 } // namespace ThermoElasticOps
64 
65 template <AssemblyType A, typename EleOp>
66 struct OpFluxRhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1, A,
67  GAUSS, EleOp> : OpBaseImpl<A, EleOp> {
68 
70 
71  OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id, std::string field_name,
72  boost::shared_ptr<VectorDouble> t_ptr);
73 
74 protected:
78  boost::shared_ptr<VectorDouble> tPtr;
80 };
81 
82 template <AssemblyType A, typename EleOp>
83 struct OpFluxLhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1, A,
84  GAUSS, EleOp> : OpBaseImpl<A, EleOp> {
85 
87 
88  OpFluxLhsImpl(MoFEM::Interface &m_field, int ms_id,
89  std::string row_field_name, std::string col_field_name,
90  boost::shared_ptr<VectorDouble> t_ptr);
91 
92 protected:
96  boost::shared_ptr<VectorDouble>
97  tPtr; // pointer for boundary temperature field
98  MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
99  EntitiesFieldData::EntData &col_data);
100 };
101 
102 template <AssemblyType A, typename EleOp>
103 OpFluxRhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1, A, GAUSS,
104  EleOp>::OpFluxRhsImpl(MoFEM::Interface &m_field, int ms_id,
105  std::string field_name,
106  boost::shared_ptr<VectorDouble> t_ptr)
107  : OpBase(field_name, field_name, OpBase::OPROW), tPtr(t_ptr) {
110  this->stefanBoltzmanConstant, this->emmisivityParameter,
111  this->ambientTemperature, this->entsPtr, m_field, ms_id, Sev::inform),
112  "Cannot read radiation data from blockset");
113 }
114 
115 template <AssemblyType A, typename EleOp>
119  &row_data) {
121 
122  // get integration weights
123  auto t_w = OpBase::getFTensor0IntegrationWeight();
124  // get base function values on rows
125  auto t_row_base = row_data.getFTensor0N();
126 
127  // get temperature
128  auto t_temp = getFTensor0FromVec(*tPtr);
129  // loop over integration points
130  for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
131  const auto alpha =
132  -t_w * (std::pow(t_temp, 4) - std::pow(ambientTemperature, 4));
133 
134  int rr = 0;
135  for (; rr != OpBase::nbRows; ++rr) {
136  OpBase::locF[rr] += (alpha * t_row_base);
137  ++t_row_base;
138  }
139 
140  for (; rr < OpBase::nbRowBaseFunctions; ++rr)
141  ++t_row_base;
142 
143  ++t_w;
144  ++t_temp;
145  }
146 
147  // get normal vector
148  auto t_normal = OpBase::getFTensor1Normal();
149  OpBase::locF *= t_normal.l2() * stefanBoltzmanConstant * emmisivityParameter;
150 
151  EntityType fe_type = OpBase::getNumeredEntFiniteElementPtr()->getEntType();
152  if (fe_type == MBTRI) {
153  OpBase::locF /= 2;
154  }
155 
157 }
158 
159 template <AssemblyType A, typename EleOp>
160 OpFluxLhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1, A, GAUSS,
161  EleOp>::OpFluxLhsImpl(MoFEM::Interface &m_field, int ms_id,
162  std::string row_field_name,
163  std::string col_field_name,
164  boost::shared_ptr<VectorDouble> t_ptr)
165  : OpBase(row_field_name, col_field_name, OpBase::OPROWCOL), tPtr(t_ptr) {
166 
167  this->sYmm = true;
168 
171  this->stefanBoltzmanConstant, this->emmisivityParameter,
172  this->ambientTemperature, this->entsPtr, m_field, ms_id,
173  Sev::verbose),
174  "Can not read radiation bc from blockset");
175 }
176 
177 template <AssemblyType A, typename EleOp>
180  GAUSS,
181  EleOp>::iNtegrate(EntitiesFieldData::EntData &row_data,
182  EntitiesFieldData::EntData &col_data) {
183 
185  // get element volume
186  const double vol = OpBase::getMeasure();
187  // get integration weights
188  auto t_w = OpBase::getFTensor0IntegrationWeight();
189  // get base function values on rows
190  auto t_row_base = row_data.getFTensor0N();
191  // get temperature
192  auto t_temp = getFTensor0FromVec(*tPtr);
193  // loop over integration points
194  for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
195  const auto alpha = t_w * 4 * std::pow(t_temp, 3);
196  ++t_w; // move to another integration weight
197  ++t_temp;
198  // loop over rows base functions
199  int rr = 0;
200  for (; rr != OpBase::nbRows; rr++) {
201  const auto beta = alpha * t_row_base;
202  // get column base functions values at gauss point gg
203  auto t_col_base = col_data.getFTensor0N(gg, 0);
204  // loop over columns
205  for (int cc = 0; cc != OpBase::nbCols; cc++) {
206  OpBase::locMat(rr, cc) += beta * t_col_base;
207  ++t_col_base;
208  }
209  ++t_row_base;
210  }
211  for (; rr < OpBase::nbRowBaseFunctions; ++rr)
212  ++t_row_base;
213  }
214  // get normal vector
215  auto t_normal = OpBase::getFTensor1Normal();
216  // using L2 norm of normal vector for convenient area calculation for quads,
217  // tris etc.
218  OpBase::locMat *=
219  -t_normal.l2() * stefanBoltzmanConstant * emmisivityParameter;
220 
221  EntityType fe_type = OpBase::getNumeredEntFiniteElementPtr()->getEntType();
222  if (fe_type == MBTRI) {
223  OpBase::locMat /= 2;
224  }
225 
227 }
228 
229 template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
230  IntegrationType I, typename OpBase>
231 struct AddFluxToRhsPipelineImpl<
232 
233  OpFluxRhsImpl<ThermoElasticOps::RadiationBcType<BCTYPE>, BASE_DIM,
234  FIELD_DIM, A, I, OpBase>,
235  A, I, OpBase
236 
237  > {
238 
239  AddFluxToRhsPipelineImpl() = delete;
240 
242 
243  boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
244  MoFEM::Interface &m_field, std::string field_name,
245  boost::shared_ptr<VectorDouble> T_ptr, std::string block_name, Sev sev
246 
247  ) {
249 
250  using OP = OpFluxRhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>,
252 
253  auto add_op = [&](auto &&meshset_vec_ptr) {
254  for (auto m : meshset_vec_ptr) {
255  MOFEM_TAG_AND_LOG("WORLD", sev, "OpRadiationRhs") << "Add " << *m;
256  pipeline.push_back(
257  new OP(m_field, m->getMeshsetId(), field_name, T_ptr));
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 
285 template <CubitBC BCTYPE, int BASE_DIM, int FIELD_DIM, AssemblyType A,
286  IntegrationType I, typename OpBase>
287 struct AddFluxToLhsPipelineImpl<
288 
289  OpFluxLhsImpl<ThermoElasticOps::RadiationBcType<BCTYPE>, BASE_DIM,
290  FIELD_DIM, A, I, OpBase>,
291  A, I, OpBase
292 
293  > {
294 
295  AddFluxToLhsPipelineImpl() = delete;
296 
298 
299  boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
300  MoFEM::Interface &m_field, std::string row_field_name,
301  std::string col_field_name, boost::shared_ptr<VectorDouble> T_ptr,
302  std::string block_name, Sev sev
303 
304  ) {
306 
307  using OP = OpFluxLhsImpl<ThermoElasticOps::RadiationBcType<BLOCKSET>,
309 
310  auto add_op = [&](auto &&meshset_vec_ptr) {
311  for (auto m : meshset_vec_ptr) {
312  MOFEM_TAG_AND_LOG("WORLD", sev, "OpRadiationLhs") << "Add " << *m;
313  pipeline.push_back(new OP(m_field, m->getMeshsetId(), row_field_name,
314  col_field_name, T_ptr));
315  }
316  MOFEM_LOG_CHANNEL("WORLD");
317  };
318 
319  switch (BCTYPE) {
320  case BLOCKSET:
321  add_op(
322 
323  m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
324  std::regex(
325 
326  (boost::format("%s(.*)") % block_name).str()
327 
328  ))
329 
330  );
331 
332  break;
333  default:
334  SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
335  "Handling of bc type not implemented");
336  break;
337  }
339  }
340 };
MoFEM::UnknownInterface::getInterface
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Definition: UnknownInterface.hpp:93
MoFEM::OpBaseImpl::nbIntegrationPts
int nbIntegrationPts
number of integration points
Definition: FormsIntegrators.hpp:238
OpFluxRhsImpl< ThermoElasticOps::RadiationBcType< BLOCKSET >, 1, 1, A, GAUSS, EleOp >::tPtr
boost::shared_ptr< VectorDouble > tPtr
Definition: ThermalRadiation.hpp:78
MOFEM_LOG_SEVERITY_SYNC
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
Definition: LogManager.hpp:352
ThermoElasticOps::GetRadiationParameters< BLOCKSET >::getParameters
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)
Definition: ThermalRadiation.hpp:22
MoFEM::OpBaseImpl::locMat
MatrixDouble locMat
local entity block matrix
Definition: FormsIntegrators.hpp:249
MOFEM_LOG_CHANNEL
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
Definition: LogManager.hpp:284
MoFEM::OpFluxRhsImpl
Definition: Natural.hpp:39
MoFEM::CoreInterface::get_comm
virtual MPI_Comm & get_comm() const =0
CHK_THROW_MESSAGE
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:609
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
MoFEM::PETSC
@ PETSC
Definition: FormsIntegrators.hpp:105
ThermoElasticOps::RadiationBcType
Definition: ThermalRadiation.hpp:14
A
constexpr AssemblyType A
Definition: operators_tests.cpp:30
OpFluxLhsImpl< ThermoElasticOps::RadiationBcType< BLOCKSET >, 1, 1, A, GAUSS, EleOp >::tPtr
boost::shared_ptr< VectorDouble > tPtr
Definition: ThermalRadiation.hpp:97
BASE_DIM
constexpr int BASE_DIM
Definition: dg_projection.cpp:15
OpFluxRhsImpl< ThermoElasticOps::RadiationBcType< BLOCKSET >, 1, 1, A, GAUSS, EleOp >::ambientTemperature
double ambientTemperature
Definition: ThermalRadiation.hpp:77
MoFEM::DeprecatedCoreInterface
Deprecated interface functions.
Definition: DeprecatedCoreInterface.hpp:16
FIELD_DIM
constexpr int FIELD_DIM
Definition: child_and_parent.cpp:15
MoFEM::OpFluxLhsImpl
Definition: Natural.hpp:43
I
constexpr IntegrationType I
Definition: operators_tests.cpp:31
EleOp
MoFEM::OpBaseImpl::locF
VectorDouble locF
local entity vector
Definition: FormsIntegrators.hpp:251
MoFEM::Sev
MoFEM::LogManager::SeverityLevel Sev
Definition: CoreTemplates.hpp:17
MoFEM::OpBaseImpl
Definition: FormsIntegrators.hpp:178
OpFluxRhsImpl< ThermoElasticOps::RadiationBcType< BLOCKSET >, 1, 1, A, GAUSS, EleOp >::stefanBoltzmanConstant
double stefanBoltzmanConstant
Definition: ThermalRadiation.hpp:75
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:548
MoFEM::CoreInterface::get_moab
virtual moab::Interface & get_moab()=0
MoFEM::getFTensor0FromVec
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
Definition: Templates.hpp:135
MoFEM::GAUSS
@ GAUSS
Definition: FormsIntegrators.hpp:136
ThermoElasticOps::GetRadiationParameters
Definition: ThermalRadiation.hpp:16
ThermoElasticOps
Definition: ThermalConvection.hpp:12
OpFluxLhsImpl< ThermoElasticOps::RadiationBcType< BLOCKSET >, 1, 1, A, GAUSS, EleOp >::ambientTemperature
double ambientTemperature
Definition: ThermalRadiation.hpp:95
EntData
EntitiesFieldData::EntData EntData
Definition: child_and_parent.cpp:37
field_name
constexpr auto field_name
Definition: poisson_2d_homogeneous.cpp:13
MoFEM::IntegrationType
IntegrationType
Form integrator integration types.
Definition: FormsIntegrators.hpp:136
MoFEM::OpBaseImpl::nbRowBaseFunctions
int nbRowBaseFunctions
number or row base functions
Definition: FormsIntegrators.hpp:239
MoFEM::OpBaseImpl::nbCols
int nbCols
number if dof on column
Definition: FormsIntegrators.hpp:237
AddFluxToRhsPipelineImpl< OpFluxRhsImpl< ThermoElasticOps::RadiationBcType< BCTYPE >, BASE_DIM, FIELD_DIM, A, I, OpBase >, A, I, OpBase >::add
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, std::string field_name, boost::shared_ptr< VectorDouble > T_ptr, std::string block_name, Sev sev)
Definition: ThermalRadiation.hpp:241
MOFEM_TAG_AND_LOG
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
Definition: LogManager.hpp:362
OpFluxLhsImpl< ThermoElasticOps::RadiationBcType< BLOCKSET >, 1, 1, A, GAUSS, EleOp >::stefanBoltzmanConstant
double stefanBoltzmanConstant
Definition: ThermalRadiation.hpp:93
MoFEM::OpBaseImpl::nbRows
int nbRows
number of dofs on rows
Definition: FormsIntegrators.hpp:236
MoFEM::AssemblyType
AssemblyType
[Storage and set boundary conditions]
Definition: FormsIntegrators.hpp:104
BLOCKSET
@ BLOCKSET
Definition: definitions.h:161
AddFluxToLhsPipelineImpl< OpFluxLhsImpl< ThermoElasticOps::RadiationBcType< BCTYPE >, BASE_DIM, FIELD_DIM, A, I, OpBase >, A, I, OpBase >::add
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)
Definition: ThermalRadiation.hpp:297
OpBaseImpl
OpFluxLhsImpl< ThermoElasticOps::RadiationBcType< BLOCKSET >, 1, 1, A, GAUSS, EleOp >::emmisivityParameter
double emmisivityParameter
Definition: ThermalRadiation.hpp:94
MOFEM_DATA_INCONSISTENCY
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
m
FTensor::Index< 'm', 3 > m
Definition: shallow_wave.cpp:80
OpFluxRhsImpl< ThermoElasticOps::RadiationBcType< BLOCKSET >, 1, 1, A, GAUSS, EleOp >::emmisivityParameter
double emmisivityParameter
Definition: ThermalRadiation.hpp:76
OP
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:429
MOFEM_NOT_IMPLEMENTED
@ MOFEM_NOT_IMPLEMENTED
Definition: definitions.h:32
MoFEMFunctionBegin
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:359
CubitBC
CubitBC
Types of sets and boundary conditions.
Definition: definitions.h:157