v0.16.0
Loading...
Searching...
No Matches
ThermoElasticOps.hpp
Go to the documentation of this file.
1
2
3/** \file ThermoElasticOps.hpp
4 * \example mofem/tutorials/adv-2/src/ThermoElasticOps.hpp
5 */
6
7namespace ThermoElasticOps {
8
11 const std::string row_field_name, const std::string col_field_name,
12 boost::shared_ptr<MatrixDouble> mDptr,
13 boost::shared_ptr<VectorDouble> coeff_expansion_ptr);
14
15 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
16 EntitiesFieldData::EntData &col_data);
17
18private:
19 boost::shared_ptr<MatrixDouble> mDPtr;
20 boost::shared_ptr<VectorDouble> coeffExpansionPtr;
21};
22
24 /**
25 * @deprecated do not use this constructor
26 */
28 OpStressThermal(const std::string field_name,
29 boost::shared_ptr<MatrixDouble> strain_ptr,
30 boost::shared_ptr<VectorDouble> temp_ptr,
31 boost::shared_ptr<MatrixDouble> m_D_ptr,
32 boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
33 boost::shared_ptr<MatrixDouble> stress_ptr);
34
35 OpStressThermal(boost::shared_ptr<MatrixDouble> strain_ptr,
36 boost::shared_ptr<VectorDouble> temp_ptr,
37 boost::shared_ptr<MatrixDouble> m_D_ptr,
38 boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
39 boost::shared_ptr<double> ref_temp_ptr,
40 boost::shared_ptr<MatrixDouble> stress_ptr);
41
42 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
43
44private:
45 boost::shared_ptr<MatrixDouble> strainPtr;
46 boost::shared_ptr<VectorDouble> tempPtr;
47 boost::shared_ptr<MatrixDouble> mDPtr;
48 boost::shared_ptr<VectorDouble> coeffExpansionPtr;
49 boost::shared_ptr<double> refTempPtr;
50 boost::shared_ptr<MatrixDouble> stressPtr;
51};
52
54 const std::string row_field_name, const std::string col_field_name,
55 boost::shared_ptr<MatrixDouble> mDptr,
56 boost::shared_ptr<VectorDouble> coeff_expansion_ptr)
57 : AssemblyDomainEleOp(row_field_name, col_field_name,
58 DomainEleOp::OPROWCOL),
59 mDPtr(mDptr), coeffExpansionPtr(coeff_expansion_ptr) {
60 sYmm = false;
61}
62
63MoFEMErrorCode
64OpKCauchyThermoElasticity::iNtegrate(EntitiesFieldData::EntData &row_data,
65 EntitiesFieldData::EntData &col_data) {
67
68 auto &locMat = AssemblyDomainEleOp::locMat;
69
70 const auto nb_integration_pts = row_data.getN().size1();
71 const auto nb_row_base_functions = row_data.getN().size2();
72 auto t_w = getFTensor0IntegrationWeight();
73 auto t_row_diff_base = row_data.getFTensor1DiffN<SPACE_DIM>();
74 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(*mDPtr);
75
81
83 t_coeff_exp(i, j) = 0;
84 for (auto d = 0; d != SPACE_DIM; ++d) {
85 t_coeff_exp(d, d) = (*coeffExpansionPtr)[d];
86 }
87
88 t_eigen_strain(i, j) = (t_D(i, j, k, l) * t_coeff_exp(k, l));
89
90 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
91
92 double alpha = getMeasure() * t_w;
93 auto rr = 0;
94 for (; rr != AssemblyDomainEleOp::nbRows / SPACE_DIM; ++rr) {
95 auto t_mat =
96 getFTensor1FromMat<SPACE_DIM, 1,
97 DataLayoutTraits<DataLayout::CoeffsByGauss>>(
98 locMat, rr * SPACE_DIM);
99 auto t_col_base = col_data.getFTensor0N(gg, 0);
100 for (auto cc = 0; cc != AssemblyDomainEleOp::nbCols; cc++) {
101
102 t_mat(i) -=
103 (t_row_diff_base(j) * t_eigen_strain(i, j)) * (t_col_base * alpha);
104
105 ++t_mat;
106 ++t_col_base;
107 }
108
109 ++t_row_diff_base;
110 }
111 for (; rr != nb_row_base_functions; ++rr)
112 ++t_row_diff_base;
113
114 ++t_w;
115 }
116
118}
119
121 const std::string field_name, boost::shared_ptr<MatrixDouble> strain_ptr,
122 boost::shared_ptr<VectorDouble> temp_ptr,
123 boost::shared_ptr<MatrixDouble> m_D_ptr,
124 boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
125 boost::shared_ptr<MatrixDouble> stress_ptr)
126 : DomainEleOp(field_name, DomainEleOp::OPROW), strainPtr(strain_ptr),
127 tempPtr(temp_ptr), mDPtr(m_D_ptr), coeffExpansionPtr(coeff_expansion_ptr),
128 stressPtr(stress_ptr) {
129 // Operator is only executed for vertices
130 std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE], false);
131}
132
134 boost::shared_ptr<MatrixDouble> strain_ptr,
135 boost::shared_ptr<VectorDouble> temp_ptr,
136 boost::shared_ptr<MatrixDouble> m_D_ptr,
137 boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
138 boost::shared_ptr<double> ref_temp_ptr,
139 boost::shared_ptr<MatrixDouble> stress_ptr)
140 : DomainEleOp(NOSPACE, DomainEleOp::OPSPACE), strainPtr(strain_ptr),
141 tempPtr(temp_ptr), mDPtr(m_D_ptr), coeffExpansionPtr(coeff_expansion_ptr),
142 refTempPtr(ref_temp_ptr), stressPtr(stress_ptr) {}
143
144//! [Calculate stress]
145MoFEMErrorCode OpStressThermal::doWork(int side, EntityType type,
146 EntData &data) {
148 const auto nb_gauss_pts = getGaussPts().size2();
149 stressPtr->resize(nb_gauss_pts, (SPACE_DIM * (SPACE_DIM + 1)) / 2);
150
151 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(*mDPtr);
152 auto t_strain = getFTensor2SymmetricFromMat<SPACE_DIM>(*strainPtr);
153 auto t_stress = getFTensor2SymmetricFromMat<SPACE_DIM>(*stressPtr);
154 auto t_temp = getFTensor0FromVec(*tempPtr);
155
160
162 t_coeff_exp(i, j) = 0;
163 for (auto d = 0; d != SPACE_DIM; ++d) {
164 t_coeff_exp(d, d) = (*coeffExpansionPtr)[d];
165 }
166
167 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
168 t_stress(i, j) =
169 t_D(i, j, k, l) *
170 (t_strain(k, l) - t_coeff_exp(k, l) * (t_temp - (*refTempPtr)));
171 ++t_strain;
172 ++t_stress;
173 ++t_temp;
174 }
176}
177//! [Calculate stress]
178
179struct SetTargetTemperature;
180
181} // namespace ThermoElasticOps
182
183//! [Target temperature]
184
185template <AssemblyType A, IntegrationType I, typename OpBase>
186struct MoFEM::OpFluxRhsImpl<ThermoElasticOps::SetTargetTemperature, 1, 1, A, I,
187 OpBase>;
188
189template <AssemblyType A, IntegrationType I, typename OpBase>
190struct MoFEM::OpFluxLhsImpl<ThermoElasticOps::SetTargetTemperature, 1, 1, A, I,
191 OpBase>;
192
193template <AssemblyType A, IntegrationType I, typename OpBase>
195
196 MoFEM::OpFluxRhsImpl<ThermoElasticOps::SetTargetTemperature, 1, 1, A, I,
197 OpBase>,
198 A, I, OpBase
199
200 > {
201
203
205
206 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
207 MoFEM::Interface &m_field, const std::string field_name,
208 boost::shared_ptr<VectorDouble> temp_ptr, std::string block_name,
209 FEFun fe_fun, Sev sev
210
211 ) {
213
214 using OP_SOURCE = typename FormsIntegrators<OpBase>::template Assembly<
215 A>::template LinearForm<I>::template OpSource<1, 1>;
216 using OP_TEMP = typename FormsIntegrators<OpBase>::template Assembly<
217 A>::template LinearForm<I>::template OpBaseTimesScalar<1>;
218
219 auto add_op = [&](auto &&meshset_vec_ptr) {
221 auto *json_config = m_field.getInterface<JsonConfigManager>();
222 for (auto m : meshset_vec_ptr) {
223 const auto params_from_json =
224 json_config->getParamsFromBlockset(block_name, m->getMeshsetId());
225 double target_temperature = 0;
226 double beta = 0;
227 if (!params_from_json.empty()) {
228 target_temperature = params_from_json.at("target_temperature");
229 beta = params_from_json.at("beta");
230 } else {
231 std::vector<double> block_data;
232 m->getAttributes(block_data);
233 if (block_data.size() < 2) {
234 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
235 "Expected two parameters");
236 }
237 target_temperature = block_data[0];
238 beta = block_data[1];
239 }
240 auto ents_ptr = boost::make_shared<Range>();
241 CHKERR m_field.get_moab().get_entities_by_handle(m->meshset,
242 *(ents_ptr), true);
243
244 MOFEM_TAG_AND_LOG("WORLD", sev, "SetTargetTemperature")
245 << "Add " << *m << " target temperature " << target_temperature
246 << " penalty " << beta;
247
248 auto op_source = new OP_SOURCE(
250 [target_temperature, beta](double, double, double) {
251 return target_temperature * beta;
252 },
253 ents_ptr);
254 op_source->feScalingFun = fe_fun;
255 pipeline.push_back(op_source);
256 auto op_temp = new OP_TEMP(
257 field_name, temp_ptr,
258 [beta](double, double, double) { return -beta; }, ents_ptr);
259 op_temp->feScalingFun = fe_fun;
260 pipeline.push_back(op_temp);
261 }
263 };
264
265 CHKERR add_op(
266
267 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
268
269 (boost::format("%s(.*)") % block_name).str()
270
271 ))
272
273 );
274
275 MOFEM_LOG_CHANNEL("WORLD");
276
278 }
279};
280
281template <AssemblyType A, IntegrationType I, typename OpBase>
282struct AddFluxToLhsPipelineImpl<
283
284 OpFluxLhsImpl<ThermoElasticOps::SetTargetTemperature, 1, 1, A, I, OpBase>,
285 A, I, OpBase
286
287 > {
288
290
291 static MoFEMErrorCode add(
292
293 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
294 MoFEM::Interface &m_field, const std::string field_name,
295 std::string block_name, FEFun fe_fun, Sev sev
296
297 ) {
299
300 using OP_MASS = typename FormsIntegrators<OpBase>::template Assembly<
302
303 auto add_op = [&](auto &&meshset_vec_ptr) {
305 auto *json_config = m_field.getInterface<JsonConfigManager>();
306 for (auto m : meshset_vec_ptr) {
307 const auto params_from_json =
308 json_config->getParamsFromBlockset(block_name, m->getMeshsetId());
309 double beta = 0;
310 if (!params_from_json.empty()) {
311 beta = params_from_json.at("beta");
312 } else {
313 std::vector<double> block_data;
314 m->getAttributes(block_data);
315 if (block_data.size() != 2) {
316 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
317 "Expected two parameters");
318 }
319 beta = block_data[1];
320 }
321 auto ents_ptr = boost::make_shared<Range>();
322 CHKERR m_field.get_moab().get_entities_by_handle(m->meshset,
323 *(ents_ptr), true);
324
325 MOFEM_TAG_AND_LOG("WORLD", sev, "SetTargetTemperature")
326 << "Add " << *m << " penalty " << beta;
327
328 auto op_mass = new OP_MASS(
330 [beta](double, double, double) { return beta; }, ents_ptr);
331 op_mass->feScalingFun = fe_fun;
332 pipeline.push_back(op_mass);
333 }
335 };
336
337 CHKERR add_op(
338
339 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
340
341 (boost::format("%s(.*)") % block_name).str()
342
343 ))
344
345 );
346
347 MOFEM_LOG_CHANNEL("WORLD");
348
350 }
351};
352
353//! [Target temperature]
std::string type
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
constexpr int SPACE_DIM
@ NOSPACE
Definition definitions.h:83
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define DEPRECATED
Definition definitions.h:17
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
SeverityLevel
Severity levels.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
boost::function< double(const FEMethod *fe_ptr)> FEFun
Lambda function used to scale with time.
constexpr IntegrationType I
constexpr AssemblyType A
constexpr auto field_name
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMass
[Only used with Hooke equation (linear material model)]
Definition seepage.cpp:56
FTensor::Index< 'm', 3 > m
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, const std::string field_name, std::string block_name, FEFun fe_fun, Sev sev)
static MoFEMErrorCode add(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, MoFEM::Interface &m_field, const std::string field_name, boost::shared_ptr< VectorDouble > temp_ptr, std::string block_name, FEFun fe_fun, Sev sev)
virtual moab::Interface & get_moab()=0
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
std::map< std::string, double > getParamsFromBlockset(const std::string &type_name, int meshset_id) const
Interface for managing meshsets containing materials and boundary conditions.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
boost::shared_ptr< MatrixDouble > mDPtr
boost::shared_ptr< VectorDouble > coeffExpansionPtr
OpKCauchyThermoElasticity(const std::string row_field_name, const std::string col_field_name, boost::shared_ptr< MatrixDouble > mDptr, boost::shared_ptr< VectorDouble > coeff_expansion_ptr)
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
boost::shared_ptr< double > refTempPtr
boost::shared_ptr< MatrixDouble > strainPtr
DEPRECATED OpStressThermal(const std::string field_name, boost::shared_ptr< MatrixDouble > strain_ptr, boost::shared_ptr< VectorDouble > temp_ptr, boost::shared_ptr< MatrixDouble > m_D_ptr, boost::shared_ptr< VectorDouble > coeff_expansion_ptr, boost::shared_ptr< MatrixDouble > stress_ptr)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
[Calculate stress]
boost::shared_ptr< MatrixDouble > stressPtr
boost::shared_ptr< MatrixDouble > mDPtr
boost::shared_ptr< VectorDouble > coeffExpansionPtr
boost::shared_ptr< VectorDouble > tempPtr