v0.16.3
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
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 for (auto m : meshset_vec_ptr) {
222 std::vector<double> block_data;
223 m->getAttributes(block_data);
224 if (block_data.size() < 2) {
225 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
226 "Expected two parameters");
227 }
228 double target_temperature = block_data[0];
229 double beta = block_data[1];
230 auto ents_ptr = boost::make_shared<Range>();
231 CHKERR m_field.get_moab().get_entities_by_handle(m->meshset,
232 *(ents_ptr), true);
233
234 MOFEM_TAG_AND_LOG("WORLD", sev, "SetTargetTemperature")
235 << "Add " << *m << " target temperature " << target_temperature
236 << " penalty " << beta;
237
238 auto op_source = new OP_SOURCE(
240 [target_temperature, beta](double, double, double) {
241 return target_temperature * beta;
242 },
243 ents_ptr);
244 op_source->feScalingFun = fe_fun;
245 pipeline.push_back(op_source);
246 auto op_temp = new OP_TEMP(
247 field_name, temp_ptr,
248 [beta](double, double, double) { return -beta; }, ents_ptr);
249 op_temp->feScalingFun = fe_fun;
250 pipeline.push_back(op_temp);
251 }
253 };
254
255 CHKERR add_op(
256
257 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
258
259 (boost::format("%s(.*)") % block_name).str()
260
261 ))
262
263 );
264
265 MOFEM_LOG_CHANNEL("WORLD");
266
268 }
269};
270
271template <AssemblyType A, IntegrationType I, typename OpBase>
272struct AddFluxToLhsPipelineImpl<
273
274 OpFluxLhsImpl<ThermoElasticOps::SetTargetTemperature, 1, 1, A, I, OpBase>,
275 A, I, OpBase
276
277 > {
278
280
281 static MoFEMErrorCode add(
282
283 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
284 MoFEM::Interface &m_field, const std::string field_name,
285 std::string block_name, FEFun fe_fun, Sev sev
286
287 ) {
289
290 using OP_MASS = typename FormsIntegrators<OpBase>::template Assembly<
292
293 auto add_op = [&](auto &&meshset_vec_ptr) {
295 for (auto m : meshset_vec_ptr) {
296 std::vector<double> block_data;
297 m->getAttributes(block_data);
298 if (block_data.size() != 2) {
299 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
300 "Expected two parameters");
301 }
302 double beta = block_data[1];
303 auto ents_ptr = boost::make_shared<Range>();
304 CHKERR m_field.get_moab().get_entities_by_handle(m->meshset,
305 *(ents_ptr), true);
306
307 MOFEM_TAG_AND_LOG("WORLD", sev, "SetTargetTemperature")
308 << "Add " << *m << " penalty " << beta;
309
310 auto op_mass = new OP_MASS(
312 [beta](double, double, double) { return beta; }, ents_ptr);
313 op_mass->feScalingFun = fe_fun;
314 pipeline.push_back(op_mass);
315 }
317 };
318
319 CHKERR add_op(
320
321 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
322
323 (boost::format("%s(.*)") % block_name).str()
324
325 ))
326
327 );
328
329 MOFEM_LOG_CHANNEL("WORLD");
330
332 }
333};
334
335//! [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)
Interface for managing meshsets containing materials and boundary conditions.
int nbRows
number of dofs on rows
MatrixDouble locMat
local entity block matrix
int nbCols
number if dof on column
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
boost::shared_ptr< MatrixDouble > mDPtr
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)
boost::shared_ptr< VectorDouble > coeffExpansionPtr
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
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)
boost::shared_ptr< VectorDouble > coeffExpansionPtr
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
[Calculate stress]
boost::shared_ptr< MatrixDouble > strainPtr
boost::shared_ptr< MatrixDouble > stressPtr
boost::shared_ptr< double > refTempPtr
boost::shared_ptr< VectorDouble > tempPtr
boost::shared_ptr< MatrixDouble > mDPtr