v0.14.0
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  BlockedParameters
 

Public Member Functions

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

Private Member Functions

MoFEMErrorCode setupProblem ()
 add fields More...
 
MoFEMErrorCode createCommonData ()
 [Set up problem] More...
 
MoFEMErrorCode bC ()
 [Create common data] More...
 
MoFEMErrorCode OPs ()
 [Boundary condition] More...
 
MoFEMErrorCode tsSolve ()
 [Push operators to pipeline] More...
 
MoFEMErrorCode addMatBlockOps (boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_elastic_name, std::string block_thermal_name, boost::shared_ptr< BlockedParameters > blockedParamsPtr, Sev sev)
 

Private Attributes

MoFEM::InterfacemField
 
PetscBool doEvalField
 
std::array< double, SPACE_DIMfieldEvalCoords
 
boost::shared_ptr< FieldEvaluatorInterface::SetPtsDatafieldEvalData
 
boost::shared_ptr< VectorDouble > scalarFieldPtr
 
boost::shared_ptr< MatrixDouble > vectorFieldPtr
 
boost::shared_ptr< MatrixDouble > tensorFieldPtr
 

Detailed Description

Examples
thermo_elastic.cpp.

Definition at line 152 of file thermo_elastic.cpp.

Constructor & Destructor Documentation

◆ ThermoElasticProblem()

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

Definition at line 154 of file thermo_elastic.cpp.

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

Member Function Documentation

◆ addMatBlockOps()

MoFEMErrorCode ThermoElasticProblem::addMatBlockOps ( boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &  pipeline,
std::string  block_elastic_name,
std::string  block_thermal_name,
boost::shared_ptr< BlockedParameters blockedParamsPtr,
Sev  sev 
)
private

[Calculate elasticity tensor]

[Calculate elasticity tensor]

Examples
thermo_elastic.cpp.

Definition at line 205 of file thermo_elastic.cpp.

208 {
210
211 struct OpMatElasticBlocks : public DomainEleOp {
212 OpMatElasticBlocks(boost::shared_ptr<MatrixDouble> m, double bulk_modulus_K,
213 double shear_modulus_G, MoFEM::Interface &m_field,
214 Sev sev,
215 std::vector<const CubitMeshSets *> meshset_vec_ptr)
216 : DomainEleOp(NOSPACE, DomainEleOp::OPSPACE), matDPtr(m),
217 bulkModulusKDefault(bulk_modulus_K),
218 shearModulusGDefault(shear_modulus_G) {
219 CHK_THROW_MESSAGE(extractElasticBlockData(m_field, meshset_vec_ptr, sev),
220 "Can not get data from block");
221 }
222
223 MoFEMErrorCode doWork(int side, EntityType type,
226
227 for (auto &b : blockData) {
228
229 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
230 CHKERR getMatDPtr(matDPtr, b.bulkModulusK, b.shearModulusG);
232 }
233 }
234
235 CHKERR getMatDPtr(matDPtr, bulkModulusKDefault, shearModulusGDefault);
237 }
238
239 private:
240 boost::shared_ptr<MatrixDouble> matDPtr;
241
242 struct BlockData {
243 double bulkModulusK;
244 double shearModulusG;
245 Range blockEnts;
246 };
247
248 double bulkModulusKDefault;
249 double shearModulusGDefault;
250 std::vector<BlockData> blockData;
251
253 extractElasticBlockData(MoFEM::Interface &m_field,
254 std::vector<const CubitMeshSets *> meshset_vec_ptr,
255 Sev sev) {
257
258 for (auto m : meshset_vec_ptr) {
259 MOFEM_TAG_AND_LOG("WORLD", sev, "Mat Elastic Block") << *m;
260 std::vector<double> block_data;
261 CHKERR m->getAttributes(block_data);
262 if (block_data.size() < 2) {
263 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
264 "Expected that block has two attributes");
265 }
266 auto get_block_ents = [&]() {
267 Range ents;
268 CHKERR
269 m_field.get_moab().get_entities_by_handle(m->meshset, ents, true);
270 return ents;
271 };
272
273 double young_modulus = block_data[0];
274 double poisson_ratio = block_data[1];
275 double bulk_modulus_K = young_modulus / (3 * (1 - 2 * poisson_ratio));
276 double shear_modulus_G = young_modulus / (2 * (1 + poisson_ratio));
277
278 MOFEM_TAG_AND_LOG("WORLD", sev, "Mat Elastic Block")
279 << m->getName() << ": E = " << young_modulus
280 << " nu = " << poisson_ratio;
281
282 blockData.push_back(
283 {bulk_modulus_K, shear_modulus_G, get_block_ents()});
284 }
285 MOFEM_LOG_CHANNEL("WORLD");
287 }
288
289 MoFEMErrorCode getMatDPtr(boost::shared_ptr<MatrixDouble> mat_D_ptr,
290 double bulk_modulus_K, double shear_modulus_G) {
292 //! [Calculate elasticity tensor]
293 auto set_material_stiffness = [&]() {
299 double A = (SPACE_DIM == 2)
300 ? 2 * shear_modulus_G /
301 (bulk_modulus_K + (4. / 3.) * shear_modulus_G)
302 : 1;
303 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(*mat_D_ptr);
304 t_D(i, j, k, l) =
305 2 * shear_modulus_G * ((t_kd(i, k) ^ t_kd(j, l)) / 4.) +
306 A * (bulk_modulus_K - (2. / 3.) * shear_modulus_G) * t_kd(i, j) *
307 t_kd(k, l);
308 };
309 //! [Calculate elasticity tensor]
310 constexpr auto size_symm = (SPACE_DIM * (SPACE_DIM + 1)) / 2;
311 mat_D_ptr->resize(size_symm * size_symm, 1);
312 set_material_stiffness();
314 }
315 };
316
317 double default_bulk_modulus_K =
319 double default_shear_modulus_G =
321
322 pipeline.push_back(new OpMatElasticBlocks(
323 blockedParamsPtr->getDPtr(), default_bulk_modulus_K,
324 default_bulk_modulus_K, mField, sev,
325
326 // Get blockset using regular expression
327 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
328
329 (boost::format("%s(.*)") % block_elastic_name).str()
330
331 ))
332
333 ));
334
335 struct OpMatThermalBlocks : public DomainEleOp {
336 OpMatThermalBlocks(boost::shared_ptr<double> expansion_ptr,
337 boost::shared_ptr<double> conductivity_ptr,
338 boost::shared_ptr<double> capacity_ptr,
339 MoFEM::Interface &m_field, Sev sev,
340 std::vector<const CubitMeshSets *> meshset_vec_ptr)
341 : DomainEleOp(NOSPACE, DomainEleOp::OPSPACE),
342 expansionPtr(expansion_ptr), conductivityPtr(conductivity_ptr),
343 capacityPtr(capacity_ptr) {
344 CHK_THROW_MESSAGE(extractThermallockData(m_field, meshset_vec_ptr, sev),
345 "Can not get data from block");
346 }
347
348 MoFEMErrorCode doWork(int side, EntityType type,
351
352 for (auto &b : blockData) {
353
354 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
355 *expansionPtr = b.expansion;
356 *conductivityPtr = b.conductivity;
357 *capacityPtr = b.capacity;
359 }
360 }
361
362 *expansionPtr = default_coeff_expansion;
363 *conductivityPtr = default_heat_conductivity;
364 *capacityPtr = default_heat_capacity;
365
367 }
368
369 private:
370 struct BlockData {
371 double expansion;
372 double conductivity;
373 double capacity;
374 Range blockEnts;
375 };
376
377 std::vector<BlockData> blockData;
378
380 extractThermallockData(MoFEM::Interface &m_field,
381 std::vector<const CubitMeshSets *> meshset_vec_ptr,
382 Sev sev) {
384
385 for (auto m : meshset_vec_ptr) {
386 MOFEM_TAG_AND_LOG("WORLD", sev, "Mat Thermal Block") << *m;
387 std::vector<double> block_data;
388 CHKERR m->getAttributes(block_data);
389 if (block_data.size() < 3) {
390 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
391 "Expected that block has two attributes");
392 }
393 auto get_block_ents = [&]() {
394 Range ents;
395 CHKERR
396 m_field.get_moab().get_entities_by_handle(m->meshset, ents, true);
397 return ents;
398 };
399
400 MOFEM_TAG_AND_LOG("WORLD", sev, "Mat Thermal Block")
401 << m->getName() << ": expansion = " << block_data[0]
402 << " conductivity = " << block_data[1] << " capacity "
403 << block_data[2];
404
405 blockData.push_back(
406 {block_data[0], block_data[1], block_data[2], get_block_ents()});
407 }
408 MOFEM_LOG_CHANNEL("WORLD");
410 }
411
412 boost::shared_ptr<double> expansionPtr;
413 boost::shared_ptr<double> conductivityPtr;
414 boost::shared_ptr<double> capacityPtr;
415 };
416
417 pipeline.push_back(new OpMatThermalBlocks(
418 blockedParamsPtr->getCoeffExpansionPtr(),
419 blockedParamsPtr->getHeatConductivityPtr(),
420 blockedParamsPtr->getHeatCapacityPtr(), mField, sev,
421
422 // Get blockset using regular expression
424
425 (boost::format("%s(.*)") % block_thermal_name).str()
426
427 ))
428
429 ));
430
432}
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
Definition: LogManager.hpp:362
constexpr int SPACE_DIM
Kronecker Delta class symmetric.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:595
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:447
@ NOSPACE
Definition: definitions.h:83
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:346
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
#define CHKERR
Inline error check.
Definition: definitions.h:535
double bulk_modulus_K
double shear_modulus_G
FTensor::Index< 'm', SPACE_DIM > m
constexpr auto t_kd
SeverityLevel
Severity levels.
Definition: LogManager.hpp:33
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
Definition: LogManager.hpp:284
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.
Definition: Exceptions.hpp:56
constexpr AssemblyType A
double young_modulus
Young modulus.
Definition: plastic.cpp:172
constexpr auto size_symm
Definition: plastic.cpp:42
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 refernce to pointer of interface.
double default_heat_capacity
double default_young_modulus
[Essential boundary conditions (Least square approach)]
double default_coeff_expansion
double default_heat_conductivity
double default_poisson_ratio

◆ bC()

MoFEMErrorCode ThermoElasticProblem::bC ( )
private

[Create common data]

[Boundary condition]

Examples
thermo_elastic.cpp.

Definition at line 551 of file thermo_elastic.cpp.

551 {
553
554 MOFEM_LOG("SYNC", Sev::noisy) << "bC";
556
558 auto bc_mng = mField.getInterface<BcManager>();
559
560 CHKERR bc_mng->removeBlockDOFsOnEntities<DisplacementCubitBcData>(
561 simple->getProblemName(), "U");
562 CHKERR bc_mng->pushMarkDOFsOnEntities<HeatFluxCubitBcData>(
563 simple->getProblemName(), "FLUX", false);
564
565 auto get_skin = [&]() {
566 Range body_ents;
567 CHKERR mField.get_moab().get_entities_by_dimension(0, SPACE_DIM, body_ents);
568 Skinner skin(&mField.get_moab());
569 Range skin_ents;
570 CHKERR skin.find_skin(0, body_ents, false, skin_ents);
571 return skin_ents;
572 };
573
574 auto filter_flux_blocks = [&](auto skin) {
575 auto remove_cubit_blocks = [&](auto c) {
577 for (auto m :
578
580
581 ) {
582 Range ents;
583 CHKERR mField.get_moab().get_entities_by_dimension(
584 m->getMeshset(), SPACE_DIM - 1, ents, true);
585 skin = subtract(skin, ents);
586 }
588 };
589
590 auto remove_named_blocks = [&](auto n) {
593 std::regex(
594
595 (boost::format("%s(.*)") % n).str()
596
597 ))
598
599 ) {
600 Range ents;
601 CHKERR mField.get_moab().get_entities_by_dimension(
602 m->getMeshset(), SPACE_DIM - 1, ents, true);
603 skin = subtract(skin, ents);
604 }
606 };
607
608 CHK_THROW_MESSAGE(remove_cubit_blocks(NODESET | TEMPERATURESET),
609 "remove_cubit_blocks");
610 CHK_THROW_MESSAGE(remove_cubit_blocks(SIDESET | HEATFLUXSET),
611 "remove_cubit_blocks");
612 CHK_THROW_MESSAGE(remove_named_blocks("TEMPERATURE"),
613 "remove_named_blocks");
614 CHK_THROW_MESSAGE(remove_named_blocks("HEATFLUX"), "remove_named_blocks");
615
616 return skin;
617 };
618
619 auto filter_true_skin = [&](auto skin) {
620 Range boundary_ents;
621 ParallelComm *pcomm =
622 ParallelComm::get_pcomm(&mField.get_moab(), MYPCOMM_INDEX);
623 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
624 PSTATUS_NOT, -1, &boundary_ents);
625 return boundary_ents;
626 };
627
628 auto remove_flux_ents = filter_true_skin(filter_flux_blocks(get_skin()));
629
630 CHKERR mField.getInterface<CommInterface>()->synchroniseEntities(
631 remove_flux_ents);
632
633 MOFEM_LOG("SYNC", Sev::noisy) << remove_flux_ents << endl;
635
636#ifndef NDEBUG
637
640 (boost::format("flux_remove_%d.vtk") % mField.get_comm_rank()).str(),
641 remove_flux_ents);
642
643#endif
644
645 CHKERR mField.getInterface<ProblemsManager>()->removeDofsOnEntities(
646 simple->getProblemName(), "FLUX", remove_flux_ents);
647
649}
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
Definition: LogManager.hpp:352
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition: acoustic.cpp:69
#define MYPCOMM_INDEX
default communicator number PCOMM
Definition: definitions.h:215
@ TEMPERATURESET
Definition: definitions.h:155
@ HEATFLUXSET
Definition: definitions.h:156
@ NODESET
Definition: definitions.h:146
@ SIDESET
Definition: definitions.h:147
FTensor::Index< 'n', SPACE_DIM > n
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:308
const double c
speed of light (cm/ns)
Simple interface for fast problem set-up.
Definition: BcManager.hpp:25
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
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

◆ createCommonData()

MoFEMErrorCode ThermoElasticProblem::createCommonData ( )
private

[Set up problem]

[Create common data]

Examples
thermo_elastic.cpp.

Definition at line 508 of file thermo_elastic.cpp.

508 {
510
511 auto get_command_line_parameters = [&]() {
513 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-young_modulus",
514 &default_young_modulus, PETSC_NULL);
515 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-poisson_ratio",
516 &default_poisson_ratio, PETSC_NULL);
517 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-coeff_expansion",
518 &default_coeff_expansion, PETSC_NULL);
519 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-ref_temp", &ref_temp,
520 PETSC_NULL);
521
522 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-capacity",
523 &default_heat_capacity, PETSC_NULL);
524 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-conductivity",
525 &default_heat_conductivity, PETSC_NULL);
526
527 MOFEM_LOG("ThermoElastic", Sev::inform)
528 << "Young modulus " << default_young_modulus;
529 MOFEM_LOG("ThermoElastic", Sev::inform)
530 << "Poisson ratio " << default_poisson_ratio;
531 MOFEM_LOG("ThermoElastic", Sev::inform)
532 << "Coeff of expansion " << default_coeff_expansion;
533 MOFEM_LOG("ThermoElastic", Sev::inform)
534 << "Capacity " << default_heat_capacity;
535 MOFEM_LOG("ThermoElastic", Sev::inform)
536 << "Heat conductivity " << default_heat_conductivity;
537
538 MOFEM_LOG("ThermoElastic", Sev::inform)
539 << "Reference_temperature " << ref_temp;
540
542 };
543
544 CHKERR get_command_line_parameters();
545
547}
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
double ref_temp

◆ OPs()

MoFEMErrorCode ThermoElasticProblem::OPs ( )
private

[Boundary condition]

[Push operators to pipeline]

Examples
thermo_elastic.cpp.

Definition at line 653 of file thermo_elastic.cpp.

653 {
655
656 MOFEM_LOG("SYNC", Sev::noisy) << "OPs";
658
659 auto pipeline_mng = mField.getInterface<PipelineManager>();
661 auto bc_mng = mField.getInterface<BcManager>();
662
663 auto boundary_marker =
664 bc_mng->getMergedBlocksMarker(vector<string>{"HEATFLUX"});
665
666 auto integration_rule = [](int, int, int approx_order) {
667 return 2 * approx_order;
668 };
669 CHKERR pipeline_mng->setDomainRhsIntegrationRule(integration_rule);
670 CHKERR pipeline_mng->setDomainLhsIntegrationRule(integration_rule);
671 CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(integration_rule);
672 CHKERR pipeline_mng->setBoundaryLhsIntegrationRule(integration_rule);
673
674 auto block_params = boost::make_shared<BlockedParameters>();
675 auto mDPtr = block_params->getDPtr();
676 auto coeff_expansion_ptr = block_params->getCoeffExpansionPtr();
677 auto heat_conductivity_ptr = block_params->getHeatConductivityPtr();
678 auto heat_capacity_ptr = block_params->getHeatCapacityPtr();
679
680 auto time_scale = boost::make_shared<TimeScale>();
681
682 auto add_domain_rhs_ops = [&](auto &pipeline) {
684 CHKERR addMatBlockOps(pipeline, "MAT_ELASTIC", "MAT_THERMAL", block_params,
685 Sev::inform);
687
688 auto mat_grad_ptr = boost::make_shared<MatrixDouble>();
689 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
690 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
691
692 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
693 auto vec_temp_dot_ptr = boost::make_shared<VectorDouble>();
694 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
695 auto vec_temp_div_ptr = boost::make_shared<VectorDouble>();
696
697 pipeline.push_back(new OpCalculateScalarFieldValues("T", vec_temp_ptr));
698 pipeline.push_back(
699 new OpCalculateScalarFieldValuesDot("T", vec_temp_dot_ptr));
701 "FLUX", vec_temp_div_ptr));
702 pipeline.push_back(
703 new OpCalculateHVecVectorField<3, SPACE_DIM>("FLUX", mat_flux_ptr));
704
706 "U", mat_grad_ptr));
707 pipeline.push_back(
708 new OpSymmetrizeTensor<SPACE_DIM>("U", mat_grad_ptr, mat_strain_ptr));
709 pipeline.push_back(new OpStressThermal("U", mat_strain_ptr, vec_temp_ptr,
710 mDPtr, coeff_expansion_ptr,
711 mat_stress_ptr));
712
713 pipeline.push_back(new OpSetBc("FLUX", true, boundary_marker));
714
715 pipeline.push_back(new OpInternalForceCauchy(
716 "U", mat_stress_ptr,
717 [](double, double, double) constexpr { return 1; }));
718
719 auto resistance = [heat_conductivity_ptr](const double, const double,
720 const double) {
721 return (1. / (*heat_conductivity_ptr));
722 };
723 // negative value is consequence of symmetric system
724 auto capacity = [heat_capacity_ptr](const double, const double,
725 const double) {
726 return -(*heat_capacity_ptr);
727 };
728 auto unity = [](const double, const double, const double) constexpr {
729 return -1.;
730 };
731 pipeline.push_back(new OpHdivFlux("FLUX", mat_flux_ptr, resistance));
732 pipeline.push_back(new OpHDivTemp("FLUX", vec_temp_ptr, unity));
733 pipeline.push_back(new OpBaseDivFlux("T", vec_temp_div_ptr, unity));
734 pipeline.push_back(new OpBaseDotT("T", vec_temp_dot_ptr, capacity));
735
736 pipeline.push_back(new OpUnSetBc("FLUX"));
737
739 pipeline, mField, "T", {time_scale}, "HEAT_SOURCE", Sev::inform);
741 pipeline, mField, "U", {time_scale}, "BODY_FORCE", Sev::inform);
743 pipeline, mField, "T", vec_temp_ptr, "SETTEMP", Sev::inform);
744
746 };
747
748 auto add_domain_lhs_ops = [&](auto &pipeline) {
750 CHKERR addMatBlockOps(pipeline, "MAT_ELASTIC", "MAT_THERMAL", block_params,
751 Sev::verbose);
753
754 pipeline.push_back(new OpSetBc("FLUX", true, boundary_marker));
755
756 pipeline.push_back(new OpKCauchy("U", "U", mDPtr));
757 pipeline.push_back(new ThermoElasticOps::OpKCauchyThermoElasticity(
758 "U", "T", mDPtr, coeff_expansion_ptr));
759
760 auto resistance = [heat_conductivity_ptr](const double, const double,
761 const double) {
762 return (1. / (*heat_conductivity_ptr));
763 };
764 auto capacity = [heat_capacity_ptr](const double, const double,
765 const double) {
766 return -(*heat_capacity_ptr);
767 };
768 pipeline.push_back(new OpHdivHdiv("FLUX", "FLUX", resistance));
769 pipeline.push_back(new OpHdivT(
770 "FLUX", "T", []() constexpr { return -1; }, true));
771
772 auto op_capacity = new OpCapacity("T", "T", capacity);
773 op_capacity->feScalingFun = [](const FEMethod *fe_ptr) {
774 return fe_ptr->ts_a;
775 };
776 pipeline.push_back(op_capacity);
777
778 pipeline.push_back(new OpUnSetBc("FLUX"));
779
780 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
781 pipeline.push_back(new OpCalculateScalarFieldValues("T", vec_temp_ptr));
783 pipeline, mField, "T", vec_temp_ptr, "SETTEMP", Sev::verbose);
784
786 };
787
788 auto add_boundary_rhs_ops = [&](auto &pipeline) {
790
792
793 pipeline.push_back(new OpSetBc("FLUX", true, boundary_marker));
794
796 pipeline_mng->getOpBoundaryRhsPipeline(), mField, "U", {time_scale}, "FORCE",
797 Sev::inform);
798
800 pipeline_mng->getOpBoundaryRhsPipeline(), mField, "FLUX", {time_scale},
801 "TEMPERATURE", Sev::inform);
802
803 pipeline.push_back(new OpUnSetBc("FLUX"));
804
805 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
806 pipeline.push_back(
807 new OpCalculateHVecVectorField<3, SPACE_DIM>("FLUX", mat_flux_ptr));
810 mField, pipeline, simple->getProblemName(), "FLUX", mat_flux_ptr,
811 {time_scale});
812
814 };
815
816 auto add_boundary_lhs_ops = [&](auto &pipeline) {
818
820
823 mField, pipeline, simple->getProblemName(), "FLUX");
824
826 };
827
828 auto get_bc_hook_rhs = [&]() {
830 mField, pipeline_mng->getDomainRhsFE(), {time_scale});
831 return hook;
832 };
833 auto get_bc_hook_lhs = [&]() {
835 mField, pipeline_mng->getDomainLhsFE(), {time_scale});
836 return hook;
837 };
838
839 pipeline_mng->getDomainRhsFE()->preProcessHook = get_bc_hook_rhs();
840 pipeline_mng->getDomainLhsFE()->preProcessHook = get_bc_hook_lhs();
841
842 CHKERR add_domain_rhs_ops(pipeline_mng->getOpDomainRhsPipeline());
843 CHKERR add_domain_lhs_ops(pipeline_mng->getOpDomainLhsPipeline());
844 CHKERR add_boundary_rhs_ops(pipeline_mng->getOpBoundaryRhsPipeline());
845 CHKERR add_boundary_lhs_ops(pipeline_mng->getOpBoundaryLhsPipeline());
846
848}
@ H1
continuous field
Definition: definitions.h:85
@ HDIV
field with continuous normal traction
Definition: definitions.h:87
auto integration_rule
OpCalculateScalarFieldValuesFromPetscVecImpl< PetscData::CTX_SET_X_T > OpCalculateScalarFieldValuesDot
static constexpr int approx_order
Add operators pushing bases from local to physical configuration.
Essential boundary conditions.
Definition: Essential.hpp:125
Class (Function) to enforce essential constrains.
Definition: Essential.hpp:39
structure for User Loop Methods on finite elements
Get vector field for H-div approximation.
Calculate divergence of vector field.
Get value at integration points for scalar field.
Get field gradients at integration pts for scalar filed rank 0, i.e. vector field.
Set indices on entities on finite element.
PipelineManager interface.
MoFEMErrorCode addMatBlockOps(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_elastic_name, std::string block_thermal_name, boost::shared_ptr< BlockedParameters > blockedParamsPtr, Sev sev)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpBaseDotT
Integrate Rhs base of temperature time heat capacity times heat rate (T)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMixDivTimesScalar< SPACE_DIM > OpHdivT
Integrate Lhs div of base of flux time base of temperature (FLUX x T) and transpose of it,...
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesVector< 3, SPACE_DIM, 1 > OpHdivFlux
Integrating Rhs flux base (1/k) flux (FLUX)
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 >::BiLinearForm< GAUSS >::OpMass< 3, SPACE_DIM > OpHdivHdiv
[Linear elastic problem]
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesSymTensor< 1, SPACE_DIM, SPACE_DIM > OpInternalForceCauchy
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradSymTensorGrad< 1, SPACE_DIM, SPACE_DIM, 0 > OpKCauchy
[Linear elastic problem]
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpMixDivTimesU< 3, 1, SPACE_DIM > OpHDivTemp
Integrate Rhs div flux base times temperature (T)
OpBaseDotT OpBaseDivFlux
Integrate Rhs base of temperature times divergence of flux (T)

◆ runProblem()

MoFEMErrorCode ThermoElasticProblem::runProblem ( )

[Run problem]

Examples
thermo_elastic.cpp.

Definition at line 435 of file thermo_elastic.cpp.

435 {
439 CHKERR bC();
440 CHKERR OPs();
441 CHKERR tsSolve();
443}
MoFEMErrorCode createCommonData()
[Set up problem]
MoFEMErrorCode setupProblem()
add fields
MoFEMErrorCode bC()
[Create common data]
MoFEMErrorCode OPs()
[Boundary condition]
MoFEMErrorCode tsSolve()
[Push operators to pipeline]

◆ setupProblem()

MoFEMErrorCode ThermoElasticProblem::setupProblem ( )
private

add fields

[Run problem]

[Set up problem]

Examples
thermo_elastic.cpp.

Definition at line 447 of file thermo_elastic.cpp.

447 {
450 // Add field
452 // Mechanical fields
453 CHKERR simple->addDomainField("U", H1, base, SPACE_DIM);
454 CHKERR simple->addBoundaryField("U", H1, base, SPACE_DIM);
455 // Temperature
456 constexpr auto flux_space = (SPACE_DIM == 2) ? HCURL : HDIV;
457 CHKERR simple->addDomainField("T", L2, AINSWORTH_LEGENDRE_BASE, 1);
458 CHKERR simple->addDomainField("FLUX", flux_space, DEMKOWICZ_JACOBI_BASE, 1);
459 CHKERR simple->addBoundaryField("FLUX", flux_space, DEMKOWICZ_JACOBI_BASE, 1);
460
461 CHKERR PetscOptionsGetInt(PETSC_NULL, "", "-order", &order, PETSC_NULL);
462 CHKERR simple->setFieldOrder("U", order + 1);
463 CHKERR simple->setFieldOrder("FLUX", order + 1);
464 CHKERR simple->setFieldOrder("T", order);
465 CHKERR simple->setUp();
466
467 int coords_dim = SPACE_DIM;
468 CHKERR PetscOptionsGetRealArray(NULL, NULL, "-field_eval_coords",
469 fieldEvalCoords.data(), &coords_dim,
470 &doEvalField);
471
472 scalarFieldPtr = boost::make_shared<VectorDouble>();
473 vectorFieldPtr = boost::make_shared<MatrixDouble>();
474 tensorFieldPtr = boost::make_shared<MatrixDouble>();
475
476 if (doEvalField) {
478 mField.getInterface<FieldEvaluatorInterface>()->getData<DomainEle>();
479
480 if constexpr (SPACE_DIM == 3) {
482 fieldEvalData, simple->getDomainFEName());
483 } else {
485 fieldEvalData, simple->getDomainFEName());
486 }
487
488 fieldEvalData->setEvalPoints(fieldEvalCoords.data(), 1);
489 auto no_rule = [](int, int, int) { return -1; };
490
491 auto field_eval_fe_ptr = fieldEvalData->feMethodPtr.lock();
492 field_eval_fe_ptr->getRuleHook = no_rule;
493
494 field_eval_fe_ptr->getOpPtrVector().push_back(
496 field_eval_fe_ptr->getOpPtrVector().push_back(
498 field_eval_fe_ptr->getOpPtrVector().push_back(
500 "U", tensorFieldPtr));
501 }
502
504}
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 PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
PetscErrorCode PetscOptionsGetRealArray(PetscOptions *, const char pre[], const char name[], PetscReal dval[], PetscInt *nmax, PetscBool *set)
Field evaluator interface.
Get values at integration pts for tensor filed rank 1, i.e. vector field.
boost::shared_ptr< FieldEvaluatorInterface::SetPtsData > fieldEvalData
std::array< double, SPACE_DIM > fieldEvalCoords
boost::shared_ptr< MatrixDouble > vectorFieldPtr
boost::shared_ptr< VectorDouble > scalarFieldPtr
boost::shared_ptr< MatrixDouble > tensorFieldPtr
int order

◆ tsSolve()

MoFEMErrorCode ThermoElasticProblem::tsSolve ( )
private

[Push operators to pipeline]

[Solve]

Examples
thermo_elastic.cpp.

Definition at line 852 of file thermo_elastic.cpp.

852 {
854
857 ISManager *is_manager = mField.getInterface<ISManager>();
858
859 auto dm = simple->getDM();
860 auto solver = pipeline_mng->createTSIM();
861 auto snes_ctx_ptr = getDMSnesCtx(dm);
862
863 auto set_section_monitor = [&](auto solver) {
865 SNES snes;
866 CHKERR TSGetSNES(solver, &snes);
867 CHKERR SNESMonitorSet(snes,
868 (MoFEMErrorCode(*)(SNES, PetscInt, PetscReal,
870 (void *)(snes_ctx_ptr.get()), nullptr);
872 };
873
874 auto create_post_process_element = [&]() {
875 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
876
877 auto block_params = boost::make_shared<BlockedParameters>();
878 auto mDPtr = block_params->getDPtr();
879 auto coeff_expansion_ptr = block_params->getCoeffExpansionPtr();
880
881 CHKERR addMatBlockOps(post_proc_fe->getOpPtrVector(), "MAT_ELASTIC",
882 "MAT_THERMAL", block_params, Sev::verbose);
883
885 post_proc_fe->getOpPtrVector(), {H1, HDIV});
886
887 auto mat_grad_ptr = boost::make_shared<MatrixDouble>();
888 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
889 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
890
891 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
892 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
893
894 post_proc_fe->getOpPtrVector().push_back(
895 new OpCalculateScalarFieldValues("T", vec_temp_ptr));
896 post_proc_fe->getOpPtrVector().push_back(
897 new OpCalculateHVecVectorField<3, SPACE_DIM>("FLUX", mat_flux_ptr));
898
899 auto u_ptr = boost::make_shared<MatrixDouble>();
900 post_proc_fe->getOpPtrVector().push_back(
902 post_proc_fe->getOpPtrVector().push_back(
904 mat_grad_ptr));
905 post_proc_fe->getOpPtrVector().push_back(
906 new OpSymmetrizeTensor<SPACE_DIM>("U", mat_grad_ptr, mat_strain_ptr));
907 post_proc_fe->getOpPtrVector().push_back(
908 new OpStressThermal("U", mat_strain_ptr, vec_temp_ptr, mDPtr,
909 coeff_expansion_ptr, mat_stress_ptr));
910
912
913 post_proc_fe->getOpPtrVector().push_back(
914
915 new OpPPMap(
916
917 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
918
919 {{"T", vec_temp_ptr}},
920
921 {{"U", u_ptr}, {"FLUX", mat_flux_ptr}},
922
923 {},
924
925 {{"STRAIN", mat_strain_ptr}, {"STRESS", mat_stress_ptr}}
926
927 )
928
929 );
930
931 return post_proc_fe;
932 };
933
934 auto monitor_ptr = boost::make_shared<FEMethod>();
935 auto post_proc_fe = create_post_process_element();
936
937 auto set_time_monitor = [&](auto dm, auto solver) {
939 monitor_ptr->preProcessHook = [&]() {
941
942 CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
943 post_proc_fe,
944 monitor_ptr->getCacheWeakPtr());
945 CHKERR post_proc_fe->writeFile(
946 "out_" + boost::lexical_cast<std::string>(monitor_ptr->ts_step) +
947 ".h5m");
948
949 if (doEvalField) {
950 if constexpr (SPACE_DIM == 3) {
952 ->evalFEAtThePoint3D(
953 fieldEvalCoords.data(), 1e-12, simple->getProblemName(),
954 simple->getDomainFEName(), fieldEvalData,
956 MF_EXIST, QUIET);
957 } else {
959 ->evalFEAtThePoint2D(
960 fieldEvalCoords.data(), 1e-12, simple->getProblemName(),
961 simple->getDomainFEName(), fieldEvalData,
963 MF_EXIST, QUIET);
964 }
965
966 if (scalarFieldPtr->size()) {
967 auto t_temp = getFTensor0FromVec(*scalarFieldPtr);
968 MOFEM_LOG("ThermoElasticSync", Sev::inform)
969 << "Eval point T: " << t_temp;
970 }
971 if (vectorFieldPtr->size1()) {
973 auto t_disp = getFTensor1FromMat<SPACE_DIM>(*vectorFieldPtr);
974 MOFEM_LOG("ThermoElasticSync", Sev::inform)
975 << "Eval point U magnitude: " << sqrt(t_disp(i) * t_disp(i));
976 }
977 if (tensorFieldPtr->size1()) {
979 auto t_disp_grad =
980 getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(*tensorFieldPtr);
981 MOFEM_LOG("ThermoElasticSync", Sev::inform)
982 << "Eval point U_GRAD trace: " << t_disp_grad(i, i);
983 }
984
986 }
987
989 };
990 auto null = boost::shared_ptr<FEMethod>();
991 CHKERR DMMoFEMTSSetMonitor(dm, solver, simple->getDomainFEName(), null,
992 monitor_ptr, null);
994 };
995
996 auto set_fieldsplit_preconditioner = [&](auto solver) {
998
999 SNES snes;
1000 CHKERR TSGetSNES(solver, &snes);
1001 KSP ksp;
1002 CHKERR SNESGetKSP(snes, &ksp);
1003 PC pc;
1004 CHKERR KSPGetPC(ksp, &pc);
1005 PetscBool is_pcfs = PETSC_FALSE;
1006 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
1007
1008 // Setup fieldsplit (block) solver - optional: yes/no
1009 if (is_pcfs == PETSC_TRUE) {
1010 auto bc_mng = mField.getInterface<BcManager>();
1011 auto is_mng = mField.getInterface<ISManager>();
1012 auto name_prb = simple->getProblemName();
1013
1014 SmartPetscObj<IS> is_u;
1015 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb, ROW, "U", 0,
1016 SPACE_DIM, is_u);
1017 SmartPetscObj<IS> is_flux;
1018 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb, ROW, "FLUX", 0, 0,
1019 is_flux);
1020 SmartPetscObj<IS> is_T;
1021 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb, ROW, "T", 0, 0,
1022 is_T);
1023 IS is_tmp;
1024 CHKERR ISExpand(is_T, is_flux, &is_tmp);
1025 auto is_TFlux = SmartPetscObj<IS>(is_tmp);
1026
1027 auto is_all_bc = bc_mng->getBlockIS(name_prb, "HEATFLUX", "FLUX", 0, 0);
1028 int is_all_bc_size;
1029 CHKERR ISGetSize(is_all_bc, &is_all_bc_size);
1030 MOFEM_LOG("ThermoElastic", Sev::inform)
1031 << "Field split block size " << is_all_bc_size;
1032 if (is_all_bc_size) {
1033 IS is_tmp2;
1034 CHKERR ISDifference(is_TFlux, is_all_bc, &is_tmp2);
1035 is_TFlux = SmartPetscObj<IS>(is_tmp2);
1036 CHKERR PCFieldSplitSetIS(pc, PETSC_NULL,
1037 is_all_bc); // boundary block
1038 }
1039
1040 CHKERR ISSort(is_u);
1041 CHKERR ISSort(is_TFlux);
1042 CHKERR PCFieldSplitSetIS(pc, PETSC_NULL, is_TFlux);
1043 CHKERR PCFieldSplitSetIS(pc, PETSC_NULL, is_u);
1044 }
1045
1047 };
1048
1049 auto D = createDMVector(dm);
1050 CHKERR TSSetSolution(solver, D);
1051 CHKERR TSSetFromOptions(solver);
1052
1053 CHKERR set_section_monitor(solver);
1054 CHKERR set_fieldsplit_preconditioner(solver);
1055 CHKERR set_time_monitor(dm, solver);
1056
1057 CHKERR TSSetUp(solver);
1058 CHKERR TSSolve(solver, NULL);
1059
1061}
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
Definition: LogManager.hpp:345
@ QUIET
Definition: definitions.h:208
@ ROW
Definition: definitions.h:123
@ MF_EXIST
Definition: definitions.h:100
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:440
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:572
auto createDMVector(DM dm)
Get smart vector from DM.
Definition: DMMoFEM.hpp:1003
double D
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:1042
MoFEMErrorCode MoFEMSNESMonitorFields(SNES snes, PetscInt its, PetscReal fgnorm, SnesCtx *snes_ctx)
Sens monitor printing residual field by field.
Definition: SnesCtx.cpp:226
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
Definition: Templates.hpp:135
auto getDMSnesCtx(DM dm)
Get SNES context data structure used by DM.
Definition: DMMoFEM.hpp:1031
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
Section manager is used to create indexes and sections.
Definition: ISManager.hpp:23
Post post-proc data at points from hash maps.
intrusive_ptr for managing petsc objects

Member Data Documentation

◆ doEvalField

PetscBool ThermoElasticProblem::doEvalField
private
Examples
thermo_elastic.cpp.

Definition at line 161 of file thermo_elastic.cpp.

◆ fieldEvalCoords

std::array<double, SPACE_DIM> ThermoElasticProblem::fieldEvalCoords
private
Examples
thermo_elastic.cpp.

Definition at line 162 of file thermo_elastic.cpp.

◆ fieldEvalData

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

Definition at line 163 of file thermo_elastic.cpp.

◆ mField

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

Definition at line 159 of file thermo_elastic.cpp.

◆ scalarFieldPtr

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

Definition at line 165 of file thermo_elastic.cpp.

◆ tensorFieldPtr

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

Definition at line 167 of file thermo_elastic.cpp.

◆ vectorFieldPtr

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

Definition at line 166 of file thermo_elastic.cpp.


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