202 return boost::shared_ptr<double>(shared_from_this(), &
refTemp);
208 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
209 std::string block_name,
210 boost::shared_ptr<BlockedThermoElasticParameters> blockedParamsPtr,
217 struct OpMatThermoElasticBlocks :
public DomainEleOp {
218 OpMatThermoElasticBlocks(boost::shared_ptr<VectorDouble> expansion_ptr,
219 boost::shared_ptr<double> ref_temp_ptr,
220 double local_coeff_expansion,
223 std::vector<const CubitMeshSets *> meshset_vec_ptr)
225 expansionPtr(expansion_ptr), refTempPtr(ref_temp_ptr),
226 defaultCoeffExpansion(local_coeff_expansion),
227 defaultRefTemp(local_ref_temp) {
229 extractThermoElasticBlockData(m_field, meshset_vec_ptr, sev),
230 "Cannot get data from thermoelastic block");
233 MoFEMErrorCode doWork(
int side, EntityType type,
234 EntitiesFieldData::EntData &data) {
237 for (
auto &b : blockData) {
239 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
240 *expansionPtr = b.expansion;
241 *refTempPtr = b.ref_temp;
246 *expansionPtr = VectorDouble(
SPACE_DIM, defaultCoeffExpansion);
247 *refTempPtr = defaultRefTemp;
253 double defaultCoeffExpansion;
254 double defaultRefTemp;
257 VectorDouble expansion;
261 std::vector<BlockData> blockData;
263 MoFEMErrorCode extractThermoElasticBlockData(
265 std::vector<const CubitMeshSets *> meshset_vec_ptr, Sev sev) {
268 for (
auto m : meshset_vec_ptr) {
270 std::vector<double> block_data;
271 CHKERR m->getAttributes(block_data);
272 if (block_data.size() < 2) {
274 "Expected that block has at least two attributes");
276 auto get_block_ents = [&]() {
279 m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
283 auto get_expansion = [&]() {
285 if (block_data.size() > 2) {
286 expansion[1] = block_data[2];
288 if (
SPACE_DIM == 3 && block_data.size() > 3) {
289 expansion[2] = block_data[3];
294 auto coeff_exp_vec = get_expansion();
297 <<
" ref_temp = " << block_data[0]
298 <<
" expansion = " << coeff_exp_vec;
300 blockData.push_back({block_data[0], coeff_exp_vec, get_block_ents()});
306 boost::shared_ptr<VectorDouble> expansionPtr;
307 boost::shared_ptr<double> refTempPtr;
310 pipeline.push_back(
new OpMatThermoElasticBlocks(
311 blockedParamsPtr->getCoeffExpansionPtr(),
312 blockedParamsPtr->getRefTempPtr(), local_coeff_expansion, local_ref_temp,
316 m_field.
getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
318 (boost::format(
"%s(.*)") % block_name).str()
329 const std::string row_field_name,
const std::string col_field_name,
330 boost::shared_ptr<MatrixDouble> mDptr,
331 boost::shared_ptr<VectorDouble> coeff_expansion_ptr);
333 MoFEMErrorCode
iNtegrate(EntitiesFieldData::EntData &row_data,
334 EntitiesFieldData::EntData &col_data);
337 boost::shared_ptr<MatrixDouble>
mDPtr;
347 boost::shared_ptr<MatrixDouble> strain_ptr,
348 boost::shared_ptr<VectorDouble> temp_ptr,
349 boost::shared_ptr<MatrixDouble> m_D_ptr,
350 boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
351 boost::shared_ptr<MatrixDouble> stress_ptr);
354 boost::shared_ptr<VectorDouble> temp_ptr,
355 boost::shared_ptr<MatrixDouble> m_D_ptr,
356 boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
357 boost::shared_ptr<double> ref_temp_ptr,
358 boost::shared_ptr<MatrixDouble> stress_ptr);
363 boost::shared_ptr<MatrixDouble>
strainPtr;
364 boost::shared_ptr<VectorDouble>
tempPtr;
365 boost::shared_ptr<MatrixDouble>
mDPtr;
368 boost::shared_ptr<MatrixDouble>
stressPtr;
372 const std::string row_field_name,
const std::string col_field_name,
373 boost::shared_ptr<MatrixDouble> mDptr,
374 boost::shared_ptr<VectorDouble> coeff_expansion_ptr)
377 mDPtr(mDptr), coeffExpansionPtr(coeff_expansion_ptr) {
383 EntitiesFieldData::EntData &col_data) {
386 auto &locMat = AssemblyDomainEleOp::locMat;
388 const auto nb_integration_pts = row_data.getN().size1();
389 const auto nb_row_base_functions = row_data.getN().size2();
390 auto t_w = getFTensor0IntegrationWeight();
392 auto t_row_diff_base = row_data.getFTensor1DiffN<
SPACE_DIM>();
393 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(*
mDPtr);
402 t_coeff_exp(
i,
j) = 0;
404 t_coeff_exp(d, d) = (*coeffExpansionPtr)[d];
407 t_eigen_strain(
i,
j) = (t_D(
i,
j,
k,
l) * t_coeff_exp(
k,
l));
409 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
411 double alpha = getMeasure() * t_w;
413 for (; rr != AssemblyDomainEleOp::nbRows /
SPACE_DIM; ++rr) {
414 auto t_mat = getFTensor1FromMat<SPACE_DIM, 1>(locMat, rr *
SPACE_DIM);
415 auto t_col_base = col_data.getFTensor0N(gg, 0);
416 for (
auto cc = 0; cc != AssemblyDomainEleOp::nbCols; cc++) {
419 (t_row_diff_base(
j) * t_eigen_strain(
i,
j)) * (t_col_base * alpha);
427 for (; rr != nb_row_base_functions; ++rr)
437 const std::string
field_name, boost::shared_ptr<MatrixDouble> strain_ptr,
438 boost::shared_ptr<VectorDouble> temp_ptr,
439 boost::shared_ptr<MatrixDouble> m_D_ptr,
440 boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
441 boost::shared_ptr<MatrixDouble> stress_ptr)
443 tempPtr(temp_ptr), mDPtr(m_D_ptr), coeffExpansionPtr(coeff_expansion_ptr),
444 stressPtr(stress_ptr) {
446 std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE],
false);
450 boost::shared_ptr<MatrixDouble> strain_ptr,
451 boost::shared_ptr<VectorDouble> temp_ptr,
452 boost::shared_ptr<MatrixDouble> m_D_ptr,
453 boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
454 boost::shared_ptr<double> ref_temp_ptr,
455 boost::shared_ptr<MatrixDouble> stress_ptr)
457 tempPtr(temp_ptr), mDPtr(m_D_ptr), coeffExpansionPtr(coeff_expansion_ptr),
458 refTempPtr(ref_temp_ptr), stressPtr(stress_ptr) {}
464 const auto nb_gauss_pts = getGaussPts().size2();
467 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(*
mDPtr);
468 auto t_strain = getFTensor2SymmetricFromMat<SPACE_DIM>(*
strainPtr);
469 auto t_stress = getFTensor2SymmetricFromMat<SPACE_DIM>(*
stressPtr);
470 auto t_temp = getFTensor0FromVec(*
tempPtr);
477 t_coeff_exp(
i,
j) = 0;
479 t_coeff_exp(d, d) = (*coeffExpansionPtr)[
d];
482 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
485 (t_strain(
k,
l) - t_coeff_exp(
k,
l) * (t_temp - (*refTempPtr)));
494struct SetTargetTemperature;
500template <AssemblyType A, IntegrationType I,
typename OpBase>
504template <AssemblyType A, IntegrationType I, typename OpBase>
508template <AssemblyType A, IntegrationType I, typename OpBase>
511 MoFEM::OpFluxRhsImpl<ThermoElasticOps::SetTargetTemperature, 1, 1, A, I,
521 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
523 boost::shared_ptr<VectorDouble> temp_ptr, std::string block_name,
Sev sev
533 auto add_op = [&](
auto &&meshset_vec_ptr) {
535 for (
auto m : meshset_vec_ptr) {
536 std::vector<double> block_data;
537 m->getAttributes(block_data);
538 if (block_data.size() < 2) {
540 "Expected two parameters");
542 double target_temperature = block_data[0];
545 auto ents_ptr = boost::make_shared<Range>();
550 <<
"Add " << *
m <<
" target temperature " << target_temperature
551 <<
" penalty " << beta;
553 pipeline.push_back(
new OP_SOURCE(
555 [target_temperature, beta](
double,
double,
double) {
556 return target_temperature * beta;
559 pipeline.push_back(
new OP_TEMP(
561 [beta](
double,
double,
double) {
return -beta; }, ents_ptr));
570 (boost::format(
"%s(.*)") % block_name).str()
582template <AssemblyType A, IntegrationType I,
typename OpBase>
583struct AddFluxToLhsPipelineImpl<
592 static MoFEMErrorCode
add(
594 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
596 boost::shared_ptr<VectorDouble> temp_ptr, std::string block_name, Sev sev
601 using OP_MASS =
typename FormsIntegrators<OpBase>::template Assembly<
604 auto add_op = [&](
auto &&meshset_vec_ptr) {
606 for (
auto m : meshset_vec_ptr) {
607 std::vector<double> block_data;
608 m->getAttributes(block_data);
609 if (block_data.size() != 2) {
611 "Expected two parameters");
615 auto ents_ptr = boost::make_shared<Range>();
620 <<
"Add " << *
m <<
" penalty " << beta;
622 pipeline.push_back(
new OP_MASS(
624 [beta](
double,
double,
double) {
return -beta; }, ents_ptr));
631 m_field.
getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
633 (boost::format(
"%s(.*)") % block_name).str()
653template <AssemblyType A, IntegrationType I>
657 boost::shared_ptr<VectorDouble> dot_T_ptr,
658 boost::shared_ptr<VectorDouble> T_ptr,
659 boost::shared_ptr<MatrixDouble> grad_T_ptr,
660 boost::shared_ptr<double> initial_T_ptr,
661 boost::shared_ptr<double> peak_T_ptr)
666 MoFEMErrorCode
iNtegrate(EntitiesFieldData::EntData &data) {
669 const double vol = getMeasure();
670 auto t_w = getFTensor0IntegrationWeight();
671 auto t_coords = getFTensor1CoordsAtGaussPts();
672 auto t_base = data.getFTensor0N();
673 auto t_diff_base = data.getFTensor1DiffN<
SPACE_DIM>();
676 if (data.getDiffN().size1() != data.getN().size1())
678 if (data.getDiffN().size2() != data.getN().size2() *
SPACE_DIM) {
680 <<
"Side " << rowSide <<
" " << CN::EntityTypeName(rowType);
681 MOFEM_LOG(
"SELF", Sev::error) << data.getN();
682 MOFEM_LOG(
"SELF", Sev::error) << data.getDiffN();
687 auto t_T = getFTensor0FromVec(*
TPtr);
690 for (
int gg = 0; gg != nbIntegrationPts; ++gg) {
692 const double alpha = t_w * vol;
695 t_coords(1), t_coords(2));
699 for (; bb != nbRows; ++bb) {
700 locF[bb] += (t_base * alpha) * (t_T - set_T);
706 for (; bb < nbRowBaseFunctions; ++bb) {
723 boost::shared_ptr<VectorDouble>
TPtr;
734template <AssemblyType A, IntegrationType I>
738 boost::shared_ptr<VectorDouble> T_ptr)
745 MoFEMErrorCode
iNtegrate(EntitiesFieldData::EntData &row_data,
746 EntitiesFieldData::EntData &col_data) {
749 const double vol = getMeasure();
750 auto t_w = getFTensor0IntegrationWeight();
751 auto t_coords = getFTensor1CoordsAtGaussPts();
752 auto t_row_base = row_data.getFTensor0N();
753 auto t_row_diff_base = row_data.getFTensor1DiffN<
SPACE_DIM>();
756 if (row_data.getDiffN().size1() != row_data.getN().size1())
758 if (row_data.getDiffN().size2() != row_data.getN().size2() *
SPACE_DIM) {
760 <<
"Side " << rowSide <<
" " << CN::EntityTypeName(rowType);
761 MOFEM_LOG(
"SELF", Sev::error) << row_data.getN();
762 MOFEM_LOG(
"SELF", Sev::error) << row_data.getDiffN();
766 if (col_data.getDiffN().size1() != col_data.getN().size1())
768 if (col_data.getDiffN().size2() != col_data.getN().size2() *
SPACE_DIM) {
770 <<
"Side " << rowSide <<
" " << CN::EntityTypeName(rowType);
771 MOFEM_LOG(
"SELF", Sev::error) << col_data.getN();
772 MOFEM_LOG(
"SELF", Sev::error) << col_data.getDiffN();
777 auto t_T = getFTensor0FromVec(*
TPtr);
780 for (
int gg = 0; gg != nbIntegrationPts; gg++) {
782 const double alpha = t_w * vol;
785 for (; rr != nbRows; ++rr) {
787 auto t_col_base = col_data.getFTensor0N(gg, 0);
788 auto t_col_diff_base = col_data.getFTensor1DiffN<
SPACE_DIM>(gg, 0);
790 for (
int cc = 0; cc != nbCols; ++cc) {
792 locMat(rr, cc) += (t_row_base * t_col_base * alpha);
802 for (; rr < nbRowBaseFunctions; ++rr) {
817 boost::shared_ptr<VectorDouble>
TPtr;