v0.15.4
Loading...
Searching...
No Matches
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
ThermoElasticProblem Struct Reference
Collaboration diagram for ThermoElasticProblem:
[legend]

Classes

struct  BlockedThermalParameters
 
struct  BlockedThermoElasticParameters
 

Public Member Functions

 ThermoElasticProblem (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 [Run problem]
 
 ThermoElasticProblem (MoFEM::Interface &m_field)
 
MoFEMErrorCode runProblem ()
 

Private Member Functions

MoFEMErrorCode setupProblem ()
 add fields
 
MoFEMErrorCode getCommandLineParameters ()
 [Run problem]
 
MoFEMErrorCode bC ()
 [Set up problem]
 
MoFEMErrorCode OPs ()
 [Boundary condition]
 
MoFEMErrorCode tsSolve ()
 [Push operators to pipeline]
 
MoFEMErrorCode addMatThermalBlockOps (boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermalParameters > blockedParamsPtr, Sev sev)
 
MoFEMErrorCode addMatThermoElasticBlockOps (boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermoElasticParameters > blockedParamsPtr, Sev sev)
 
template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode opThermoElasticFactoryDomainRhs (MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HenckyOps::CommonData > elastic_common_ptr, boost::shared_ptr< ThermoElasticProblem::BlockedThermalParameters > thermal_common_ptr, boost::shared_ptr< ThermoElasticProblem::BlockedThermoElasticParameters > thermoelastic_common_ptr, Sev sev)
 
template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode opThermoElasticFactoryDomainRhs (MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, std::string elastic_block_name, std::string thermal_block_name, std::string thermoelastic_block_name, Sev sev, double scale=1)
 
template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode opThermoElasticFactoryDomainLhs (MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, std::string coupled_field_name, boost::shared_ptr< HenckyOps::CommonData > elastic_common_ptr, boost::shared_ptr< ThermoElasticProblem::BlockedThermalParameters > thermal_common_ptr, boost::shared_ptr< ThermoElasticProblem::BlockedThermoElasticParameters > thermoelastic_common_ptr, Sev sev)
 
template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode opThermoElasticFactoryDomainLhs (MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, std::string coupled_field_name, std::string elastic_block_name, std::string thermal_block_name, std::string thermoelastic_block_name, Sev sev, double scale=1)
 
MoFEMErrorCode setupProblem ()
 add fields
 
MoFEMErrorCode getCommandLineParameters ()
 
MoFEMErrorCode bC ()
 
MoFEMErrorCode OPs ()
 
MoFEMErrorCode tsSolve ()
 
MoFEMErrorCode addMatThermalBlockOps (boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermalParameters > blockedParamsPtr, Sev sev)
 
MoFEMErrorCode addMatThermoElasticBlockOps (boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermoElasticParameters > blockedParamsPtr, Sev sev)
 
template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode opThermoElasticFactoryDomainRhs (MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HenckyOps::CommonData > elastic_common_ptr, boost::shared_ptr< ThermoElasticProblem::BlockedThermalParameters > thermal_common_ptr, boost::shared_ptr< ThermoElasticProblem::BlockedThermoElasticParameters > thermoelastic_common_ptr, Sev sev)
 
template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode opThermoElasticFactoryDomainRhs (MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, std::string elastic_block_name, std::string thermal_block_name, std::string thermoelastic_block_name, Sev sev, double scale=1)
 
template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode opThermoElasticFactoryDomainLhs (MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, std::string coupled_field_name, boost::shared_ptr< HenckyOps::CommonData > elastic_common_ptr, boost::shared_ptr< ThermoElasticProblem::BlockedThermalParameters > thermal_common_ptr, boost::shared_ptr< ThermoElasticProblem::BlockedThermoElasticParameters > thermoelastic_common_ptr, Sev sev)
 
template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode opThermoElasticFactoryDomainLhs (MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, std::string coupled_field_name, std::string elastic_block_name, std::string thermal_block_name, std::string thermoelastic_block_name, Sev sev, double scale=1)
 

Private Attributes

MoFEM::InterfacemField
 
PetscBool doEvalField
 
std::array< double, 3 > fieldEvalCoords = {0.0, 0.0, 0.0}
 
boost::shared_ptr< FieldEvaluatorInterface::SetPtsDatafieldEvalData
 
boost::shared_ptr< VectorDoubletempFieldPtr
 
boost::shared_ptr< MatrixDoublefluxFieldPtr
 
boost::shared_ptr< MatrixDoubledispFieldPtr
 
boost::shared_ptr< MatrixDoubledispGradPtr
 
boost::shared_ptr< MatrixDoublestrainFieldPtr
 
boost::shared_ptr< MatrixDoublestressFieldPtr
 
std::array< double, SPACE_DIMfieldEvalCoords
 

Detailed Description

Examples
thermo_elastic.cpp.

Definition at line 130 of file thermo_elastic.cpp.

Constructor & Destructor Documentation

◆ ThermoElasticProblem() [1/2]

ThermoElasticProblem::ThermoElasticProblem ( MoFEM::Interface m_field)
inline

Definition at line 132 of file thermo_elastic.cpp.

132: mField(m_field) {}
MoFEM::Interface & mField

◆ ThermoElasticProblem() [2/2]

ThermoElasticProblem::ThermoElasticProblem ( MoFEM::Interface m_field)
inline

Definition at line 128 of file thermo_elastic.cpp.

128: mField(m_field) {}

Member Function Documentation

◆ addMatThermalBlockOps() [1/2]

MoFEMErrorCode ThermoElasticProblem::addMatThermalBlockOps ( boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pipeline,
std::string  block_name,
boost::shared_ptr< BlockedThermalParameters blockedParamsPtr,
Sev  sev 
)
private
Examples
thermo_elastic.cpp.

Definition at line 318 of file thermo_elastic.cpp.

321 {
323
324 struct OpMatThermalBlocks : public DomainEleOp {
325 OpMatThermalBlocks(boost::shared_ptr<double> conductivity_ptr,
326 boost::shared_ptr<double> capacity_ptr,
327 MoFEM::Interface &m_field, Sev sev,
328 std::vector<const CubitMeshSets *> meshset_vec_ptr)
329 : DomainEleOp(NOSPACE, DomainEleOp::OPSPACE),
330 conductivityPtr(conductivity_ptr), capacityPtr(capacity_ptr) {
331 CHK_THROW_MESSAGE(extractThermalBlockData(m_field, meshset_vec_ptr, sev),
332 "Cannot get data from thermal block");
333 }
334
335 MoFEMErrorCode doWork(int side, EntityType type,
338
339 for (auto &b : blockData) {
340
341 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
342 *conductivityPtr = b.conductivity;
343 *capacityPtr = b.capacity;
345 }
346 }
347
348 *conductivityPtr = default_heat_conductivity;
349 *capacityPtr = default_heat_capacity;
350
352 }
353
354 private:
355 struct BlockData {
356 double conductivity;
357 double capacity;
358 Range blockEnts;
359 };
360
361 std::vector<BlockData> blockData;
362
364 extractThermalBlockData(MoFEM::Interface &m_field,
365 std::vector<const CubitMeshSets *> meshset_vec_ptr,
366 Sev sev) {
368
369 for (auto m : meshset_vec_ptr) {
370 MOFEM_TAG_AND_LOG("WORLD", sev, "Mat Thermal Block") << *m;
371 std::vector<double> block_data;
372 CHKERR m->getAttributes(block_data);
373 if (block_data.size() < 2) {
374 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
375 "Expected that block has at least two attributes");
376 }
377 auto get_block_ents = [&]() {
378 Range ents;
379 CHKERR
380 m_field.get_moab().get_entities_by_handle(m->meshset, ents, true);
381 return ents;
382 };
383
384 MOFEM_TAG_AND_LOG("WORLD", sev, "Mat Thermal Block")
385 << m->getName() << ": conductivity = " << block_data[0]
386 << " capacity = " << block_data[1];
387
388 blockData.push_back({block_data[0], block_data[1], get_block_ents()});
389 }
390 MOFEM_LOG_CHANNEL("WORLD");
392 }
393
394 boost::shared_ptr<double> conductivityPtr;
395 boost::shared_ptr<double> capacityPtr;
396 };
397
398 pipeline.push_back(new OpMatThermalBlocks(
399 blockedParamsPtr->getHeatConductivityPtr(),
400 blockedParamsPtr->getHeatCapacityPtr(), mField, sev,
401
402 // Get blockset using regular expression
404
405 (boost::format("%s(.*)") % block_name).str()
406
407 ))
408
409 ));
410
412}
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ 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 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
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
FTensor::Index< 'm', 3 > m
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.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
double default_heat_capacity
double default_heat_conductivity

◆ addMatThermalBlockOps() [2/2]

MoFEMErrorCode ThermoElasticProblem::addMatThermalBlockOps ( boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pipeline,
std::string  block_name,
boost::shared_ptr< BlockedThermalParameters blockedParamsPtr,
Sev  sev 
)
private

◆ addMatThermoElasticBlockOps() [1/2]

MoFEMErrorCode ThermoElasticProblem::addMatThermoElasticBlockOps ( boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pipeline,
std::string  block_name,
boost::shared_ptr< BlockedThermoElasticParameters blockedParamsPtr,
Sev  sev 
)
private
Examples
thermo_elastic.cpp.

Definition at line 414 of file thermo_elastic.cpp.

418 {
420
421 struct OpMatThermoElasticBlocks : public DomainEleOp {
422 OpMatThermoElasticBlocks(boost::shared_ptr<VectorDouble> expansion_ptr,
423 boost::shared_ptr<double> ref_temp_ptr,
424 MoFEM::Interface &m_field, Sev sev,
425 std::vector<const CubitMeshSets *> meshset_vec_ptr)
426 : DomainEleOp(NOSPACE, DomainEleOp::OPSPACE),
427 expansionPtr(expansion_ptr), refTempPtr(ref_temp_ptr) {
429 extractThermoElasticBlockData(m_field, meshset_vec_ptr, sev),
430 "Cannot get data from thermoelastic block");
431 }
432
433 MoFEMErrorCode doWork(int side, EntityType type,
436
437 for (auto &b : blockData) {
438
439 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
440 *expansionPtr = b.expansion;
441 *refTempPtr = b.ref_temp;
443 }
444 }
445
447 *refTempPtr = default_ref_temp;
448
450 }
451
452 private:
453 struct BlockData {
454 double ref_temp;
455 VectorDouble expansion;
456 Range blockEnts;
457 };
458
459 std::vector<BlockData> blockData;
460
461 MoFEMErrorCode extractThermoElasticBlockData(
462 MoFEM::Interface &m_field,
463 std::vector<const CubitMeshSets *> meshset_vec_ptr, Sev sev) {
465
466 for (auto m : meshset_vec_ptr) {
467 MOFEM_TAG_AND_LOG("WORLD", sev, "Mat Thermoelastic Block") << *m;
468 std::vector<double> block_data;
469 CHKERR m->getAttributes(block_data);
470 if (block_data.size() < 2) {
471 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
472 "Expected that block has at least two attributes");
473 }
474 auto get_block_ents = [&]() {
475 Range ents;
476 CHKERR
477 m_field.get_moab().get_entities_by_handle(m->meshset, ents, true);
478 return ents;
479 };
480
481 auto get_expansion = [&]() {
482 VectorDouble expansion(SPACE_DIM, block_data[1]);
483 if (block_data.size() > 2) {
484 expansion[1] = block_data[2];
485 }
486 if (SPACE_DIM == 3 && block_data.size() > 3) {
487 expansion[2] = block_data[3];
488 }
489 return expansion;
490 };
491
492 auto coeff_exp_vec = get_expansion();
493
494 MOFEM_TAG_AND_LOG("WORLD", sev, "Mat Thermoelastic Block")
495 << " ref_temp = " << block_data[0]
496 << " expansion = " << coeff_exp_vec;
497
498 blockData.push_back({block_data[0], coeff_exp_vec, get_block_ents()});
499 }
500 MOFEM_LOG_CHANNEL("WORLD");
502 }
503
504 boost::shared_ptr<VectorDouble> expansionPtr;
505 boost::shared_ptr<double> refTempPtr;
506 };
507
508 pipeline.push_back(new OpMatThermoElasticBlocks(
509 blockedParamsPtr->getCoeffExpansionPtr(),
510 blockedParamsPtr->getRefTempPtr(), mField, sev,
511
512 // Get blockset using regular expression
514
515 (boost::format("%s(.*)") % block_name).str()
516
517 ))
518
519 ));
520
522}
constexpr int SPACE_DIM
UBlasVector< double > VectorDouble
Definition Types.hpp:68
double default_ref_temp
double default_coeff_expansion

◆ addMatThermoElasticBlockOps() [2/2]

MoFEMErrorCode ThermoElasticProblem::addMatThermoElasticBlockOps ( boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pipeline,
std::string  block_name,
boost::shared_ptr< BlockedThermoElasticParameters blockedParamsPtr,
Sev  sev 
)
private

◆ bC() [1/2]

MoFEMErrorCode ThermoElasticProblem::bC ( )
private

[Set up problem]

[Boundary condition]

Examples
thermo_elastic.cpp.

Definition at line 723 of file thermo_elastic.cpp.

723 {
725
726 MOFEM_LOG("SYNC", Sev::noisy) << "bC";
728
730 auto bc_mng = mField.getInterface<BcManager>();
731
732 auto get_skin = [&]() {
733 Range body_ents;
734 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, body_ents);
735 Skinner skin(&mField.get_moab());
736 Range skin_ents;
737 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
738 return skin_ents;
739 };
740
741 auto filter_flux_blocks = [&](auto skin, bool temp_bc = false) {
742 auto remove_cubit_blocks = [&](auto c) {
744 for (auto m :
745
746 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(c)
747
748 ) {
749 Range ents;
750 CHKERR mField.get_moab().get_entities_by_dimension(
751 m->getMeshset(), SPACE_DIM - 1, ents, true);
752 skin = subtract(skin, ents);
753 }
755 };
756
757 auto remove_named_blocks = [&](auto n) {
759 for (auto m : mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
760 std::regex(
761
762 (boost::format("%s(.*)") % n).str()
763
764 ))
765
766 ) {
767 Range ents;
768 CHKERR mField.get_moab().get_entities_by_dimension(
769 m->getMeshset(), SPACE_DIM - 1, ents, true);
770 skin = subtract(skin, ents);
771 }
773 };
774 if (!temp_bc) {
775 CHK_THROW_MESSAGE(remove_cubit_blocks(NODESET | TEMPERATURESET),
776 "remove_cubit_blocks");
777 CHK_THROW_MESSAGE(remove_named_blocks("TEMPERATURE"),
778 "remove_named_blocks");
779 }
780 CHK_THROW_MESSAGE(remove_cubit_blocks(SIDESET | HEATFLUXSET),
781 "remove_cubit_blocks");
782 CHK_THROW_MESSAGE(remove_named_blocks("HEATFLUX"), "remove_named_blocks");
783 CHK_THROW_MESSAGE(remove_named_blocks("CONVECTION"), "remove_named_blocks");
784 CHK_THROW_MESSAGE(remove_named_blocks("RADIATION"), "remove_named_blocks");
785 return skin;
786 };
787
788 auto filter_true_skin = [&](auto skin) {
789 Range boundary_ents;
790 ParallelComm *pcomm =
791 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
792 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
793 PSTATUS_NOT, -1, &boundary_ents);
794 return boundary_ents;
795 };
796
797 auto remove_flux_ents = filter_true_skin(filter_flux_blocks(get_skin()));
798 auto remove_temp_bc_ents =
799 filter_true_skin(filter_flux_blocks(get_skin(), true));
800
801 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
802 remove_flux_ents);
803 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
804 remove_temp_bc_ents);
805
806 MOFEM_LOG("SYNC", Sev::noisy) << remove_flux_ents << endl;
808
809 MOFEM_LOG("SYNC", Sev::noisy) << remove_temp_bc_ents << endl;
811
812#ifndef NDEBUG
813
816 (boost::format("flux_remove_%d.vtk") % mField.get_comm_rank()).str(),
817 remove_flux_ents);
818
821 (boost::format("temp_bc_remove_%d.vtk") % mField.get_comm_rank()).str(),
822 remove_temp_bc_ents);
823
824#endif
825
826 CHKERR mField.getInterface<ProblemsManager>()->removeDofsOnEntities(
827 simple->getProblemName(), "FLUX", remove_flux_ents);
828 CHKERR mField.getInterface<ProblemsManager>()->removeDofsOnEntities(
829 simple->getProblemName(), "TBC", remove_temp_bc_ents);
830
831 auto set_init_temp = [](boost::shared_ptr<FieldEntity> field_entity_ptr) {
832 field_entity_ptr->getEntFieldData()[0] = default_init_temp;
833 return 0;
834 };
835 CHKERR mField.getInterface<FieldBlas>()->fieldLambdaOnEntities(set_init_temp,
836 "T");
837
838 CHKERR bc_mng->removeBlockDOFsOnEntities<DisplacementCubitBcData>(
839 simple->getProblemName(), "U");
840 CHKERR bc_mng->pushMarkDOFsOnEntities<HeatFluxCubitBcData>(
841 simple->getProblemName(), "FLUX", false);
842
844}
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
#define MYPCOMM_INDEX
default communicator number PCOMM
@ TEMPERATURESET
@ HEATFLUXSET
@ NODESET
@ SIDESET
#define MOFEM_LOG(channel, severity)
Log.
const double c
speed of light (cm/ns)
const double n
refractive index of diffusive medium
Boundary condition manager for finite element problem setup.
Managing BitRefLevels.
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Definition of the displacement bc data structure.
Definition BCData.hpp:72
Basic algebra on fields.
Definition FieldBlas.hpp:21
Definition of the heat flux bc data structure.
Definition BCData.hpp:423
Problem manager is used to build and partition problems.
Simple interface for fast problem set-up.
Definition Simple.hpp:27
auto save_range
constexpr int SPACE_DIM
double default_init_temp

◆ bC() [2/2]

MoFEMErrorCode ThermoElasticProblem::bC ( )
private

◆ getCommandLineParameters() [1/2]

MoFEMErrorCode ThermoElasticProblem::getCommandLineParameters ( )
private

[Run problem]

[Get command line parameters]

Examples
thermo_elastic.cpp.

Definition at line 537 of file thermo_elastic.cpp.

537 {
539
540 auto get_command_line_parameters = [&]() {
542
543 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order", &order_temp,
544 PETSC_NULLPTR);
545 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order_temp", &order_temp,
546 PETSC_NULLPTR);
548 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order_flux", &order_flux,
549 PETSC_NULLPTR);
551 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-order_disp", &order_disp,
552 PETSC_NULLPTR);
553 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-atom_test", &atom_test,
554 PETSC_NULLPTR);
555 CHKERR PetscOptionsGetInt(PETSC_NULLPTR, "", "-save_every", &save_every,
556 PETSC_NULLPTR);
557
558 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-young_modulus",
559 &default_young_modulus, PETSC_NULLPTR);
560 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-poisson_ratio",
561 &default_poisson_ratio, PETSC_NULLPTR);
562 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-coeff_expansion",
563 &default_coeff_expansion, PETSC_NULLPTR);
564 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-ref_temp", &default_ref_temp,
565 PETSC_NULLPTR);
566 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-init_temp",
567 &default_init_temp, PETSC_NULLPTR);
568
569 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-capacity",
570 &default_heat_capacity, PETSC_NULLPTR);
571 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-conductivity",
572 &default_heat_conductivity, PETSC_NULLPTR);
573
574 if constexpr (SPACE_DIM == 2) {
575 do_output_domain = PETSC_TRUE;
576 do_output_skin = PETSC_FALSE;
577 } else {
578 do_output_domain = PETSC_FALSE;
579 do_output_skin = PETSC_TRUE;
580 }
581
582 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-output_domain",
583 &do_output_domain, PETSC_NULLPTR);
584 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-output_skin", &do_output_skin,
585 PETSC_NULLPTR);
586
587 MOFEM_LOG("ThermoElastic", Sev::inform)
588 << "Young's modulus " << default_young_modulus;
589 MOFEM_LOG("ThermoElastic", Sev::inform)
590 << "Poisson's ratio " << default_poisson_ratio;
591 MOFEM_LOG("ThermoElastic", Sev::inform)
592 << "Coeff of expansion " << default_coeff_expansion;
593 MOFEM_LOG("ThermoElastic", Sev::inform)
594 << "Default heat capacity " << default_heat_capacity;
595 MOFEM_LOG("ThermoElastic", Sev::inform)
596 << "Heat conductivity " << default_heat_conductivity;
597
598 MOFEM_LOG("ThermoElastic", Sev::inform)
599 << "Reference temperature " << default_ref_temp;
600 MOFEM_LOG("ThermoElastic", Sev::inform)
601 << "Initial temperature " << default_init_temp;
602
604 };
605
606 CHKERR get_command_line_parameters();
607
609}
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
int save_every
int order_flux
int atom_test
double default_ref_temp
double default_heat_capacity
int order_disp
double default_young_modulus
[Essential boundary conditions (Least square approach)]
PetscBool do_output_skin
double default_coeff_expansion
int order_temp
PetscBool do_output_domain
double default_heat_conductivity
double default_poisson_ratio

◆ getCommandLineParameters() [2/2]

MoFEMErrorCode ThermoElasticProblem::getCommandLineParameters ( )
private

◆ OPs() [1/2]

MoFEMErrorCode ThermoElasticProblem::OPs ( )
private

[Boundary condition]

[Push operators to pipeline]

Examples
thermo_elastic.cpp.

Definition at line 848 of file thermo_elastic.cpp.

848 {
850
851 MOFEM_LOG("SYNC", Sev::noisy) << "OPs";
853
854 auto pipeline_mng = mField.getInterface<PipelineManager>();
855 auto bc_mng = mField.getInterface<BcManager>();
856
857 auto boundary_marker =
858 bc_mng->getMergedBlocksMarker(vector<string>{"HEATFLUX"});
859
860 auto integration_rule = [](int, int, int approx_order) {
861 return 2 * approx_order;
862 };
864 CHKERR pipeline_mng->setDomainLhsIntegrationRule(integration_rule);
865 CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(integration_rule);
866 CHKERR pipeline_mng->setBoundaryLhsIntegrationRule(integration_rule);
867
868 auto block_thermal_params = boost::make_shared<BlockedThermalParameters>();
869 auto heat_conductivity_ptr = block_thermal_params->getHeatConductivityPtr();
870 auto heat_capacity_ptr = block_thermal_params->getHeatCapacityPtr();
871
872 auto block_thermoelastic_params =
873 boost::make_shared<BlockedThermoElasticParameters>();
874 auto coeff_expansion_ptr = block_thermoelastic_params->getCoeffExpansionPtr();
875 auto ref_temp_ptr = block_thermoelastic_params->getRefTempPtr();
876
877 // Default time scaling of BCs and sources, from command line arguments
878 auto time_scale =
879 boost::make_shared<TimeScale>("", false, [](const double) { return 1; });
880 auto def_time_scale = [time_scale](const double time) {
881 return (!time_scale->argFileScale) ? time : 1;
882 };
883 auto def_file_name = [time_scale](const std::string &&name) {
884 return (!time_scale->argFileScale) ? name : "";
885 };
886
887 // Files which define scaling for separate variables, if provided
888 auto time_bodyforce_scaling = boost::make_shared<TimeScale>(
889 def_file_name("bodyforce_scale.txt"), false, def_time_scale);
890 auto time_heatsource_scaling = boost::make_shared<TimeScale>(
891 def_file_name("heatsource_scale.txt"), false, def_time_scale);
892 auto time_temperature_scaling = boost::make_shared<TimeScale>(
893 def_file_name("temperature_bc_scale.txt"), false, def_time_scale);
894 auto time_displacement_scaling = boost::make_shared<TimeScale>(
895 def_file_name("displacement_bc_scale.txt"), false, def_time_scale);
896 auto time_flux_scaling = boost::make_shared<TimeScale>(
897 def_file_name("flux_bc_scale.txt"), false, def_time_scale);
898 auto time_force_scaling = boost::make_shared<TimeScale>(
899 def_file_name("force_bc_scale.txt"), false, def_time_scale);
900 auto time_convection_temp_scaling = boost::make_shared<TimeScale>(
901 def_file_name("convection_temp_scale.txt"), false, def_time_scale);
902 auto time_radiation_temp_scaling = boost::make_shared<TimeScale>(
903 def_file_name("radiation_temp_scale.txt"), false, def_time_scale);
904
905 auto add_domain_rhs_ops = [&](auto &pipeline) {
907 CHKERR addMatThermalBlockOps(pipeline, "MAT_THERMAL", block_thermal_params,
908 Sev::inform);
909 CHKERR addMatThermoElasticBlockOps(pipeline, "MAT_THERMOELASTIC",
910 block_thermoelastic_params, Sev::inform);
912
913 auto hencky_common_data_ptr =
914 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
915 mField, pipeline, "U", "MAT_ELASTIC", Sev::inform);
916 auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
917 auto mat_grad_ptr = hencky_common_data_ptr->matGradPtr;
918 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
919 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
920
921 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
922 auto vec_temp_dot_ptr = boost::make_shared<VectorDouble>();
923 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
924 auto vec_temp_div_ptr = boost::make_shared<VectorDouble>();
925
926 pipeline.push_back(new OpCalculateScalarFieldValues("T", vec_temp_ptr));
927 pipeline.push_back(
928 new OpCalculateScalarFieldValuesDot("T", vec_temp_dot_ptr));
930 "FLUX", vec_temp_div_ptr));
931 pipeline.push_back(
932 new OpCalculateHVecVectorField<3, SPACE_DIM>("FLUX", mat_flux_ptr));
933
934 CHKERR opThermoElasticFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
935 mField, pipeline, "U", "MAT_ELASTIC", "MAT_THERMAL",
936 "MAT_THERMOELASTIC", Sev::inform);
937
938 auto resistance = [heat_conductivity_ptr](const double, const double,
939 const double) {
940 return (1. / (*heat_conductivity_ptr));
941 };
942 // negative value is consequence of symmetric system
943 auto capacity = [heat_capacity_ptr](const double, const double,
944 const double) {
945 return -(*heat_capacity_ptr);
946 };
947 auto unity = [](const double, const double, const double) constexpr {
948 return -1.;
949 };
950 pipeline.push_back(
951 new OpHdivFlux("FLUX", mat_flux_ptr, resistance, mat_grad_ptr));
952 pipeline.push_back(new OpHDivTemp("FLUX", vec_temp_ptr, unity));
953 pipeline.push_back(new OpBaseDivFlux("T", vec_temp_div_ptr, unity));
954 pipeline.push_back(new OpBaseDotT("T", vec_temp_dot_ptr, capacity));
955
956 // Set source terms
958 pipeline, mField, "T", {time_scale, time_heatsource_scaling},
959 "HEAT_SOURCE", Sev::inform);
961 pipeline, mField, "U", {time_scale, time_bodyforce_scaling},
962 "BODY_FORCE", Sev::inform);
964 pipeline, mField, "T", vec_temp_ptr, "SETTEMP", Sev::inform);
965
967 };
968
969 auto add_domain_lhs_ops = [&](auto &pipeline) {
971 CHKERR addMatThermalBlockOps(pipeline, "MAT_THERMAL", block_thermal_params,
972 Sev::verbose);
973 CHKERR addMatThermoElasticBlockOps(pipeline, "MAT_THERMOELASTIC",
974 block_thermoelastic_params,
975 Sev::verbose);
977
978 auto hencky_common_data_ptr =
979 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
980 mField, pipeline, "U", "MAT_ELASTIC", Sev::inform, 1);
981 auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
982 auto mat_grad_ptr = hencky_common_data_ptr->matGradPtr;
983
984 auto resistance = [heat_conductivity_ptr](const double, const double,
985 const double) {
986 return (1. / (*heat_conductivity_ptr));
987 };
988 auto capacity = [heat_capacity_ptr](const double, const double,
989 const double) {
990 return -(*heat_capacity_ptr);
991 };
992 pipeline.push_back(
993 new OpHdivHdiv("FLUX", "FLUX", resistance, mat_grad_ptr));
994 pipeline.push_back(
995 new OpHdivT("FLUX", "T", []() constexpr { return -1; }, true));
996
997 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
998 pipeline.push_back(
999 new OpCalculateHVecVectorField<3, SPACE_DIM>("FLUX", mat_flux_ptr));
1000
1001 pipeline.push_back(
1002 new OpHdivU("FLUX", "U", mat_flux_ptr, resistance, mat_grad_ptr));
1003
1004 CHKERR opThermoElasticFactoryDomainLhs<SPACE_DIM, AT, IT, DomainEleOp>(
1005 mField, pipeline, "U", "T", "MAT_ELASTIC", "MAT_THERMAL",
1006 "MAT_THERMOELASTIC", Sev::inform);
1007
1008 auto op_capacity = new OpCapacity("T", "T", capacity);
1009 op_capacity->feScalingFun = [](const FEMethod *fe_ptr) {
1010 return fe_ptr->ts_a;
1011 };
1012 pipeline.push_back(op_capacity);
1013
1014 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
1015 pipeline.push_back(new OpCalculateScalarFieldValues("T", vec_temp_ptr));
1017 pipeline, mField, "T", vec_temp_ptr, "SETTEMP", Sev::verbose);
1018
1020 };
1021
1022 auto add_boundary_rhs_ops = [&](auto &pipeline) {
1024
1026
1028 pipeline, mField, "U", {time_scale, time_force_scaling}, "FORCE",
1029 Sev::inform);
1030
1031 // Temperature BC
1032
1033 using OpTemperatureBC =
1036 pipeline, mField, "FLUX", {time_scale, time_temperature_scaling},
1037 "TEMPERATURE", Sev::inform);
1038
1039 // Note: fluxes for temperature should be aggregated. Here separate is
1040 // NaturalMeshsetType<HEATFLUXSET>, we should add version with BLOCKSET,
1041 // convection, see example tutorials/vec-0_elasticity/src/NaturalBoundaryBC.hpp.
1042 // and vec-0_elasticity/elastic.cpp
1043
1044 using OpFluxBC =
1047 pipeline, mField, "TBC", {time_scale, time_flux_scaling}, "FLUX",
1048 Sev::inform);
1049
1051 using OpConvectionRhsBC =
1052 T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
1053 using OpRadiationRhsBC =
1054 T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
1055 auto temp_bc_ptr = boost::make_shared<VectorDouble>();
1056 pipeline.push_back(new OpCalculateScalarFieldValues("TBC", temp_bc_ptr));
1057 T::AddFluxToPipeline<OpConvectionRhsBC>::add(
1058 pipeline, mField, "TBC", temp_bc_ptr,
1059 {time_scale, time_convection_temp_scaling}, "CONVECTION", Sev::inform);
1060 T::AddFluxToPipeline<OpRadiationRhsBC>::add(
1061 pipeline, mField, "TBC", temp_bc_ptr,
1062 {time_scale, time_radiation_temp_scaling}, "RADIATION", Sev::inform);
1063
1064 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
1065 pipeline.push_back(
1066 new OpCalculateHVecVectorField<3, SPACE_DIM>("FLUX", mat_flux_ptr));
1067
1068 // This is temporary implementation. It be moved to LinearFormsIntegrators,
1069 // however for hybridised case, what is goal of this changes, such function
1070 // is implemented for fluxes in broken space. Thus ultimately this operator
1071 // would be not needed.
1072
1073 struct OpTBCTimesNormalFlux
1074 : public FormsIntegrators<BoundaryEleOp>::Assembly<PETSC>::OpBase {
1075
1077
1078 OpTBCTimesNormalFlux(const std::string field_name,
1079 boost::shared_ptr<MatrixDouble> vec,
1080 boost::shared_ptr<Range> ents_ptr = nullptr)
1081 : OP(field_name, field_name, OP::OPROW, ents_ptr), sourceVec(vec) {}
1082
1083 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data) {
1086 // get integration weights
1087 auto t_w = OP::getFTensor0IntegrationWeight();
1088 // get base function values on rows
1089 auto t_row_base = row_data.getFTensor0N();
1090 // get normal vector
1091 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1092 // get vector values
1093 auto t_vec = getFTensor1FromMat<SPACE_DIM, 1>(*sourceVec);
1094 // loop over integration points
1095 for (int gg = 0; gg != OP::nbIntegrationPts; gg++) {
1096 // take into account Jacobian
1097 const double alpha = t_w * (t_vec(i) * t_normal(i));
1098 // loop over rows base functions
1099 int rr = 0;
1100 for (; rr != OP::nbRows; ++rr) {
1101 OP::locF[rr] += alpha * t_row_base;
1102 ++t_row_base;
1103 }
1104 for (; rr < OP::nbRowBaseFunctions; ++rr)
1105 ++t_row_base;
1106 ++t_w; // move to another integration weight
1107 ++t_vec;
1108 ++t_normal;
1109 }
1110 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
1111 if (fe_type == MBTRI) {
1112 OP::locF /= 2;
1113 }
1115 }
1116
1117 protected:
1118 boost::shared_ptr<MatrixDouble> sourceVec;
1119 };
1120 pipeline.push_back(new OpTBCTimesNormalFlux("TBC", mat_flux_ptr));
1121
1122 struct OpBaseNormalTimesTBC
1123 : public FormsIntegrators<BoundaryEleOp>::Assembly<PETSC>::OpBase {
1124
1126
1127 OpBaseNormalTimesTBC(const std::string field_name,
1128 boost::shared_ptr<VectorDouble> vec,
1129 boost::shared_ptr<Range> ents_ptr = nullptr)
1130 : OP(field_name, field_name, OP::OPROW, ents_ptr), sourceVec(vec) {}
1131
1132 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data) {
1135 // get integration weights
1136 auto t_w = OP::getFTensor0IntegrationWeight();
1137 // get base function values on rows
1138 auto t_row_base = row_data.getFTensor1N<3>();
1139 // get normal vector
1140 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1141 // get vector values
1142 auto t_vec = getFTensor0FromVec(*sourceVec);
1143 // loop over integration points
1144 for (int gg = 0; gg != OP::nbIntegrationPts; gg++) {
1145 // take into account Jacobian
1146 const double alpha = t_w * t_vec;
1147 // loop over rows base functions
1148 int rr = 0;
1149 for (; rr != OP::nbRows; ++rr) {
1150 OP::locF[rr] += alpha * (t_row_base(i) * t_normal(i));
1151 ++t_row_base;
1152 }
1153 for (; rr < OP::nbRowBaseFunctions; ++rr)
1154 ++t_row_base;
1155 ++t_w; // move to another integration weight
1156 ++t_vec;
1157 ++t_normal;
1158 }
1159 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
1160 if (fe_type == MBTRI) {
1161 OP::locF /= 2;
1162 }
1164 }
1165
1166 protected:
1167 boost::shared_ptr<VectorDouble> sourceVec;
1168 };
1169
1170 pipeline.push_back(new OpBaseNormalTimesTBC("FLUX", temp_bc_ptr));
1171
1173 };
1174
1175 auto add_boundary_lhs_ops = [&](auto &pipeline) {
1177
1179
1180 using T =
1181 NaturalBC<BoundaryEleOp>::template Assembly<PETSC>::BiLinearForm<GAUSS>;
1182 using OpConvectionLhsBC =
1183 T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
1184 using OpRadiationLhsBC =
1185 T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
1186 auto temp_bc_ptr = boost::make_shared<VectorDouble>();
1187 pipeline.push_back(new OpCalculateScalarFieldValues("TBC", temp_bc_ptr));
1188 T::AddFluxToPipeline<OpConvectionLhsBC>::add(pipeline, mField, "TBC", "TBC",
1189 "CONVECTION", Sev::verbose);
1190 T::AddFluxToPipeline<OpRadiationLhsBC>::add(
1191 pipeline, mField, "TBC", "TBC", temp_bc_ptr, "RADIATION", Sev::verbose);
1192
1193 // This is temporary implementation. It be moved to LinearFormsIntegrators,
1194 // however for hybridised case, what is goal of this changes, such function
1195 // is implemented for fluxes in broken space. Thus ultimately this operator
1196 // would be not needed.
1197
1198 struct OpTBCTimesNormalFlux
1199 : public FormsIntegrators<BoundaryEleOp>::Assembly<PETSC>::OpBase {
1200
1202
1203 OpTBCTimesNormalFlux(const std::string row_field_name,
1204 const std::string col_field_name,
1205 boost::shared_ptr<Range> ents_ptr = nullptr)
1206 : OP(row_field_name, col_field_name, OP::OPROWCOL, ents_ptr) {
1207 this->sYmm = false;
1208 this->assembleTranspose = true;
1209 this->onlyTranspose = false;
1210 }
1211
1212 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
1213 EntitiesFieldData::EntData &col_data) {
1215
1217
1218 // get integration weights
1219 auto t_w = OP::getFTensor0IntegrationWeight();
1220 // get base function values on rows
1221 auto t_row_base = row_data.getFTensor0N();
1222 // get normal vector
1223 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1224 // loop over integration points
1225 for (int gg = 0; gg != OP::nbIntegrationPts; gg++) {
1226 // loop over rows base functions
1227 auto a_mat_ptr = &*OP::locMat.data().begin();
1228 int rr = 0;
1229 for (; rr != OP::nbRows; rr++) {
1230 // take into account Jacobian
1231 const double alpha = t_w * t_row_base;
1232 // get column base functions values at gauss point gg
1233 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
1234 // loop over columns
1235 for (int cc = 0; cc != OP::nbCols; cc++) {
1236 // calculate element of local matrix
1237 // using L2 norm of normal vector for convenient area calculation
1238 // for quads, tris etc.
1239 *a_mat_ptr += alpha * (t_col_base(i) * t_normal(i));
1240 ++t_col_base;
1241 ++a_mat_ptr;
1242 }
1243 ++t_row_base;
1244 }
1245 for (; rr < OP::nbRowBaseFunctions; ++rr)
1246 ++t_row_base;
1247 ++t_normal;
1248 ++t_w; // move to another integration weight
1249 }
1250 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
1251 if (fe_type == MBTRI) {
1252 OP::locMat /= 2;
1253 }
1255 }
1256 };
1257
1258 pipeline.push_back(new OpTBCTimesNormalFlux("TBC", "FLUX"));
1259
1261 };
1262
1263 // Set BCs by eliminating degrees of freedom
1264 auto get_bc_hook_rhs = [&]() {
1266 mField, pipeline_mng->getDomainRhsFE(),
1267 {time_scale, time_displacement_scaling});
1268 return hook;
1269 };
1270 auto get_bc_hook_lhs = [&]() {
1272 mField, pipeline_mng->getDomainLhsFE(),
1273 {time_scale, time_displacement_scaling});
1274 return hook;
1275 };
1276
1277 pipeline_mng->getDomainRhsFE()->preProcessHook = get_bc_hook_rhs();
1278 pipeline_mng->getDomainLhsFE()->preProcessHook = get_bc_hook_lhs();
1279
1280 CHKERR add_domain_rhs_ops(pipeline_mng->getOpDomainRhsPipeline());
1281 CHKERR add_domain_lhs_ops(pipeline_mng->getOpDomainLhsPipeline());
1282 CHKERR add_boundary_rhs_ops(pipeline_mng->getOpBoundaryRhsPipeline());
1283 CHKERR add_boundary_lhs_ops(pipeline_mng->getOpBoundaryLhsPipeline());
1284
1286}
#define FTENSOR_INDEX(DIM, I)
@ H1
continuous field
Definition definitions.h:85
@ HDIV
field with continuous normal traction
Definition definitions.h:87
auto integration_rule
@ GAUSS
Gaussian quadrature integration.
@ PETSC
Standard PETSc assembly.
FTensor::Index< 'i', SPACE_DIM > i
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
OpCalculateScalarFieldValuesFromPetscVecImpl< PetscData::CTX_SET_X_T > OpCalculateScalarFieldValuesDot
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMixDivTimesScalar< SPACE_DIM > OpHdivT
Integrate Lhs div of base of flux times base of temperature (FLUX x T) and transpose of it,...
OpHdivHdivImpl< SPACE_DIM, IS_LARGE_STRAINS > OpHdivHdiv
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, 1 > OpCapacity
Integrate Lhs base of temperature times (heat capacity) times base of temperature (T x T)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpBaseDotT
Integrate Rhs base of temperature time heat capacity times heat rate (T)
OpBaseDotT OpBaseDivFlux
Integrate Rhs base of temperature times divergence of flux (T)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpMixDivTimesU< 3, 1, SPACE_DIM > OpHDivTemp
Integrate Rhs div flux base times temperature (T)
OpCalculateQdotQLhs_dU< SPACE_DIM, GAUSS, AssemblyDomainEleOp, IS_LARGE_STRAINS > OpHdivU
Integrate Lhs of flux term coupled to displacement field.
OpHdivFluxImpl< SPACE_DIM, IS_LARGE_STRAINS > OpHdivFlux
constexpr auto field_name
static constexpr int approx_order
OpBaseImpl< PETSC, EdgeEleOp > OpBase
Definition radiation.cpp:29
Add operators pushing bases from local to physical configuration.
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
Class (Function) to enforce essential constrains.
Definition Essential.hpp:25
Structure for user loop methods on finite elements.
Assembly methods.
Definition Natural.hpp:65
Natural boundary conditions.
Definition Natural.hpp:57
Get vector field for H-div approximation.
Calculate divergence of vector field.
Specialization for double precision scalar field values calculation.
PipelineManager interface.
MoFEMErrorCode setDomainRhsIntegrationRule(RuleHookFun rule)
Set integration rule for domain right-hand side finite element.
MoFEMErrorCode addMatThermalBlockOps(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermalParameters > blockedParamsPtr, Sev sev)
MoFEMErrorCode addMatThermoElasticBlockOps(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermoElasticParameters > blockedParamsPtr, Sev sev)

◆ OPs() [2/2]

MoFEMErrorCode ThermoElasticProblem::OPs ( )
private

◆ opThermoElasticFactoryDomainLhs() [1/4]

template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode ThermoElasticProblem::opThermoElasticFactoryDomainLhs ( MoFEM::Interface m_field,
boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pip,
std::string  field_name,
std::string  coupled_field_name,
boost::shared_ptr< HenckyOps::CommonData elastic_common_ptr,
boost::shared_ptr< ThermoElasticProblem::BlockedThermalParameters thermal_common_ptr,
boost::shared_ptr< ThermoElasticProblem::BlockedThermoElasticParameters thermoelastic_common_ptr,
Sev  sev 
)
inlineprivate
Examples
thermo_elastic.cpp.

Definition at line 255 of file thermo_elastic.cpp.

264 {
266
267 using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
268 A>::template BiLinearForm<I>;
269 using OpKPiola = typename B::template OpGradTensorGrad<1, DIM, DIM, 1>;
270
272 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
273 pip.push_back(new OpCalculateScalarFieldValues("T", vec_temp_ptr));
274 auto coeff_expansion_ptr = thermoelastic_common_ptr->getCoeffExpansionPtr();
275 auto ref_temp_ptr = thermoelastic_common_ptr->getRefTempPtr();
276 pip.push_back(
277 new typename H::template OpCalculateHenckyThermalStress<DIM, I, 0>(
278 "U", vec_temp_ptr, elastic_common_ptr, coeff_expansion_ptr,
279 ref_temp_ptr));
280 pip.push_back(new typename H::template OpHenckyTangent<DIM, I, 0>(
281 field_name, elastic_common_ptr));
282 pip.push_back(new OpKPiola(field_name, field_name,
283 elastic_common_ptr->getMatTangent()));
284 pip.push_back(new typename H::template OpCalculateHenckyThermalStressdT<
285 DIM, I, AssemblyDomainEleOp, 0>(
286 field_name, coupled_field_name, elastic_common_ptr,
287 coeff_expansion_ptr));
288
290 }
constexpr IntegrationType I
constexpr AssemblyType A
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradTensorGrad< 1, SPACE_DIM, SPACE_DIM, 1 > OpKPiola
[Only used for dynamics]
Definition seepage.cpp:63
double H
Hardening.
Definition plastic.cpp:128

◆ opThermoElasticFactoryDomainLhs() [2/4]

template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode ThermoElasticProblem::opThermoElasticFactoryDomainLhs ( MoFEM::Interface m_field,
boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pip,
std::string  field_name,
std::string  coupled_field_name,
boost::shared_ptr< HenckyOps::CommonData elastic_common_ptr,
boost::shared_ptr< ThermoElasticProblem::BlockedThermalParameters thermal_common_ptr,
boost::shared_ptr< ThermoElasticProblem::BlockedThermoElasticParameters thermoelastic_common_ptr,
Sev  sev 
)
inlineprivate

Definition at line 251 of file thermo_elastic.cpp.

260 {
262
263 using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
264 A>::template BiLinearForm<I>;
265 using OpKPiola = typename B::template OpGradTensorGrad<1, DIM, DIM, 1>;
266
268 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
269 pip.push_back(new OpCalculateScalarFieldValues("T", vec_temp_ptr));
270 auto coeff_expansion_ptr = thermoelastic_common_ptr->getCoeffExpansionPtr();
271 auto ref_temp_ptr = thermoelastic_common_ptr->getRefTempPtr();
272 pip.push_back(
273 new typename H::template OpCalculateHenckyThermalStress<DIM, I, 0>(
274 "U", vec_temp_ptr, elastic_common_ptr, coeff_expansion_ptr,
275 ref_temp_ptr));
276 pip.push_back(new typename H::template OpHenckyTangent<DIM, I, 0>(
277 field_name, elastic_common_ptr));
278 pip.push_back(new OpKPiola(field_name, field_name,
279 elastic_common_ptr->getMatTangent()));
280 pip.push_back(new typename H::template OpCalculateHenckyThermalStressdT<
281 DIM, I, AssemblyDomainEleOp, 0>(
282 field_name, coupled_field_name, elastic_common_ptr,
283 coeff_expansion_ptr));
284
286 }

◆ opThermoElasticFactoryDomainLhs() [3/4]

template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode ThermoElasticProblem::opThermoElasticFactoryDomainLhs ( MoFEM::Interface m_field,
boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pip,
std::string  field_name,
std::string  coupled_field_name,
std::string  elastic_block_name,
std::string  thermal_block_name,
std::string  thermoelastic_block_name,
Sev  sev,
double  scale = 1 
)
inlineprivate

Definition at line 293 of file thermo_elastic.cpp.

298 {
300
301 auto elastic_common_ptr = commonDataFactory<DIM, I, DomainEleOp>(
302 m_field, pip, field_name, elastic_block_name, sev, scale);
303 auto thermal_common_ptr = boost::make_shared<BlockedThermalParameters>();
304 CHKERR addMatThermalBlockOps(pip, thermal_block_name, thermal_common_ptr,
305 Sev::inform);
306 auto thermoelastic_common_ptr =
307 boost::make_shared<BlockedThermoElasticParameters>();
308 CHKERR addMatThermoElasticBlockOps(pip, thermoelastic_block_name,
309 thermoelastic_common_ptr, Sev::inform);
310 CHKERR opThermoElasticFactoryDomainLhs<DIM, A, I, DomainEleOp>(
311 m_field, pip, field_name, coupled_field_name, elastic_common_ptr,
312 thermal_common_ptr, thermoelastic_common_ptr, sev);
313
315 }
double scale
Definition plastic.cpp:123

◆ opThermoElasticFactoryDomainLhs() [4/4]

template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode ThermoElasticProblem::opThermoElasticFactoryDomainLhs ( MoFEM::Interface m_field,
boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pip,
std::string  field_name,
std::string  coupled_field_name,
std::string  elastic_block_name,
std::string  thermal_block_name,
std::string  thermoelastic_block_name,
Sev  sev,
double  scale = 1 
)
inlineprivate

Definition at line 289 of file thermo_elastic.cpp.

294 {
296
297 auto elastic_common_ptr = commonDataFactory<DIM, I, DomainEleOp>(
298 m_field, pip, field_name, elastic_block_name, sev, scale);
299 auto thermal_common_ptr = boost::make_shared<BlockedThermalParameters>();
300 CHKERR addMatThermalBlockOps(pip, thermal_block_name, thermal_common_ptr,
301 Sev::inform);
302 auto thermoelastic_common_ptr =
303 boost::make_shared<BlockedThermoElasticParameters>();
304 CHKERR addMatThermoElasticBlockOps(pip, thermoelastic_block_name,
305 thermoelastic_common_ptr, Sev::inform);
306 CHKERR opThermoElasticFactoryDomainLhs<DIM, A, I, DomainEleOp>(
307 m_field, pip, field_name, coupled_field_name, elastic_common_ptr,
308 thermal_common_ptr, thermoelastic_common_ptr, sev);
309
311 }

◆ opThermoElasticFactoryDomainRhs() [1/4]

template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode ThermoElasticProblem::opThermoElasticFactoryDomainRhs ( MoFEM::Interface m_field,
boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pip,
std::string  field_name,
boost::shared_ptr< HenckyOps::CommonData elastic_common_ptr,
boost::shared_ptr< ThermoElasticProblem::BlockedThermalParameters thermal_common_ptr,
boost::shared_ptr< ThermoElasticProblem::BlockedThermoElasticParameters thermoelastic_common_ptr,
Sev  sev 
)
inlineprivate
Examples
thermo_elastic.cpp.

Definition at line 198 of file thermo_elastic.cpp.

207 {
209
210 using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
211 A>::template LinearForm<I>;
213 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
214 pip.push_back(new OpCalculateScalarFieldValues("T", vec_temp_ptr));
215 auto coeff_expansion_ptr = thermoelastic_common_ptr->getCoeffExpansionPtr();
216 auto ref_temp_ptr = thermoelastic_common_ptr->getRefTempPtr();
217 pip.push_back(
218 new typename H::template OpCalculateHenckyThermalStress<DIM, I, 0>(
219 "U", vec_temp_ptr, elastic_common_ptr, coeff_expansion_ptr,
220 ref_temp_ptr));
222 typename B::template OpGradTimesTensor<1, DIM, DIM>;
223 pip.push_back(new OpInternalForcePiola(
224 "U", elastic_common_ptr->getMatFirstPiolaStress()));
225
227 }
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesTensor< 1, SPACE_DIM, SPACE_DIM > OpInternalForcePiola
Definition seepage.cpp:65

◆ opThermoElasticFactoryDomainRhs() [2/4]

template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode ThermoElasticProblem::opThermoElasticFactoryDomainRhs ( MoFEM::Interface m_field,
boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pip,
std::string  field_name,
boost::shared_ptr< HenckyOps::CommonData elastic_common_ptr,
boost::shared_ptr< ThermoElasticProblem::BlockedThermalParameters thermal_common_ptr,
boost::shared_ptr< ThermoElasticProblem::BlockedThermoElasticParameters thermoelastic_common_ptr,
Sev  sev 
)
inlineprivate

Definition at line 194 of file thermo_elastic.cpp.

203 {
205
206 using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
207 A>::template LinearForm<I>;
209 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
210 pip.push_back(new OpCalculateScalarFieldValues("T", vec_temp_ptr));
211 auto coeff_expansion_ptr = thermoelastic_common_ptr->getCoeffExpansionPtr();
212 auto ref_temp_ptr = thermoelastic_common_ptr->getRefTempPtr();
213 pip.push_back(
214 new typename H::template OpCalculateHenckyThermalStress<DIM, I, 0>(
215 "U", vec_temp_ptr, elastic_common_ptr, coeff_expansion_ptr,
216 ref_temp_ptr));
218 typename B::template OpGradTimesTensor<1, DIM, DIM>;
219 pip.push_back(new OpInternalForcePiola(
220 "U", elastic_common_ptr->getMatFirstPiolaStress()));
221
223 }

◆ opThermoElasticFactoryDomainRhs() [3/4]

template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode ThermoElasticProblem::opThermoElasticFactoryDomainRhs ( MoFEM::Interface m_field,
boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pip,
std::string  field_name,
std::string  elastic_block_name,
std::string  thermal_block_name,
std::string  thermoelastic_block_name,
Sev  sev,
double  scale = 1 
)
inlineprivate

Definition at line 230 of file thermo_elastic.cpp.

235 {
237
238 auto elastic_common_ptr = commonDataFactory<DIM, I, DomainEleOp>(
239 m_field, pip, field_name, elastic_block_name, sev, scale);
240 auto thermal_common_ptr = boost::make_shared<BlockedThermalParameters>();
241 CHKERR addMatThermalBlockOps(pip, thermal_block_name, thermal_common_ptr,
242 Sev::inform);
243 auto thermoelastic_common_ptr =
244 boost::make_shared<BlockedThermoElasticParameters>();
245 CHKERR addMatThermoElasticBlockOps(pip, thermoelastic_block_name,
246 thermoelastic_common_ptr, Sev::inform);
247 CHKERR opThermoElasticFactoryDomainRhs<DIM, A, I, DomainEleOp>(
248 m_field, pip, field_name, elastic_common_ptr, thermal_common_ptr,
249 thermoelastic_common_ptr, sev);
250
252 }

◆ opThermoElasticFactoryDomainRhs() [4/4]

template<int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp >
MoFEMErrorCode ThermoElasticProblem::opThermoElasticFactoryDomainRhs ( MoFEM::Interface m_field,
boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pip,
std::string  field_name,
std::string  elastic_block_name,
std::string  thermal_block_name,
std::string  thermoelastic_block_name,
Sev  sev,
double  scale = 1 
)
inlineprivate

Definition at line 226 of file thermo_elastic.cpp.

231 {
233
234 auto elastic_common_ptr = commonDataFactory<DIM, I, DomainEleOp>(
235 m_field, pip, field_name, elastic_block_name, sev, scale);
236 auto thermal_common_ptr = boost::make_shared<BlockedThermalParameters>();
237 CHKERR addMatThermalBlockOps(pip, thermal_block_name, thermal_common_ptr,
238 Sev::inform);
239 auto thermoelastic_common_ptr =
240 boost::make_shared<BlockedThermoElasticParameters>();
241 CHKERR addMatThermoElasticBlockOps(pip, thermoelastic_block_name,
242 thermoelastic_common_ptr, Sev::inform);
243 CHKERR opThermoElasticFactoryDomainRhs<DIM, A, I, DomainEleOp>(
244 m_field, pip, field_name, elastic_common_ptr, thermal_common_ptr,
245 thermoelastic_common_ptr, sev);
246
248 }

◆ runProblem() [1/2]

MoFEMErrorCode ThermoElasticProblem::runProblem ( )

[Run problem]

Examples
thermo_elastic.cpp.

Definition at line 525 of file thermo_elastic.cpp.

525 {
529 CHKERR bC();
530 CHKERR OPs();
531 CHKERR tsSolve();
533}
MoFEMErrorCode getCommandLineParameters()
[Run problem]
MoFEMErrorCode setupProblem()
add fields
MoFEMErrorCode bC()
[Set up problem]
MoFEMErrorCode OPs()
[Boundary condition]
MoFEMErrorCode tsSolve()
[Push operators to pipeline]

◆ runProblem() [2/2]

MoFEMErrorCode ThermoElasticProblem::runProblem ( )

◆ setupProblem() [1/2]

MoFEMErrorCode ThermoElasticProblem::setupProblem ( )
private

add fields

[Get command line parameters]

[Set up problem]

Examples
thermo_elastic.cpp.

Definition at line 613 of file thermo_elastic.cpp.

613 {
616 // Add field
618 // Mechanical fields
620 CHKERR simple->addBoundaryField("U", H1, AINSWORTH_LEGENDRE_BASE, SPACE_DIM);
621 // Temperature
622 constexpr auto flux_space = (SPACE_DIM == 2) ? HCURL : HDIV;
623 CHKERR simple->addDomainField("T", L2, base, 1);
624 CHKERR simple->addDomainField("FLUX", flux_space, base, 1);
625 CHKERR simple->addBoundaryField("FLUX", flux_space, base, 1);
626 CHKERR simple->addBoundaryField("TBC", L2, base, 1);
627
628 CHKERR simple->setFieldOrder("U", order_disp);
629 CHKERR simple->setFieldOrder("FLUX", order_flux);
630 CHKERR simple->setFieldOrder("T", order_temp);
631 CHKERR simple->setFieldOrder("TBC", order_temp);
632
633 CHKERR simple->setUp();
634
635 int coords_dim = 3;
636 CHKERR PetscOptionsGetRealArray(NULL, NULL, "-field_eval_coords",
637 fieldEvalCoords.data(), &coords_dim,
638 &doEvalField);
639
640 tempFieldPtr = boost::make_shared<VectorDouble>();
641 fluxFieldPtr = boost::make_shared<MatrixDouble>();
642 dispFieldPtr = boost::make_shared<MatrixDouble>();
643 dispGradPtr = boost::make_shared<MatrixDouble>();
644 strainFieldPtr = boost::make_shared<MatrixDouble>();
645 stressFieldPtr = boost::make_shared<MatrixDouble>();
646
647 if (doEvalField) {
649 mField.getInterface<FieldEvaluatorInterface>()->getData<DomainEle>();
650
651 CHKERR mField.getInterface<FieldEvaluatorInterface>()->buildTree<SPACE_DIM>(
652 fieldEvalData, simple->getDomainFEName());
653
654 fieldEvalData->setEvalPoints(fieldEvalCoords.data(), 1);
655 auto no_rule = [](int, int, int) { return -1; };
656
657 auto field_eval_fe_ptr = fieldEvalData->feMethodPtr.lock();
658 field_eval_fe_ptr->getRuleHook = no_rule;
659
660 auto block_thermal_params = boost::make_shared<BlockedThermalParameters>();
661 auto block_thermoelastic_params =
662 boost::make_shared<BlockedThermoElasticParameters>();
663 auto coeff_expansion_ptr =
664 block_thermoelastic_params->getCoeffExpansionPtr();
665 auto ref_temp_ptr = block_thermoelastic_params->getRefTempPtr();
666
667 CHKERR addMatThermalBlockOps(field_eval_fe_ptr->getOpPtrVector(),
668 "MAT_THERMAL", block_thermal_params,
669 Sev::verbose);
671 field_eval_fe_ptr->getOpPtrVector(), "MAT_THERMOELASTIC",
672 block_thermoelastic_params, Sev::verbose);
673
675 field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV});
676
677 auto hencky_common_data_ptr =
678 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
679 mField, field_eval_fe_ptr->getOpPtrVector(), "U", "MAT_ELASTIC",
680 Sev::inform);
681 auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
682 auto dispGradPtr = hencky_common_data_ptr->matGradPtr;
683 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
684
685 field_eval_fe_ptr->getOpPtrVector().push_back(
687 field_eval_fe_ptr->getOpPtrVector().push_back(
689 field_eval_fe_ptr->getOpPtrVector().push_back(
691 field_eval_fe_ptr->getOpPtrVector().push_back(
693 dispGradPtr));
694
696
697 field_eval_fe_ptr->getOpPtrVector().push_back(
698 new
699 typename H::template OpCalculateHenckyThermalStress<SPACE_DIM, IT, 0>(
700 "U", tempFieldPtr, hencky_common_data_ptr, coeff_expansion_ptr,
701 ref_temp_ptr));
702 if (!IS_LARGE_STRAINS) {
703 field_eval_fe_ptr->getOpPtrVector().push_back(
705 hencky_common_data_ptr->getMatFirstPiolaStress(),
707 field_eval_fe_ptr->getOpPtrVector().push_back(
709 } else {
710 field_eval_fe_ptr->getOpPtrVector().push_back(
711 new typename H::template OpCalculateLogC<SPACE_DIM, IT>(
712 "U", hencky_common_data_ptr));
713 stressFieldPtr = hencky_common_data_ptr->getMatFirstPiolaStress();
714 strainFieldPtr = hencky_common_data_ptr->getMatLogC();
715 };
716 }
717
719}
FieldApproximationBase
approximation base
Definition definitions.h:58
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ DEMKOWICZ_JACOBI_BASE
Definition definitions.h:66
@ L2
field with C-1 continuity
Definition definitions.h:88
@ HCURL
field with continuous tangents
Definition definitions.h:86
PetscErrorCode PetscOptionsGetRealArray(PetscOptions *, const char pre[], const char name[], PetscReal dval[], PetscInt *nmax, PetscBool *set)
Field evaluator interface.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for double precision vector field values calculation.
Operator for symmetrizing tensor fields.
MoFEMErrorCode addDomainField(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_ZERO, int verb=-1)
Add field on domain.
Definition Simple.cpp:261
boost::shared_ptr< MatrixDouble > dispFieldPtr
boost::shared_ptr< MatrixDouble > strainFieldPtr
std::array< double, 3 > fieldEvalCoords
boost::shared_ptr< VectorDouble > tempFieldPtr
boost::shared_ptr< MatrixDouble > fluxFieldPtr
boost::shared_ptr< MatrixDouble > stressFieldPtr
boost::shared_ptr< MatrixDouble > dispGradPtr
boost::shared_ptr< FieldEvaluatorInterface::SetPtsData > fieldEvalData
constexpr bool IS_LARGE_STRAINS

◆ setupProblem() [2/2]

MoFEMErrorCode ThermoElasticProblem::setupProblem ( )
private

add fields

◆ tsSolve() [1/2]

MoFEMErrorCode ThermoElasticProblem::tsSolve ( )
private

[Push operators to pipeline]

[Solve]

Examples
thermo_elastic.cpp.

Definition at line 1290 of file thermo_elastic.cpp.

1290 {
1292
1295 ISManager *is_manager = mField.getInterface<ISManager>();
1296
1297 auto dm = simple->getDM();
1298 auto solver = pipeline_mng->createTSIM();
1299 auto snes_ctx_ptr = getDMSnesCtx(dm);
1300
1301 auto set_section_monitor = [&](auto solver) {
1303 SNES snes;
1304 CHKERR TSGetSNES(solver, &snes);
1305 CHKERR SNESMonitorSet(snes,
1306 (MoFEMErrorCode(*)(SNES, PetscInt, PetscReal,
1307 void *))MoFEMSNESMonitorFields,
1308 (void *)(snes_ctx_ptr.get()), nullptr);
1310 };
1311
1312 auto create_post_process_elements = [&]() {
1313 auto block_thermal_params = boost::make_shared<BlockedThermalParameters>();
1314
1315 auto block_thermoelastic_params =
1316 boost::make_shared<BlockedThermoElasticParameters>();
1317 auto coeff_expansion_ptr =
1318 block_thermoelastic_params->getCoeffExpansionPtr();
1319 auto ref_temp_ptr = block_thermoelastic_params->getRefTempPtr();
1320
1321 auto u_ptr = boost::make_shared<MatrixDouble>();
1322 auto mat_grad_ptr = boost::make_shared<MatrixDouble>();
1323 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
1324 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
1325 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
1326 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
1327
1328 auto push_domain_ops = [&](auto &pp_fe) {
1330 auto &pip = pp_fe->getOpPtrVector();
1331
1332 CHKERR addMatThermalBlockOps(pip, "MAT_THERMAL", block_thermal_params,
1333 Sev::verbose);
1335 pip, "MAT_THERMOELASTIC", block_thermoelastic_params, Sev::verbose);
1336
1338
1339 pip.push_back(new OpCalculateScalarFieldValues("T", vec_temp_ptr));
1340 pip.push_back(
1341 new OpCalculateHVecVectorField<3, SPACE_DIM>("FLUX", mat_flux_ptr));
1342
1343 pip.push_back(new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
1345 "U", mat_grad_ptr));
1346 auto elastic_common_ptr = commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
1347 mField, pip, "U", "MAT_ELASTIC", Sev::inform);
1349 pip.push_back(
1350 new
1351 typename H::template OpCalculateHenckyThermalStress<SPACE_DIM, IT, 0>(
1352 "U", vec_temp_ptr, elastic_common_ptr, coeff_expansion_ptr,
1353 ref_temp_ptr));
1354 if (!IS_LARGE_STRAINS) {
1355 pip.push_back(new OpSymmetrizeTensor<SPACE_DIM>(
1356 elastic_common_ptr->getMatFirstPiolaStress(), mat_stress_ptr));
1357 pip.push_back(
1358 new OpSymmetrizeTensor<SPACE_DIM>(mat_grad_ptr, mat_strain_ptr));
1359 } else {
1360 mat_stress_ptr = elastic_common_ptr->getMatFirstPiolaStress();
1361 mat_strain_ptr = elastic_common_ptr->getMatLogC();
1362 }
1363
1365 };
1366
1367 auto push_post_proc_ops = [&](auto &pp_fe) {
1369 auto &pip = pp_fe->getOpPtrVector();
1371
1372 if (!IS_LARGE_STRAINS) {
1373 pip.push_back(
1374
1375 new OpPPMap(
1376
1377 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
1378
1379 {{"T", vec_temp_ptr}},
1380
1381 {{"U", u_ptr}, {"FLUX", mat_flux_ptr}},
1382
1383 {},
1384
1385 {{"CAUCHY", mat_stress_ptr}, {"STRAIN", mat_strain_ptr}}
1386
1387 )
1388
1389 );
1390 } else {
1391 pip.push_back(
1392
1393 new OpPPMap(
1394
1395 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
1396
1397 {{"T", vec_temp_ptr}},
1398
1399 {{"U", u_ptr}, {"FLUX", mat_flux_ptr}},
1400
1401 {{"PIOLA", mat_stress_ptr}},
1402
1403 {{"HENCKY_STRAIN", mat_strain_ptr}}
1404
1405 )
1406
1407 );
1408 }
1409
1411 };
1412
1413 auto domain_post_proc = [&]() {
1414 if (do_output_domain == PETSC_FALSE)
1415 return boost::shared_ptr<PostProcEle>();
1416 auto pp_fe = boost::make_shared<PostProcEle>(mField);
1417 CHK_MOAB_THROW(push_domain_ops(pp_fe),
1418 "push domain ops to domain element");
1419 CHK_MOAB_THROW(push_post_proc_ops(pp_fe),
1420 "push post proc ops to domain element");
1421 return pp_fe;
1422 };
1423
1424 auto skin_post_proc = [&]() {
1425 if (do_output_skin == PETSC_FALSE)
1426 return boost::shared_ptr<SkinPostProcEle>();
1427 auto pp_fe = boost::make_shared<SkinPostProcEle>(mField);
1428 auto simple = mField.getInterface<Simple>();
1429 auto op_side = new OpLoopSide<SideEle>(mField, simple->getDomainFEName(),
1430 SPACE_DIM, Sev::verbose);
1431 CHK_MOAB_THROW(push_domain_ops(op_side),
1432 "push domain ops to side element");
1433 pp_fe->getOpPtrVector().push_back(op_side);
1434 CHK_MOAB_THROW(push_post_proc_ops(pp_fe),
1435 "push post proc ops to skin element");
1436 return pp_fe;
1437 };
1438
1439 return std::make_pair(domain_post_proc(), skin_post_proc());
1440 };
1441
1442 auto monitor_ptr = boost::make_shared<FEMethod>();
1443
1444 auto set_time_monitor = [&](auto dm, auto solver, auto domain_post_proc_fe,
1445 auto skin_post_proc_fe) {
1447 monitor_ptr->preProcessHook = [&]() {
1449
1450 if (save_every && (monitor_ptr->ts_step % save_every == 0)) {
1451 if (do_output_domain) {
1452 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
1453 domain_post_proc_fe,
1454 monitor_ptr->getCacheWeakPtr());
1455 CHKERR domain_post_proc_fe->writeFile(
1456 "out_" + boost::lexical_cast<std::string>(monitor_ptr->ts_step) +
1457 ".h5m");
1458 }
1459 if (do_output_skin) {
1460 CHKERR DMoFEMLoopFiniteElements(dm, simple->getBoundaryFEName(),
1461 skin_post_proc_fe,
1462 monitor_ptr->getCacheWeakPtr());
1463 CHKERR skin_post_proc_fe->writeFile(
1464 "out_skin_" +
1465 boost::lexical_cast<std::string>(monitor_ptr->ts_step) + ".h5m");
1466 }
1467 }
1468
1469 struct AtomTestResult {
1470 bool fail = false;
1471 std::string msg = "";
1472 };
1473 AtomTestResult atom_test_result;
1474
1475 auto fail_atom_test = [&atom_test_result](const std::string &msg) {
1476 atom_test_result.fail = true;
1477 atom_test_result.msg = msg;
1478 };
1479
1480 struct AtomTestData{
1481 double expected = 0.0;
1482 double tol = 0.0;
1483 };
1484
1485 if (doEvalField) {
1486
1488 ->evalFEAtThePoint<SPACE_DIM>(
1489 fieldEvalCoords.data(), 1e-12, simple->getProblemName(),
1490 simple->getDomainFEName(), fieldEvalData,
1492 MF_EXIST, QUIET);
1493
1494 if (atom_test) {
1495 auto eval_num_vec =
1496 createVectorMPI(mField.get_comm(), PETSC_DECIDE, 1);
1497 CHKERR VecZeroEntries(eval_num_vec);
1498 if (tempFieldPtr->size()) {
1499 CHKERR VecSetValue(eval_num_vec, 0, 1, ADD_VALUES);
1500 }
1501 CHKERR VecAssemblyBegin(eval_num_vec);
1502 CHKERR VecAssemblyEnd(eval_num_vec);
1503
1504 double eval_num;
1505 CHKERR VecSum(eval_num_vec, &eval_num);
1506 if (!(int)eval_num) {
1507 fail_atom_test(
1508 "did not find elements to evaluate the field, check the "
1509 "coordinates");
1510 }
1511 }
1512
1513 if (tempFieldPtr->size()) {
1514 auto t_temp = getFTensor0FromVec(*tempFieldPtr);
1515 MOFEM_LOG("ThermoElasticSync", Sev::inform)
1516 << "Eval point T: " << t_temp;
1517 if (atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
1518 AtomTestData atom_test_data;
1519 switch (atom_test) {
1520 case 1:
1521 case 2:
1522 case 3:
1523 atom_test_data = {554.48, 1e-2};
1524 break;
1525 case 4:
1526 atom_test_data = {250.0, 1e-2};
1527 break;
1528 case 5:
1529 atom_test_data = {1.0, 1e-2};
1530 break;
1531 default:
1532 fail_atom_test("unknown atom test number");
1533 }
1534 if (fabs(t_temp - atom_test_data.expected) > atom_test_data.tol) {
1535 fail_atom_test("wrong temperature value");
1536 }
1537 }
1538 }
1539 if (fluxFieldPtr->size1()) {
1541 auto t_flux = getFTensor1FromMat<SPACE_DIM>(*fluxFieldPtr);
1542 auto flux_mag = sqrt(t_flux(i) * t_flux(i));
1543 MOFEM_LOG("ThermoElasticSync", Sev::inform)
1544 << "Eval point FLUX magnitude: " << flux_mag;
1545 if (atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
1546 AtomTestData atom_test_data;
1547 switch (atom_test) {
1548 case 1:
1549 case 2:
1550 case 3:
1551 atom_test_data = {27008.0, 2e1};
1552 break;
1553 case 4:
1554 atom_test_data = {150e3, 1e-1};
1555 break;
1556 case 5:
1557 atom_test_data = {0.0, 1e-6};
1558 break;
1559 default:
1560 fail_atom_test("unknown atom test number");
1561 }
1562 if (fabs(flux_mag - atom_test_data.expected) > atom_test_data.tol) {
1563 fail_atom_test("wrong flux value");
1564 }
1565 }
1566 }
1567 if (dispFieldPtr->size1()) {
1569 auto t_disp = getFTensor1FromMat<SPACE_DIM>(*dispFieldPtr);
1570 auto disp_mag = sqrt(t_disp(i) * t_disp(i));
1571 MOFEM_LOG("ThermoElasticSync", Sev::inform)
1572 << "Eval point U magnitude: " << disp_mag;
1573 if (atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
1574 AtomTestData atom_test_data;
1575 switch (atom_test) {
1576 case 1:
1577 atom_test_data = {0.00345, 1e-5};
1578 break;
1579 case 2:
1580 case 3:
1581 atom_test_data = {0.00265, 1e-5};
1582 break;
1583 case 4:
1584 atom_test_data = {0.00061, 1e-5};
1585 break;
1586 case 5:
1587 atom_test_data = {std::sqrt(2) * (std::sqrt(std::exp(0.2)) - 1),
1588 1e-5};
1589 break;
1590 default:
1591 fail_atom_test("unknown atom test number");
1592 }
1593 if (fabs(disp_mag - atom_test_data.expected) > atom_test_data.tol) {
1594 fail_atom_test("wrong displacement value");
1595 }
1596 }
1597 }
1598 if (strainFieldPtr->size1()) {
1600 auto t_strain =
1601 getFTensor2SymmetricFromMat<SPACE_DIM>(*strainFieldPtr);
1602 auto t_strain_trace = t_strain(i, i);
1603 if (atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
1604 AtomTestData atom_test_data;
1605 switch (atom_test) {
1606 case 1:
1607 atom_test_data = {0.00679, 1e-5};
1608 break;
1609 case 2:
1610 case 3:
1611 atom_test_data = {0.00522, 1e-5};
1612 break;
1613 case 4:
1614 atom_test_data = {-0.00085, 1e-5};
1615 break;
1616 case 5:
1617 atom_test_data = {0.2, 1e-5};
1618 break;
1619 default:
1620 fail_atom_test("unknown atom test number");
1621 }
1622 if (fabs(t_strain_trace - atom_test_data.expected) >
1623 atom_test_data.tol) {
1624 fail_atom_test("wrong strain value");
1625 }
1626 }
1627 }
1628 if (stressFieldPtr->size1()) {
1629 double von_mises_stress;
1630 auto getVonMisesStress = [&](auto t_stress) {
1632 von_mises_stress = std::sqrt(
1633 0.5 *
1634 ((t_stress(0, 0) - t_stress(1, 1)) *
1635 (t_stress(0, 0) - t_stress(1, 1)) +
1636 (SPACE_DIM == 3 ? (t_stress(1, 1) - t_stress(2, 2)) *
1637 (t_stress(1, 1) - t_stress(2, 2))
1638 : 0) +
1639 (SPACE_DIM == 3 ? (t_stress(2, 2) - t_stress(0, 0)) *
1640 (t_stress(2, 2) - t_stress(0, 0))
1641 : 0) +
1642 6 * (t_stress(0, 1) * t_stress(0, 1) +
1643 (SPACE_DIM == 3 ? t_stress(1, 2) * t_stress(1, 2) : 0) +
1644 (SPACE_DIM == 3 ? t_stress(2, 0) * t_stress(2, 0) : 0))));
1646 };
1647 if (!IS_LARGE_STRAINS) {
1648 auto t_stress =
1649 getFTensor2SymmetricFromMat<SPACE_DIM>(*stressFieldPtr);
1650 CHKERR getVonMisesStress(t_stress);
1651 } else {
1652 auto t_stress =
1653 getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(*stressFieldPtr);
1654 CHKERR getVonMisesStress(t_stress);
1655 }
1656 MOFEM_LOG("ThermoElasticSync", Sev::inform)
1657 << "Eval point von Mises Stress: " << von_mises_stress;
1658 if (atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
1659 AtomTestData atom_test_data;
1660 switch (atom_test) {
1661 case 1:
1662 atom_test_data = {523.0, 5e-1};
1663 break;
1664 case 2:
1665 atom_test_data = {16.3, 5e-2};
1666 break;
1667 case 3:
1668 atom_test_data = {14.9, 5e-2};
1669 break;
1670 case 4:
1671 atom_test_data = {92.3, 2e-1};
1672 break;
1673 case 5:
1674 atom_test_data = {0.0, 5e-2};
1675 break;
1676 default:
1677 fail_atom_test("unknown atom test number");
1678 }
1679 if (fabs(von_mises_stress - atom_test_data.expected) >
1680 atom_test_data.tol) {
1681 fail_atom_test("wrong von Mises stress value");
1682 }
1683 }
1684 }
1686 }
1687
1688 if (atom_test_result.fail) {
1689 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
1690 "atom test %d failed: %s", atom_test,
1691 atom_test_result.msg.c_str());
1692 }
1693
1695 };
1696 auto null = boost::shared_ptr<FEMethod>();
1697 CHKERR DMMoFEMTSSetMonitor(dm, solver, simple->getDomainFEName(), null,
1698 monitor_ptr, null);
1700 };
1701
1702 auto set_fieldsplit_preconditioner = [&](auto solver) {
1704
1705 SNES snes;
1706 CHKERR TSGetSNES(solver, &snes);
1707 KSP ksp;
1708 CHKERR SNESGetKSP(snes, &ksp);
1709 PC pc;
1710 CHKERR KSPGetPC(ksp, &pc);
1711 PetscBool is_pcfs = PETSC_FALSE;
1712 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
1713
1714 // Setup fieldsplit (block) solver - optional: yes/no
1715 if (is_pcfs == PETSC_TRUE) {
1716 auto is_mng = mField.getInterface<ISManager>();
1717 auto name_prb = simple->getProblemName();
1718
1719 SmartPetscObj<IS> is_u;
1720 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb, ROW, "U", 0,
1721 SPACE_DIM, is_u);
1722 SmartPetscObj<IS> is_flux;
1723 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb, ROW, "FLUX", 0, 0,
1724 is_flux);
1725 SmartPetscObj<IS> is_T;
1726 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb, ROW, "T", 0, 0,
1727 is_T);
1728 SmartPetscObj<IS> is_TBC;
1729 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb, ROW, "TBC", 0, 0,
1730 is_TBC);
1731 IS is_tmp, is_tmp2;
1732 CHKERR ISExpand(is_T, is_flux, &is_tmp);
1733 CHKERR ISExpand(is_TBC, is_tmp, &is_tmp2);
1734 CHKERR ISDestroy(&is_tmp);
1735 auto is_TFlux = SmartPetscObj<IS>(is_tmp2);
1736
1737 CHKERR ISSort(is_u);
1738 CHKERR ISSort(is_TFlux);
1739 CHKERR PCFieldSplitSetIS(pc, PETSC_NULLPTR, is_TFlux);
1740 CHKERR PCFieldSplitSetIS(pc, PETSC_NULLPTR, is_u);
1741 }
1742
1744 };
1745
1746 auto B = createDMMatrix(dm);
1747 CHKERR TSSetIJacobian(solver, B, B, PETSC_NULLPTR, PETSC_NULLPTR);
1748 auto D = createDMVector(dm);
1749 CHKERR DMoFEMMeshToLocalVector(dm, D, INSERT_VALUES, SCATTER_FORWARD);
1750 CHKERR TSSetSolution(solver, D);
1751 CHKERR TSSetFromOptions(solver);
1752
1753 CHKERR set_section_monitor(solver);
1754 CHKERR set_fieldsplit_preconditioner(solver);
1755
1756 auto [domain_post_proc_fe, skin_post_proc_fe] =
1757 create_post_process_elements();
1758 CHKERR set_time_monitor(dm, solver, domain_post_proc_fe, skin_post_proc_fe);
1759
1760 CHKERR TSSetUp(solver);
1761 CHKERR TSSolve(solver, NULL);
1762
1764}
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
@ QUIET
@ ROW
@ MF_EXIST
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:576
auto createDMVector(DM dm)
Get smart vector from DM.
Definition DMMoFEM.hpp:1234
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition DMMoFEM.hpp:1191
double D
double tol
PetscErrorCode DMMoFEMTSSetMonitor(DM dm, TS ts, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
Set Monitor To TS solver.
Definition DMMoFEM.cpp:1046
MoFEMErrorCode MoFEMSNESMonitorFields(SNES snes, PetscInt its, PetscReal fgnorm, SnesCtx *ctx)
Sens monitor printing residual field by field.
Definition SnesCtx.cpp:596
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
auto getDMSnesCtx(DM dm)
Get SNES context data structure used by DM.
Definition DMMoFEM.hpp:1262
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
Section manager is used to create indexes and sections.
Definition ISManager.hpp:23
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
intrusive_ptr for managing petsc objects

◆ tsSolve() [2/2]

MoFEMErrorCode ThermoElasticProblem::tsSolve ( )
private

Member Data Documentation

◆ dispFieldPtr

boost::shared_ptr< MatrixDouble > ThermoElasticProblem::dispFieldPtr
private
Examples
thermo_elastic.cpp.

Definition at line 145 of file thermo_elastic.cpp.

◆ dispGradPtr

boost::shared_ptr< MatrixDouble > ThermoElasticProblem::dispGradPtr
private
Examples
thermo_elastic.cpp.

Definition at line 146 of file thermo_elastic.cpp.

◆ doEvalField

PetscBool ThermoElasticProblem::doEvalField
private
Examples
thermo_elastic.cpp.

Definition at line 139 of file thermo_elastic.cpp.

◆ fieldEvalCoords [1/2]

std::array<double, 3> ThermoElasticProblem::fieldEvalCoords = {0.0, 0.0, 0.0}
private
Examples
thermo_elastic.cpp.

Definition at line 140 of file thermo_elastic.cpp.

140{0.0, 0.0, 0.0};

◆ fieldEvalCoords [2/2]

std::array<double, SPACE_DIM> ThermoElasticProblem::fieldEvalCoords
private

Definition at line 136 of file thermo_elastic.cpp.

◆ fieldEvalData

boost::shared_ptr< FieldEvaluatorInterface::SetPtsData > ThermoElasticProblem::fieldEvalData
private
Examples
thermo_elastic.cpp.

Definition at line 141 of file thermo_elastic.cpp.

◆ fluxFieldPtr

boost::shared_ptr< MatrixDouble > ThermoElasticProblem::fluxFieldPtr
private
Examples
thermo_elastic.cpp.

Definition at line 144 of file thermo_elastic.cpp.

◆ mField

MoFEM::Interface & ThermoElasticProblem::mField
private
Examples
thermo_elastic.cpp.

Definition at line 137 of file thermo_elastic.cpp.

◆ strainFieldPtr

boost::shared_ptr< MatrixDouble > ThermoElasticProblem::strainFieldPtr
private
Examples
thermo_elastic.cpp.

Definition at line 147 of file thermo_elastic.cpp.

◆ stressFieldPtr

boost::shared_ptr< MatrixDouble > ThermoElasticProblem::stressFieldPtr
private
Examples
thermo_elastic.cpp.

Definition at line 148 of file thermo_elastic.cpp.

◆ tempFieldPtr

boost::shared_ptr< VectorDouble > ThermoElasticProblem::tempFieldPtr
private
Examples
thermo_elastic.cpp.

Definition at line 143 of file thermo_elastic.cpp.


The documentation for this struct was generated from the following files: