13 #include <MGIS/Behaviour/Behaviour.hxx>
14 #include <MGIS/Behaviour/BehaviourData.hxx>
15 #include "MGIS/LibrariesManager.hxx"
16 #include "MGIS/Behaviour/Integrate.hxx"
19using namespace mgis::behaviour;
23 constexpr double inv_sqr2 = boost::math::constants::half_root_two<double>();
25 #define VOIGT_VEC_SYMM_3D(VEC) \
26 VEC[0], inv_sqr2 *VEC[3], inv_sqr2 *VEC[4], VEC[1], inv_sqr2 *VEC[5], VEC[2]
28 #define VOIGT_VEC_SYMM_2D(VEC) VEC[0], inv_sqr2 *VEC[3], VEC[1]
30 #define VOIGT_VEC_SYMM_2D_FULL(VEC) \
31 VEC[0], inv_sqr2 *VEC[3], 0., VEC[1], 0., VEC[2]
33 #define VOIGT_VEC_3D(VEC) \
34 VEC[0], VEC[3], VEC[5], VEC[4], VEC[1], VEC[7], VEC[6], VEC[8], VEC[2]
36 #define VOIGT_VEC_2D(VEC) VEC[0], VEC[3], VEC[4], VEC[1]
38 #define VOIGT_VEC_2D_FULL(VEC) \
39 VEC[0], VEC[3], 0., VEC[4], VEC[1], 0., 0., 0., VEC[2]
41template <ModelHypothesis MH>
struct MFrontEleType;
45 MFrontEleType() =
delete;
46 ~MFrontEleType() =
delete;
50 using PostProcDomainEle = PostProcBrokenMeshInMoabBase<DomainEle>;
57 MFrontEleType() =
delete;
58 ~MFrontEleType() =
delete;
62 using PostProcDomainEle = PostProcBrokenMeshInMoabBase<DomainEle>;
69 MFrontEleType() =
delete;
70 ~MFrontEleType() =
delete;
74 using PostProcDomainEle = PostProcBrokenMeshInMoabBase<DomainEle>;
80template <ModelHypothesis MH, AssemblyType AT = AssemblyType::PETSC>
81struct MFrontInterfaceImpl :
public MFrontInterface {
85 using DomainEle =
typename MFrontEleType<MH>::DomainEle;
86 using DomainEleOp =
typename MFrontEleType<MH>::DomainEleOp;
87 using PostProcDomainEle =
typename MFrontEleType<MH>::PostProcDomainEle;
89 static constexpr int DIM = MFrontEleType<MH>::SPACE_DIM;
91 using OpInternalForce =
92 typename FormsIntegrators<DomainEleOp>::template Assembly<AT>::
94 using OpAssembleLhsFiniteStrains =
95 typename FormsIntegrators<DomainEleOp>::template Assembly<
98 using OpAssembleLhsSmallStrains =
99 typename FormsIntegrators<DomainEleOp>::template Assembly<AT>::
106 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
110 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
114 setUpdateInternalVariablesOperators(ForcesAndSourcesCore::RuleHookFun rule,
117 MoFEMErrorCode setPostProcessOperators(ForcesAndSourcesCore::RuleHookFun rule,
123 std::string fe_name)
override;
126 string fe_name)
override;
129 setMonitor(boost::shared_ptr<MoFEM::FEMethod> monitor_ptr)
override {
131 monitorPtr = monitor_ptr;
138 string optionsPrefix;
140 SmartPetscObj<DM> dM;
143 PetscBool saveDomain;
145 PetscBool testJacobian;
146 PetscReal randomFieldScale;
148 bool isFiniteKinematics;
152 boost::shared_ptr<PostProcDomainEle> postProcFe;
153 boost::shared_ptr<DomainEle> updateIntVariablesElePtr;
155 boost::shared_ptr<moab::Interface> moabGaussIntPtr;
157 boost::shared_ptr<MoFEM::FEMethod> monitorPtr;
159 boost::shared_ptr<CommonData> commonDataPtr;
162template <ModelHypothesis MH>
163boost::shared_ptr<MFrontInterface>
168 return boost::make_shared<MFrontInterfaceImpl<MH, PETSC>>(m_field);
170 return boost::make_shared<MFrontInterfaceImpl<MH, SCHUR>>(m_field);
172 return boost::make_shared<MFrontInterfaceImpl<MH, BLOCK_MAT>>(m_field);
174 return boost::make_shared<MFrontInterfaceImpl<MH, BLOCK_SCHUR>>(m_field);
179 return boost::shared_ptr<MFrontInterface>();
182boost::shared_ptr<MFrontInterface>
188 return createMFrontInterfaceImpl<TRIDIMENSIONAL>(m_field, at);
190 return createMFrontInterfaceImpl<PLANESTRAIN>(m_field, at);
192 return createMFrontInterfaceImpl<AXISYMMETRICAL>(m_field, at);
196 return boost::shared_ptr<MFrontInterface>();
199struct MFrontInterface::CommonData {
204 const int nb_gauss_pts,
const int var_size,
205 const int grad_size,
const int stress_size,
213 boost::shared_ptr<MatrixDouble> mGradPtr;
214 boost::shared_ptr<MatrixDouble> mStressPtr;
215 boost::shared_ptr<MatrixDouble> mFullStrainPtr;
216 boost::shared_ptr<MatrixDouble> mFullStressPtr;
218 boost::shared_ptr<MatrixDouble> mPrevGradPtr;
219 boost::shared_ptr<MatrixDouble> mPrevStressPtr;
221 boost::shared_ptr<MatrixDouble> mDispPtr;
222 boost::shared_ptr<MatrixDouble> materialTangentPtr;
223 boost::shared_ptr<MatrixDouble> mFullTangentPtr;
224 boost::shared_ptr<MatrixDouble> internalVariablePtr;
228 std::map<int, BlockData> setOfBlocksData;
229 std::map<EntityHandle, int> blocksIDmap;
235 Tag internalVariableTag;
240enum DataTags { RHS = 0, LHS };
242struct MFrontInterface::CommonData::BlockData {
245 : isFiniteStrain(false), behaviourPath(
"src/libBehaviour.so"),
246 behaviourName(
"LinearElasticity") {
249 externalVariable = 0;
255 behDataPtr->K[0] = 0;
257 behDataPtr->K[0] = 5;
262 MoFEMErrorCode setBlockBehaviourData(
bool set_params_from_blocks);
267 string behaviourPath;
268 string behaviourName;
270 boost::shared_ptr<mgis::behaviour::Behaviour> mGisBehaviour;
271 mgis::behaviour::BehaviourDataView bView;
272 boost::shared_ptr<mgis::behaviour::BehaviourData> behDataPtr;
279 vector<double> params;
283 double externalVariable;
288MoFEMErrorCode MFrontInterface::CommonData::BlockData::setBlockBehaviourData(
289 bool set_params_from_blocks) {
293 auto &mgis_bv = *mGisBehaviour;
295 sizeIntVar = getArraySize(mgis_bv.isvs, mgis_bv.hypothesis);
296 sizeExtVar = getArraySize(mgis_bv.esvs, mgis_bv.hypothesis);
297 sizeGradVar = getArraySize(mgis_bv.gradients, mgis_bv.hypothesis);
299 getArraySize(mgis_bv.thermodynamic_forces, mgis_bv.hypothesis);
301 behDataPtr = boost::make_shared<BehaviourData>(BehaviourData{mgis_bv});
302 bView = make_view(*behDataPtr);
303 const int total_number_of_params = mgis_bv.mps.size();
305 if (set_params_from_blocks) {
307 if (params.size() < total_number_of_params)
309 "Not enough parameters supplied for this block. We have %zu "
310 "provided where %d are necessary for this block",
311 params.size(), total_number_of_params);
313 for (
int dd = 0;
dd < total_number_of_params; ++
dd) {
314 setMaterialProperty(behDataPtr->s0, dd, params[dd]);
315 setMaterialProperty(behDataPtr->s1, dd, params[dd]);
319 if (isFiniteStrain) {
320 behDataPtr->K[0] = 0;
321 behDataPtr->K[1] = 2;
322 behDataPtr->K[2] = 2;
324 behDataPtr->K[0] = 0;
325 behDataPtr->K[1] = 0;
328 for (
auto &mb : {&behDataPtr->s0, &behDataPtr->s1}) {
329 mb->dissipated_energy = dIssipation;
330 mb->stored_energy = storedEnergy;
331 setExternalStateVariable(*mb, 0, externalVariable);
340 string block_name =
"MAT_MFRONT";
342 if (it->getName().compare(0, block_name.size(), block_name) == 0) {
343 std::vector<double> block_data;
345 CHKERR it->getAttributes(block_data);
346 const int id = it->getMeshsetId();
348 CHKERR mField.get_moab().get_entities_by_dimension(
349 meshset, dim, setOfBlocksData[
id].eNts,
true);
350 for (
auto ent : setOfBlocksData[id].eNts)
351 blocksIDmap[ent] = id;
353 setOfBlocksData[id].iD = id;
354 setOfBlocksData[id].params.resize(block_data.size());
356 for (
int n = 0;
n != block_data.size();
n++)
357 setOfBlocksData[
id].params[
n] = block_data[
n];
365 const EntityHandle fe_ent,
const int nb_gauss_pts,
const int var_size,
369 auto mget_tag_data = [&](
Tag &m_tag, boost::shared_ptr<MatrixDouble> &m_mat,
370 const int &m_size,
bool is_def_grad =
false) {
375 rval = mField.get_moab().tag_get_by_ptr(
376 m_tag, &fe_ent, 1, (
const void **)&tag_data, &tag_size);
378 if (
rval != MB_SUCCESS || tag_size != m_size * nb_gauss_pts) {
379 m_mat->resize(nb_gauss_pts, m_size,
false);
383 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
388 void const *tag_data2[] = {&*m_mat->data().begin()};
389 const int tag_size2 = m_mat->data().size();
390 CHKERR mField.get_moab().tag_set_by_ptr(m_tag, &fe_ent, 1, tag_data2,
394 nb_gauss_pts, m_size,
395 ublas::shallow_array_adaptor<double>(tag_size, tag_data));
403 CHKERR mget_tag_data(internalVariableTag, internalVariablePtr, var_size);
404 CHKERR mget_tag_data(stressTag, mPrevStressPtr, stress_size);
405 CHKERR mget_tag_data(gradientTag, mPrevGradPtr, grad_size,
true);
411MFrontInterface::CommonData::setInternalVar(
const EntityHandle fe_ent) {
414 auto mset_tag_data = [&](
Tag &m_tag, boost::shared_ptr<MatrixDouble> &m_mat) {
416 void const *tag_data[] = {&*m_mat->data().begin()};
417 const int tag_size = m_mat->data().size();
418 CHKERR mField.get_moab().tag_set_by_ptr(m_tag, &fe_ent, 1, tag_data,
423 CHKERR mset_tag_data(internalVariableTag, internalVariablePtr);
424 CHKERR mset_tag_data(stressTag, mPrevStressPtr);
425 CHKERR mset_tag_data(gradientTag, mPrevGradPtr);
432 const int default_length = 0;
433 CHKERR mField.get_moab().tag_get_handle(
434 "_INTERNAL_VAR", default_length, MB_TYPE_DOUBLE, internalVariableTag,
435 MB_TAG_CREAT | MB_TAG_VARLEN | MB_TAG_SPARSE, PETSC_NULLPTR);
436 CHKERR mField.get_moab().tag_get_handle(
437 "_STRESS_TAG", default_length, MB_TYPE_DOUBLE, stressTag,
438 MB_TAG_CREAT | MB_TAG_VARLEN | MB_TAG_SPARSE, PETSC_NULLPTR);
439 CHKERR mField.get_moab().tag_get_handle(
440 "_GRAD_TAG", default_length, MB_TYPE_DOUBLE, gradientTag,
441 MB_TAG_CREAT | MB_TAG_VARLEN | MB_TAG_SPARSE, PETSC_NULLPTR);
449 for (
auto &[
id, data] : setOfBlocksData) {
450 CHKERR mField.get_moab().tag_clear_data(internalVariableTag, data.eNts,
452 CHKERR mField.get_moab().tag_clear_data(stressTag, data.eNts, &zero);
453 CHKERR mField.get_moab().tag_clear_data(gradientTag, data.eNts, &zero);
458template <ModelHypothesis MH, AssemblyType AT>
462 isFiniteKinematics =
false;
463 saveGauss = PETSC_FALSE;
464 saveDomain = PETSC_TRUE;
465 testJacobian = PETSC_FALSE;
466 randomFieldScale = 1.0;
467 optionsPrefix =
"mf_";
468 monitorPtr =
nullptr;
471 if (!LogManager::checkIfChannelExist(
"MFrontInterfaceWorld")) {
472 auto core_log = logging::core::get();
474 core_log->add_sink(LogManager::createSink(LogManager::getStrmWorld(),
475 "MFrontInterfaceWorld"));
476 core_log->add_sink(LogManager::createSink(LogManager::getStrmSync(),
477 "MFrontInterfaceSync"));
478 core_log->add_sink(LogManager::createSink(LogManager::getStrmSelf(),
479 "MFrontInterfaceSelf"));
481 LogManager::setLog(
"MFrontInterfaceWorld");
482 LogManager::setLog(
"MFrontInterfaceSync");
483 LogManager::setLog(
"MFrontInterfaceSelf");
490 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::noisy) <<
"MFront Interface created";
493template <ModelHypothesis MH, AssemblyType AT>
494MoFEMErrorCode MFrontInterfaceImpl<MH, AT>::getCommandLineParameters() {
497 PetscOptionsBegin(PETSC_COMM_WORLD, optionsPrefix.c_str(),
"",
"none");
499 CHKERR PetscOptionsBool(
"-save_gauss",
"save gauss pts (internal variables)",
500 "", saveGauss, &saveGauss, PETSC_NULLPTR);
501 CHKERR PetscOptionsBool(
"-save_domain",
"save results on a domain mesh",
"",
502 saveDomain, &saveDomain, PETSC_NULLPTR);
504 CHKERR PetscOptionsBool(
"-test_jacobian",
"test Jacobian (LHS matrix)",
"",
505 testJacobian, &testJacobian, PETSC_NULLPTR);
506 CHKERR PetscOptionsReal(
"-random_field_scale",
507 "scale for the finite difference jacobian",
"",
508 randomFieldScale, &randomFieldScale, PETSC_NULLPTR);
511 moabGaussIntPtr = boost::shared_ptr<moab::Interface>(
new moab::Core());
513 commonDataPtr = boost::make_shared<MFrontInterface::CommonData>(mField);
515 commonDataPtr->setBlocks(DIM);
516 commonDataPtr->createTags();
518 commonDataPtr->mGradPtr = boost::make_shared<MatrixDouble>();
519 commonDataPtr->mStressPtr = boost::make_shared<MatrixDouble>();
520 commonDataPtr->mFullStrainPtr = boost::make_shared<MatrixDouble>();
521 commonDataPtr->mFullStressPtr = boost::make_shared<MatrixDouble>();
522 commonDataPtr->mDispPtr = boost::make_shared<MatrixDouble>();
523 commonDataPtr->mPrevGradPtr = boost::make_shared<MatrixDouble>();
524 commonDataPtr->mPrevStressPtr = boost::make_shared<MatrixDouble>();
525 commonDataPtr->materialTangentPtr = boost::make_shared<MatrixDouble>();
526 commonDataPtr->mFullTangentPtr = boost::make_shared<MatrixDouble>();
527 commonDataPtr->internalVariablePtr = boost::make_shared<MatrixDouble>();
529 if (commonDataPtr->setOfBlocksData.empty() ||
530 commonDataPtr->blocksIDmap.empty()) {
532 "No blocksets on the mesh have been provided for MFront (e.g. "
536 auto check_lib_finite_strain = [&](
const std::string &lib,
537 const std::string &beh_name,
bool &flag) {
540 ifstream
f(lib.c_str());
542 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::error)
543 <<
"Problem with the behaviour path: " << lib;
545 auto &lm = mgis::LibrariesManager::get();
546 flag =
bool(lm.getBehaviourType(lib, beh_name) == 2) &&
547 (lm.getBehaviourKinematic(lib, beh_name) == 3);
551 auto op = FiniteStrainBehaviourOptions{};
552 op.stress_measure = FiniteStrainBehaviourOptions::PK1;
553 op.tangent_operator = FiniteStrainBehaviourOptions::DPK1_DF;
555 for (
auto &block : commonDataPtr->setOfBlocksData) {
556 const int &
id = block.first;
557 auto &lib_path = block.second.behaviourPath;
558 auto &name = block.second.behaviourName;
559 const string param_name =
"-block_" + to_string(
id);
560 const string param_path =
"-lib_path_" + to_string(
id);
561 const string param_from_blocks =
"-params_" + to_string(
id);
562 PetscBool set_from_blocks = PETSC_FALSE;
566 CHKERR PetscOptionsBool(param_from_blocks.c_str(),
567 "set parameters from blocks",
"", set_from_blocks,
568 &set_from_blocks, PETSC_NULLPTR);
570 CHKERR PetscOptionsString(param_name.c_str(),
"name of the behaviour",
"",
571 "LinearElasticity", char_name, 255, &is_param);
573 name = string(char_name);
574 string default_lib_path =
575 "src/libBehaviour." + string(DEFAULT_LIB_EXTENSION);
576 CHKERR PetscOptionsString(
577 param_path.c_str(),
"path to the behaviour library",
"",
578 default_lib_path.c_str(), char_name, 255, &is_param);
580 lib_path = string(char_name);
581 auto &mgis_bv_ptr = block.second.mGisBehaviour;
582 bool is_finite_strain =
false;
584 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform)
585 <<
"Loading behaviour from " << lib_path;
587 CHKERR check_lib_finite_strain(lib_path, name, is_finite_strain);
589 mgis::behaviour::Hypothesis
h;
592 h = mgis::behaviour::Hypothesis::TRIDIMENSIONAL;
593 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform)
594 <<
"Model hypothesis: TRIDIMENSIONAL";
597 h = mgis::behaviour::Hypothesis::PLANESTRAIN;
598 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform)
599 <<
"Model hypothesis: PLANESTRAIN";
602 h = mgis::behaviour::Hypothesis::AXISYMMETRICAL;
603 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform)
604 <<
"Model hypothesis: AXISYMMETRICAL";
610 if (is_finite_strain) {
611 mgis_bv_ptr = boost::make_shared<Behaviour>(load(op, lib_path, name,
h));
612 block.second.isFiniteStrain =
true;
614 mgis_bv_ptr = boost::make_shared<Behaviour>(load(lib_path, name,
h));
616 CHKERR block.second.setBlockBehaviourData(set_from_blocks);
617 for (
size_t dd = 0;
dd < mgis_bv_ptr->mps.size(); ++
dd) {
619 PetscBool is_set = PETSC_FALSE;
620 string param_cmd =
"-param_" + to_string(
id) +
"_" + to_string(dd);
621 CHKERR PetscOptionsScalar(param_cmd.c_str(),
"parameter from cmd",
"",
622 my_param, &my_param, &is_set);
625 setMaterialProperty(block.second.behDataPtr->s0, dd, my_param);
626 setMaterialProperty(block.second.behDataPtr->s1, dd, my_param);
629 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform)
630 << mgis_bv_ptr->behaviour <<
" behaviour loaded on block "
633 if (is_finite_strain)
634 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform)
635 <<
"Finite Strain Kinematics";
637 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform)
638 <<
"Small Strain Kinematics";
640 if (mgis_bv_ptr->isvs.size()) {
641 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform) <<
"Internal variables:";
642 for (
const auto &is : mgis_bv_ptr->isvs) {
643 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform) <<
": " << is.name;
647 if (mgis_bv_ptr->esvs.size()) {
648 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform) <<
"External variables:";
649 for (
const auto &es : mgis_bv_ptr->esvs) {
650 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform) <<
": " << es.name;
654 auto it = block.second.behDataPtr->s0.material_properties.begin();
657 if (mgis_bv_ptr->mps.size()) {
658 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform) <<
"Material properties:";
659 for (
const auto &mp : mgis_bv_ptr->mps) {
660 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform)
661 << nb++ <<
" : " << mp.name <<
" = " << *it++;
665 if (mgis_bv_ptr->params.size()) {
666 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform) <<
"Real parameters:";
667 for (
const auto &p : mgis_bv_ptr->params) {
668 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform) << nb++ <<
" : " << p;
672 if (mgis_bv_ptr->iparams.size()) {
673 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform) <<
"Integer parameters:";
674 for (
const auto &p : mgis_bv_ptr->iparams) {
675 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform) << nb++ <<
" : " << p;
679 if (mgis_bv_ptr->usparams.size()) {
680 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform)
681 <<
"Unsigned short parameters:";
682 for (
const auto &p : mgis_bv_ptr->usparams) {
683 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::inform) << nb++ <<
" : " << p;
690 auto check_behaviours_kinematics = [&](
bool &is_finite_kin) {
693 commonDataPtr->setOfBlocksData.begin()->second.isFiniteStrain;
694 for (
auto &block : commonDataPtr->setOfBlocksData) {
695 if (block.second.isFiniteStrain != is_finite_kin)
697 "All used MFront behaviours have to be of same kinematics "
704 CHKERR check_behaviours_kinematics(isFiniteKinematics);
706 auto get_base = [&]() {
708 CHKERR mField.get_moab().get_entities_by_dimension(0, DIM, domain_ents,
710 if (domain_ents.empty())
728 fieldBase = get_base();
729 MOFEM_LOG(
"MFrontInterfaceWorld", Sev::verbose)
730 <<
"MFront post process projection base: "
753 ((DIM * (DIM + 1)) / 2) * ((DIM * (DIM + 1)) / 2)>,
756template <
typename T>
inline size_t get_paraview_size(T &vsize) {
757 return vsize > 1 ? (vsize > 3 ? 9 : 3) : 1;
761template <
typename T1,
typename T2>
770 if (std::is_same<T2, Tensor4Pack<3>>::value) {
771 D(N0, N0, N0, N0) =
K[0];
772 D(N0, N0, N1, N1) =
K[1];
773 D(N0, N0, N2, N2) =
K[2];
774 D(N0, N0, N0, N1) =
K[3];
775 D(N0, N0, N1, N0) =
K[4];
776 D(N0, N0, N0, N2) =
K[5];
777 D(N0, N0, N2, N0) =
K[6];
778 D(N0, N0, N1, N2) =
K[7];
779 D(N0, N0, N2, N1) =
K[8];
780 D(N1, N1, N0, N0) =
K[9];
781 D(N1, N1, N1, N1) =
K[10];
782 D(N1, N1, N2, N2) =
K[11];
783 D(N1, N1, N0, N1) =
K[12];
784 D(N1, N1, N1, N0) =
K[13];
785 D(N1, N1, N0, N2) =
K[14];
786 D(N1, N1, N2, N0) =
K[15];
787 D(N1, N1, N1, N2) =
K[16];
788 D(N1, N1, N2, N1) =
K[17];
789 D(N2, N2, N0, N0) =
K[18];
790 D(N2, N2, N1, N1) =
K[19];
791 D(N2, N2, N2, N2) =
K[20];
792 D(N2, N2, N0, N1) =
K[21];
793 D(N2, N2, N1, N0) =
K[22];
794 D(N2, N2, N0, N2) =
K[23];
795 D(N2, N2, N2, N0) =
K[24];
796 D(N2, N2, N1, N2) =
K[25];
797 D(N2, N2, N2, N1) =
K[26];
798 D(N0, N1, N0, N0) =
K[27];
799 D(N0, N1, N1, N1) =
K[28];
800 D(N0, N1, N2, N2) =
K[29];
801 D(N0, N1, N0, N1) =
K[30];
802 D(N0, N1, N1, N0) =
K[31];
803 D(N0, N1, N0, N2) =
K[32];
804 D(N0, N1, N2, N0) =
K[33];
805 D(N0, N1, N1, N2) =
K[34];
806 D(N0, N1, N2, N1) =
K[35];
807 D(N1, N0, N0, N0) =
K[36];
808 D(N1, N0, N1, N1) =
K[37];
809 D(N1, N0, N2, N2) =
K[38];
810 D(N1, N0, N0, N1) =
K[39];
811 D(N1, N0, N1, N0) =
K[40];
812 D(N1, N0, N0, N2) =
K[41];
813 D(N1, N0, N2, N0) =
K[42];
814 D(N1, N0, N1, N2) =
K[43];
815 D(N1, N0, N2, N1) =
K[44];
816 D(N0, N2, N0, N0) =
K[45];
817 D(N0, N2, N1, N1) =
K[46];
818 D(N0, N2, N2, N2) =
K[47];
819 D(N0, N2, N0, N1) =
K[48];
820 D(N0, N2, N1, N0) =
K[49];
821 D(N0, N2, N0, N2) =
K[50];
822 D(N0, N2, N2, N0) =
K[51];
823 D(N0, N2, N1, N2) =
K[52];
824 D(N0, N2, N2, N1) =
K[53];
825 D(N2, N0, N0, N0) =
K[54];
826 D(N2, N0, N1, N1) =
K[55];
827 D(N2, N0, N2, N2) =
K[56];
828 D(N2, N0, N0, N1) =
K[57];
829 D(N2, N0, N1, N0) =
K[58];
830 D(N2, N0, N0, N2) =
K[59];
831 D(N2, N0, N2, N0) =
K[60];
832 D(N2, N0, N1, N2) =
K[61];
833 D(N2, N0, N2, N1) =
K[62];
834 D(N1, N2, N0, N0) =
K[63];
835 D(N1, N2, N1, N1) =
K[64];
836 D(N1, N2, N2, N2) =
K[65];
837 D(N1, N2, N0, N1) =
K[66];
838 D(N1, N2, N1, N0) =
K[67];
839 D(N1, N2, N0, N2) =
K[68];
840 D(N1, N2, N2, N0) =
K[69];
841 D(N1, N2, N1, N2) =
K[70];
842 D(N1, N2, N2, N1) =
K[71];
843 D(N2, N1, N0, N0) =
K[72];
844 D(N2, N1, N1, N1) =
K[73];
845 D(N2, N1, N2, N2) =
K[74];
846 D(N2, N1, N0, N1) =
K[75];
847 D(N2, N1, N1, N0) =
K[76];
848 D(N2, N1, N0, N2) =
K[77];
849 D(N2, N1, N2, N0) =
K[78];
850 D(N2, N1, N1, N2) =
K[79];
851 D(N2, N1, N2, N1) =
K[80];
855 if (std::is_same<T2, Tensor4Pack<2>>::value) {
856 D(N0, N0, N0, N0) =
K[0];
857 D(N0, N0, N1, N1) =
K[1];
859 D(N0, N0, N0, N1) =
K[3];
860 D(N0, N0, N1, N0) =
K[4];
861 D(N1, N1, N0, N0) =
K[5];
862 D(N1, N1, N1, N1) =
K[6];
864 D(N1, N1, N0, N1) =
K[8];
865 D(N1, N1, N1, N0) =
K[9];
867 D(N0, N1, N0, N0) =
K[15];
868 D(N0, N1, N1, N1) =
K[16];
870 D(N0, N1, N0, N1) =
K[18];
871 D(N0, N1, N1, N0) =
K[19];
872 D(N1, N0, N0, N0) =
K[20];
873 D(N1, N0, N1, N1) =
K[21];
875 D(N1, N0, N0, N1) =
K[23];
876 D(N1, N0, N1, N0) =
K[24];
880 if (std::is_same<T2, DdgPack<3>>::value) {
881 D(N0, N0, N0, N0) =
K[0];
882 D(N0, N0, N1, N1) =
K[1];
883 D(N0, N0, N2, N2) =
K[2];
885 D(N0, N0, N0, N1) = inv_sqr2 *
K[3];
886 D(N0, N0, N0, N2) = inv_sqr2 *
K[4];
887 D(N0, N0, N1, N2) = inv_sqr2 *
K[5];
889 D(N1, N1, N0, N0) =
K[6];
890 D(N1, N1, N1, N1) =
K[7];
891 D(N1, N1, N2, N2) =
K[8];
893 D(N1, N1, N0, N1) = inv_sqr2 *
K[9];
894 D(N1, N1, N0, N2) = inv_sqr2 *
K[10];
895 D(N1, N1, N1, N2) = inv_sqr2 *
K[11];
897 D(N2, N2, N0, N0) =
K[12];
898 D(N2, N2, N1, N1) =
K[13];
899 D(N2, N2, N2, N2) =
K[14];
901 D(N2, N2, N0, N1) = inv_sqr2 *
K[15];
902 D(N2, N2, N0, N2) = inv_sqr2 *
K[16];
903 D(N2, N2, N1, N2) = inv_sqr2 *
K[17];
905 D(N0, N1, N0, N0) = inv_sqr2 *
K[18];
906 D(N0, N1, N1, N1) = inv_sqr2 *
K[19];
907 D(N0, N1, N2, N2) = inv_sqr2 *
K[20];
909 D(N0, N1, N0, N1) = 0.5 *
K[21];
910 D(N0, N1, N0, N2) = 0.5 *
K[22];
911 D(N0, N1, N1, N2) = 0.5 *
K[23];
913 D(N0, N2, N0, N0) = inv_sqr2 *
K[24];
914 D(N0, N2, N1, N1) = inv_sqr2 *
K[25];
915 D(N0, N2, N2, N2) = inv_sqr2 *
K[26];
917 D(N0, N2, N0, N1) = 0.5 *
K[27];
918 D(N0, N2, N0, N2) = 0.5 *
K[28];
919 D(N0, N2, N1, N2) = 0.5 *
K[29];
921 D(N1, N2, N0, N0) = inv_sqr2 *
K[30];
922 D(N1, N2, N1, N1) = inv_sqr2 *
K[31];
923 D(N1, N2, N2, N2) = inv_sqr2 *
K[32];
925 D(N1, N2, N0, N1) = 0.5 *
K[33];
926 D(N1, N2, N0, N2) = 0.5 *
K[34];
927 D(N1, N2, N1, N2) = 0.5 *
K[35];
931 if (std::is_same<T2, DdgPack<2>>::value) {
933 D(N0, N0, N0, N0) =
K[0];
934 D(N0, N0, N1, N1) =
K[1];
937 D(N0, N0, N0, N1) = inv_sqr2 *
K[3];
939 D(N1, N1, N0, N0) =
K[4];
940 D(N1, N1, N1, N1) =
K[5];
943 D(N1, N1, N0, N1) = inv_sqr2 *
K[7];
947 D(N0, N1, N0, N0) = inv_sqr2 *
K[12];
948 D(N0, N1, N1, N1) = inv_sqr2 *
K[13];
952 D(N0, N1, N0, N1) = 0.5 *
K[15];
958template <
bool IS_LARGE_STRAIN,
typename T1,
typename T2>
967 if constexpr (IS_LARGE_STRAIN) {
968 D(N0, N0, N0, N0) =
K[0];
969 D(N0, N0, N1, N1) =
K[1];
970 D(N0, N0, N2, N2) =
K[2];
971 D(N0, N0, N0, N1) =
K[3];
972 D(N0, N0, N1, N0) =
K[4];
973 D(N1, N1, N0, N0) =
K[5];
974 D(N1, N1, N1, N1) =
K[6];
975 D(N1, N1, N2, N2) =
K[7];
976 D(N1, N1, N0, N1) =
K[8];
977 D(N1, N1, N1, N0) =
K[9];
978 D(N2, N2, N0, N0) =
K[10];
979 D(N2, N2, N1, N1) =
K[11];
980 D(N2, N2, N2, N2) =
K[12];
981 D(N2, N2, N0, N1) =
K[13];
982 D(N2, N2, N1, N0) =
K[14];
983 D(N0, N1, N0, N0) =
K[15];
984 D(N0, N1, N1, N1) =
K[16];
985 D(N0, N1, N2, N2) =
K[17];
986 D(N0, N1, N0, N1) =
K[18];
987 D(N0, N1, N1, N0) =
K[19];
988 D(N1, N0, N0, N0) =
K[20];
989 D(N1, N0, N1, N1) =
K[21];
990 D(N1, N0, N2, N2) =
K[22];
991 D(N1, N0, N0, N1) =
K[23];
992 D(N1, N0, N1, N0) =
K[24];
995 D(N0, N0, N0, N0) =
K[0];
996 D(N0, N0, N1, N1) =
K[1];
997 D(N0, N0, N2, N2) =
K[2];
999 D(N0, N0, N0, N1) = inv_sqr2 *
K[3];
1001 D(N1, N1, N0, N0) =
K[4];
1002 D(N1, N1, N1, N1) =
K[5];
1003 D(N1, N1, N2, N2) =
K[6];
1005 D(N1, N1, N0, N1) = inv_sqr2 *
K[7];
1007 D(N2, N2, N0, N0) =
K[8];
1008 D(N2, N2, N1, N1) =
K[9];
1009 D(N2, N2, N2, N2) =
K[10];
1011 D(N2, N2, N0, N1) = inv_sqr2 *
K[11];
1012 D(N2, N2, N1, N0) =
D(N2, N2, N0, N1);
1014 D(N0, N1, N0, N0) = inv_sqr2 *
K[12];
1015 D(N0, N1, N1, N1) = inv_sqr2 *
K[13];
1017 D(N0, N1, N2, N2) = inv_sqr2 *
K[14];
1018 D(N1, N0, N2, N2) =
D(N0, N1, N2, N2);
1020 D(N0, N1, N0, N1) = 0.5 *
K[15];
1026template <
typename T> T get_tangent_tensor(MatrixDouble &mat);
1029Tensor4Pack<3> get_tangent_tensor<Tensor4Pack<3>>(
MatrixDouble &mat) {
1030 return getFTensor4FromMat<3, 3, 3, 3>(mat);
1034Tensor4Pack<2> get_tangent_tensor<Tensor4Pack<2>>(
MatrixDouble &mat) {
1035 return getFTensor4FromMat<2, 2, 2, 2>(mat);
1038template <> DdgPack<3> get_tangent_tensor<DdgPack<3>>(
MatrixDouble &mat) {
1039 return getFTensor4DdgFromMat<3, 3>(mat);
1042template <> DdgPack<2> get_tangent_tensor<DdgPack<2>>(
MatrixDouble &mat) {
1043 return getFTensor4DdgFromMat<2, 2>(mat);
1046template <
bool IS_LARGE_STRAIN, ModelHypothesis MH>
1048mgis_integration(
size_t gg, Tensor2Pack<MFrontEleType<MH>::SPACE_DIM> &t_grad,
1049 Tensor1Pack<MFrontEleType<MH>::SPACE_DIM> &t_disp,
1050 Tensor1PackCoords &t_coords,
1051 MFrontInterface::CommonData &common_data,
1052 MFrontInterface::CommonData::BlockData &block_data) {
1055 static constexpr int DIM = MFrontEleType<MH>::SPACE_DIM;
1057 int check_integration;
1058 MatrixDouble &mat_int = *common_data.internalVariablePtr;
1060 MatrixDouble &mat_stress0 = *common_data.mPrevStressPtr;
1062 int &size_of_vars = block_data.sizeIntVar;
1063 int &size_of_grad = block_data.sizeGradVar;
1064 int &size_of_stress = block_data.sizeStressVar;
1066 auto &mgis_bv = *block_data.mGisBehaviour;
1071 if constexpr (IS_LARGE_STRAIN) {
1075 setGradient(block_data.behDataPtr->s1, 0, size_of_grad,
1078 setGradient(block_data.behDataPtr->s1, 0, size_of_grad,
1079 &*getVoigtVec<DIM>(t_strain).data());
1083 t_strain(
i,
j) = (t_grad(
i,
j) || t_grad(
j,
i)) / 2;
1086 block_data.behDataPtr->s1, 0, size_of_grad,
1089 setGradient(block_data.behDataPtr->s1, 0, size_of_grad,
1090 &*getVoigtVecSymm<DIM>(t_strain).data());
1096 setGradient(block_data.behDataPtr->s0, 0, size_of_grad, &*grad0_vec.begin());
1098 auto stress0_vec =
getVectorAdaptor(&mat_stress0.data()[gg * size_of_stress],
1100 setThermodynamicForce(block_data.behDataPtr->s0, 0, size_of_stress,
1101 &*stress0_vec.begin());
1106 setInternalStateVariable(block_data.behDataPtr->s0, 0, size_of_vars,
1107 &*internal_var.begin());
1110 check_integration = mgis::behaviour::integrate(block_data.bView, mgis_bv);
1111 switch (check_integration) {
1113 MOFEM_LOG(
"WORLD", Sev::error) <<
"Mfront integration failed";
1117 <<
"Mfront integration succeeded but results are unreliable";
1127template <
bool UPDATE,
bool IS_LARGE_STRAIN, ModelHypothesis MH>
1129 static constexpr int DIM = MFrontEleType<MH>::SPACE_DIM;
1130 using DomainEleOp =
typename MFrontEleType<MH>::DomainEleOp;
1133 boost::shared_ptr<MFrontInterface::CommonData> common_data_ptr,
1134 boost::shared_ptr<FEMethod> monitor_ptr)
1136 commonDataPtr(common_data_ptr), monitorPtr(monitor_ptr) {
1137 std::fill(&DomainEleOp::doEntities[MBEDGE],
1138 &DomainEleOp::doEntities[MBMAXTYPE],
false);
1143 boost::shared_ptr<MFrontInterface::CommonData> commonDataPtr;
1144 boost::shared_ptr<FEMethod> monitorPtr;
1147template <ModelHypothesis MH>
1148using OpUpdateVariablesFiniteStrains = OpStressTmp<true, true, MH>;
1150template <ModelHypothesis MH>
1151using OpUpdateVariablesSmallStrains = OpStressTmp<true, false, MH>;
1153template <ModelHypothesis MH>
1154using OpStressFiniteStrains = OpStressTmp<false, true, MH>;
1156template <ModelHypothesis MH>
1157using OpStressSmallStrains = OpStressTmp<false, false, MH>;
1159template <
bool UPDATE,
bool IS_LARGE_STRAIN, ModelHypothesis MH>
1160MoFEMErrorCode OpStressTmp<UPDATE, IS_LARGE_STRAIN, MH>::doWork(
int side,
1171 const size_t nb_gauss_pts = DomainEleOp::getGaussPts().size2();
1172 auto fe_ent = DomainEleOp::getNumeredEntFiniteElementPtr()->getEnt();
1173 auto id = commonDataPtr->blocksIDmap.at(fe_ent);
1174 auto &dAta = commonDataPtr->setOfBlocksData.at(
id);
1176 if (monitorPtr ==
nullptr)
1178 "Time Monitor (FEMethod) has not been set for MFrontInterfaceImpl. "
1179 "Make sure to call setMonitor before calling "
1180 "opFactoryDomainRhs and opFactoryDomainLhs");
1182 dAta.setTag(DataTags::RHS);
1183 dAta.behDataPtr->dt = monitorPtr->ts_dt;
1184 dAta.bView.dt = monitorPtr->ts_dt;
1186 CHKERR commonDataPtr->getInternalVar(fe_ent, nb_gauss_pts, dAta.sizeIntVar,
1187 dAta.sizeGradVar, dAta.sizeStressVar,
1190 MatrixDouble &mat_int = *commonDataPtr->internalVariablePtr;
1191 MatrixDouble &mat_grad0 = *commonDataPtr->mPrevGradPtr;
1192 MatrixDouble &mat_stress0 = *commonDataPtr->mPrevStressPtr;
1194 auto t_grad = getFTensor2FromMat<DIM, DIM>(*(commonDataPtr->mGradPtr));
1195 auto t_disp = getFTensor1FromMat<DIM>(*(commonDataPtr->mDispPtr));
1196 auto t_coords = DomainEleOp::getFTensor1CoordsAtGaussPts();
1198 commonDataPtr->mStressPtr->resize(nb_gauss_pts, DIM * DIM);
1199 commonDataPtr->mStressPtr->clear();
1200 auto t_stress = getFTensor2FromMat<DIM, DIM>(*(commonDataPtr->mStressPtr));
1202 commonDataPtr->mFullStressPtr->resize(nb_gauss_pts, 3 * 3);
1203 commonDataPtr->mFullStressPtr->clear();
1204 auto t_full_stress =
1205 getFTensor2FromMat<3, 3>(*(commonDataPtr->mFullStressPtr));
1207 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1209 CHKERR mgis_integration<IS_LARGE_STRAIN, MH>(gg, t_grad, t_disp, t_coords,
1210 *commonDataPtr, dAta);
1212 if constexpr (DIM == 3) {
1214 if constexpr (IS_LARGE_STRAIN) {
1216 VOIGT_VEC_3D(getThermodynamicForce(dAta.behDataPtr->s1, 0)));
1219 VOIGT_VEC_SYMM_3D(getThermodynamicForce(dAta.behDataPtr->s1, 0))));
1221 t_stress(
i,
j) = t_force(
i,
j);
1222 }
else if constexpr (DIM == 2) {
1225 if constexpr (IS_LARGE_STRAIN) {
1227 VOIGT_VEC_2D(getThermodynamicForce(dAta.behDataPtr->s1, 0)));
1229 VOIGT_VEC_2D_FULL(getThermodynamicForce(dAta.behDataPtr->s1, 0)));
1232 VOIGT_VEC_SYMM_2D(getThermodynamicForce(dAta.behDataPtr->s1, 0))));
1235 getThermodynamicForce(dAta.behDataPtr->s1, 0))));
1237 t_stress(
I,
J) = t_force(
I,
J);
1238 t_full_stress(
i,
j) = t_full_force(
i,
j);
1241 if constexpr (UPDATE) {
1242 for (
int dd = 0;
dd != dAta.sizeIntVar; ++
dd) {
1243 mat_int(gg, dd) = *getInternalStateVariable(dAta.behDataPtr->s1, dd);
1245 for (
int dd = 0;
dd != dAta.sizeGradVar; ++
dd) {
1246 mat_grad0(gg, dd) = *getGradient(dAta.behDataPtr->s1, dd);
1248 for (
int dd = 0;
dd != dAta.sizeStressVar; ++
dd) {
1249 mat_stress0(gg, dd) = *getThermodynamicForce(dAta.behDataPtr->s1, dd);
1260 if constexpr (UPDATE) {
1261 CHKERR commonDataPtr->setInternalVar(fe_ent);
1267template <
typename T, ModelHypothesis MH>
1269 static constexpr int DIM = MFrontEleType<MH>::SPACE_DIM;
1270 using DomainEleOp =
typename MFrontEleType<MH>::DomainEleOp;
1273 boost::shared_ptr<MFrontInterface::CommonData> common_data_ptr,
1274 boost::shared_ptr<FEMethod> monitor_ptr)
1276 commonDataPtr(common_data_ptr), monitorPtr(monitor_ptr) {
1277 std::fill(&DomainEleOp::doEntities[MBEDGE],
1278 &DomainEleOp::doEntities[MBMAXTYPE],
false);
1283 boost::shared_ptr<MFrontInterface::CommonData> commonDataPtr;
1284 boost::shared_ptr<FEMethod> monitorPtr;
1287template <ModelHypothesis MH>
1288using OpTangentFiniteStrains =
1289 struct OpTangent<Tensor4Pack<MFrontEleType<MH>::
SPACE_DIM>, MH>;
1291template <ModelHypothesis MH>
1292using OpTangentSmallStrains =
1293 struct OpTangent<DdgPack<MFrontEleType<MH>::SPACE_DIM>, MH>;
1295template <typename T, ModelHypothesis MH>
1296MoFEMErrorCode OpTangent<T, MH>::doWork(int side, EntityType type,
1300 const size_t nb_gauss_pts = DomainEleOp::getGaussPts().size2();
1301 auto fe_ent = DomainEleOp::getNumeredEntFiniteElementPtr()->getEnt();
1302 auto id = commonDataPtr->blocksIDmap.at(fe_ent);
1303 auto &dAta = commonDataPtr->setOfBlocksData.at(
id);
1305 if (monitorPtr ==
nullptr)
1307 "Time Monitor (FEMethod) has not been set for MFrontInterfaceImpl. "
1308 "Make sure to call setMonitor(monitor_ptr) before calling "
1311 dAta.setTag(DataTags::LHS);
1312 dAta.behDataPtr->dt = monitorPtr->ts_dt;
1313 dAta.bView.dt = monitorPtr->ts_dt;
1315 constexpr bool IS_LARGE_STRAIN = std::is_same<T, Tensor4Pack<3>>::value ||
1316 std::is_same<T, Tensor4Pack<2>>::value;
1318 CHKERR commonDataPtr->getInternalVar(fe_ent, nb_gauss_pts, dAta.sizeIntVar,
1319 dAta.sizeGradVar, dAta.sizeStressVar,
1322 MatrixDouble &S_E = *(commonDataPtr->materialTangentPtr);
1325 size_t tens_size = 36;
1327 if constexpr (DIM == 2) {
1329 if constexpr (IS_LARGE_STRAIN)
1334 if constexpr (IS_LARGE_STRAIN)
1338 S_E.resize(nb_gauss_pts, tens_size,
false);
1339 auto D1 = get_tangent_tensor<T>(S_E);
1341 size_t full_tens_size = 81;
1342 F_E.resize(nb_gauss_pts, full_tens_size,
false);
1345 auto D2 = get_tangent_tensor<Tensor4Pack<3>>(F_E);
1347 auto t_grad = getFTensor2FromMat<DIM, DIM>(*(commonDataPtr->mGradPtr));
1348 auto t_disp = getFTensor1FromMat<DIM>(*(commonDataPtr->mDispPtr));
1349 auto t_coords = DomainEleOp::getFTensor1CoordsAtGaussPts();
1351 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1353 CHKERR mgis_integration<IS_LARGE_STRAIN, MH>(gg, t_grad, t_disp, t_coords,
1354 *commonDataPtr, dAta);
1356 CHKERR get_tensor4_from_voigt(&*dAta.behDataPtr->K.begin(), D1);
1357 CHKERR get_full_tensor4_from_voigt<IS_LARGE_STRAIN>(
1358 &*dAta.behDataPtr->K.begin(), D2);
1370template <AssemblyType AT>
1371struct OpAxisymmetricRhs
1372 :
public FormsIntegrators<
1373 MFrontEleType<AXISYMMETRICAL>::DomainEleOp>::Assembly<AT>
::OpBase {
1374 using DomainEleOp =
typename MFrontEleType<AXISYMMETRICAL>::DomainEleOp;
1375 using OpBase =
typename FormsIntegrators<DomainEleOp>::Assembly<
AT>
::OpBase;
1379 boost::shared_ptr<MFrontInterface::CommonData> common_data_ptr)
1381 commonDataPtr(common_data_ptr) {};
1384 boost::shared_ptr<MFrontInterface::CommonData> commonDataPtr;
1389template <AssemblyType AT>
1394 const double vol = OpBase::getMeasure();
1396 auto t_w = OpBase::getFTensor0IntegrationWeight();
1399 auto t_full_stress =
1400 getFTensor2FromMat<3, 3>(*(commonDataPtr->mFullStressPtr));
1405 auto t_nf = OpBase::template getNf<2>();
1410 const double alpha = t_w * vol * 2. * M_PI;
1414 t_nf(0) += alpha * t_full_stress(2, 2) * t_base;
1427template <AssemblyType AT>
1428struct OpAxisymmetricLhs
1429 :
public FormsIntegrators<
1430 MFrontEleType<AXISYMMETRICAL>::DomainEleOp>::Assembly<AT>
::OpBase {
1431 using DomainEleOp =
typename MFrontEleType<AXISYMMETRICAL>::DomainEleOp;
1432 using OpBase =
typename FormsIntegrators<DomainEleOp>::Assembly<
AT>
::OpBase;
1436 boost::shared_ptr<MFrontInterface::CommonData> common_data_ptr)
1438 commonDataPtr(common_data_ptr) {};
1441 boost::shared_ptr<MFrontInterface::CommonData> commonDataPtr;
1446template <AssemblyType AT>
1452 const double vol = OpBase::getMeasure();
1454 auto t_w = OpBase::getFTensor0IntegrationWeight();
1460 auto t_coords = OpBase::getFTensor1CoordsAtGaussPts();
1466 auto t_D = getFTensor4FromMat<3, 3, 3, 3>(*(commonDataPtr->mFullTangentPtr));
1472 const double r_cylinder = t_coords(0);
1475 const double alpha = t_w * vol * 2. * M_PI;
1482 auto t_m = OpBase::template getLocMat<2>(2 * rr);
1493 alpha * t_D(N0, N0, N2, N2) * t_col_base * t_row_diff_base(0);
1496 alpha * t_D(N1, N1, N2, N2) * t_col_base * t_row_diff_base(1);
1499 alpha * t_D(N2, N2, N0, N0) * t_col_diff_base(0) * t_row_base;
1502 alpha * t_D(N2, N2, N1, N1) * t_col_diff_base(1) * t_row_base;
1504 t_m(0, 0) += alpha * (t_D(N2, N2, N2, N2) / r_cylinder) * t_col_base *
1508 alpha * t_D(N2, N2, N0, N1) * t_col_diff_base(1) * t_row_base;
1511 alpha * t_D(N2, N2, N1, N0) * t_col_diff_base(0) * t_row_base;
1514 alpha * t_D(N0, N1, N2, N2) * t_col_base * t_row_diff_base(1);
1517 alpha * t_D(N1, N0, N2, N2) * t_col_base * t_row_diff_base(0);
1541template <ModelHypothesis MH, AssemblyType AT>
1543 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
1547 auto jacobian = [&](
const double r,
const double,
const double) {
1548 if (MH == AXISYMMETRICAL)
1549 return 2. * M_PI *
r;
1554 auto add_domain_ops_rhs = [&](
auto &pipeline) {
1555 if (isFiniteKinematics)
1557 new OpStressFiniteStrains<MH>(
field_name, commonDataPtr, monitorPtr));
1560 new OpStressSmallStrains<MH>(
field_name, commonDataPtr, monitorPtr));
1563 new OpInternalForce(
field_name, commonDataPtr->mStressPtr, jacobian));
1565 if (MH == AXISYMMETRICAL)
1566 pipeline.push_back(
new OpAxisymmetricRhs<AT>(
field_name, commonDataPtr));
1569 auto add_domain_base_ops = [&](
auto &pipeline) {
1570 pipeline.push_back(
new OpCalculateVectorFieldValues<DIM>(
1572 pipeline.push_back(
new OpCalculateVectorFieldGradient<DIM, DIM>(
1576 add_domain_base_ops(pip);
1577 add_domain_ops_rhs(pip);
1582template <ModelHypothesis MH, AssemblyType AT>
1584 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
1588 auto jacobian = [&](
const double r,
const double,
const double) {
1589 if (MH == AXISYMMETRICAL)
1590 return 2. * M_PI *
r;
1595 auto add_domain_ops_lhs = [&](
auto &pipeline) {
1596 if (isFiniteKinematics) {
1597 pipeline.push_back(
new OpTangentFiniteStrains<MH>(
1599 pipeline.push_back(
new OpAssembleLhsFiniteStrains(
1603 new OpTangentSmallStrains<MH>(
field_name, commonDataPtr, monitorPtr));
1604 pipeline.push_back(
new OpAssembleLhsSmallStrains(
1608 if (MH == AXISYMMETRICAL)
1609 pipeline.push_back(
new OpAxisymmetricLhs<AT>(
field_name, commonDataPtr));
1612 auto add_domain_base_ops = [&](
auto &pipeline) {
1613 pipeline.push_back(
new OpCalculateVectorFieldValues<DIM>(
1615 pipeline.push_back(
new OpCalculateVectorFieldGradient<DIM, DIM>(
1619 add_domain_base_ops(pip);
1620 add_domain_ops_lhs(pip);
1625template <ModelHypothesis MH>
1626struct OpSaveGaussPts :
public MFrontEleType<MH>
::DomainEleOp {
1627 static constexpr int DIM = MFrontEleType<MH>::SPACE_DIM;
1628 using DomainEleOp =
typename MFrontEleType<MH>::DomainEleOp;
1630 OpSaveGaussPts(
const std::string
field_name, moab::Interface &moab_mesh,
1631 boost::shared_ptr<MFrontInterface::CommonData> common_data_ptr)
1633 commonDataPtr(common_data_ptr), fieldName(
field_name) {
1634 std::fill(&DomainEleOp::doEntities[MBEDGE],
1635 &DomainEleOp::doEntities[MBMAXTYPE],
false);
1641 auto fe_ent = DomainEleOp::getNumeredEntFiniteElementPtr()->getEnt();
1642 auto id = commonDataPtr->blocksIDmap.at(fe_ent);
1643 auto &dAta = commonDataPtr->setOfBlocksData.at(
id);
1644 auto &mgis_bv = *dAta.mGisBehaviour;
1646 int &size_of_vars = dAta.sizeIntVar;
1647 int &size_of_grad = dAta.sizeGradVar;
1648 int &size_of_stress = dAta.sizeStressVar;
1650 auto get_tag = [&](std::string name,
size_t size) {
1651 std::array<double, 9> def;
1652 std::fill(def.begin(), def.end(), 0);
1654 CHKERR internalVarMesh.tag_get_handle(name.c_str(), size, MB_TYPE_DOUBLE,
1655 th, MB_TAG_CREAT | MB_TAG_SPARSE,
1660 auto t_stress = getFTensor2FromMat<3, 3>(*(commonDataPtr->mStressPtr));
1664 auto th_disp = get_tag(fieldName, 3);
1665 auto th_stress = get_tag(mgis_bv.thermodynamic_forces[0].name, 9);
1666 auto th_grad = get_tag(mgis_bv.gradients[0].name, 9);
1668 size_t nb_gauss_pts = DomainEleOp::getGaussPts().size2();
1669 auto t_grad = getFTensor2FromMat<3, 3>(*(commonDataPtr->mGradPtr));
1670 auto t_disp = getFTensor1FromMat<3>(*(commonDataPtr->mDispPtr));
1671 CHKERR commonDataPtr->getInternalVar(fe_ent, nb_gauss_pts, size_of_vars,
1672 size_of_grad, size_of_stress);
1674 MatrixDouble &mat_int = *commonDataPtr->internalVariablePtr;
1675 vector<Tag> tags_vec;
1678 for (
auto c : mgis_bv.isvs) {
1679 auto vsize = getVariableSize(
c, mgis_bv.hypothesis);
1680 const size_t parav_siz = get_paraview_size(vsize);
1681 tags_vec.emplace_back(get_tag(
c.name, parav_siz));
1684 if (!(side == 0 &&
type == MBVERTEX))
1687 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1689 double coords[] = {0, 0, 0};
1691 for (
int dd = 0;
dd != 3;
dd++)
1692 coords[dd] = DomainEleOp::getCoordsAtGaussPts()(gg,
dd);
1694 CHKERR internalVarMesh.create_vertex(coords, vertex);
1697 auto it = tags_vec.begin();
1698 for (
auto c : mgis_bv.isvs) {
1699 auto vsize = getVariableSize(
c, mgis_bv.hypothesis);
1700 const size_t parav_siz = get_paraview_size(vsize);
1702 getVariableOffset(mgis_bv.isvs,
c.name, mgis_bv.hypothesis);
1706 tag_vec.resize(parav_siz);
1708 CHKERR internalVarMesh.tag_set_data(*it, &vertex, 1, &*tag_vec.begin());
1714 array<double, 9> my_stress_vec{
1715 t_stress(0, 0), t_stress(1, 1), t_stress(2, 2),
1716 t_stress(0, 1), t_stress(1, 0), t_stress(0, 2),
1717 t_stress(2, 0), t_stress(1, 2), t_stress(2, 1)};
1722 array<double, 9> grad1_vec;
1726 grad1_vec = getVoigtVec<3>(t_strain);
1729 t_strain(
i,
j) = (t_grad(
i,
j) || t_grad(
j,
i)) / 2;
1730 grad1_vec = getVoigtVecSymm<3>(t_strain);
1733 CHKERR internalVarMesh.tag_set_data(th_stress, &vertex, 1,
1734 my_stress_vec.data());
1735 CHKERR internalVarMesh.tag_set_data(th_grad, &vertex, 1,
1737 CHKERR internalVarMesh.tag_set_data(th_disp, &vertex, 1, &*disps.begin());
1748 boost::shared_ptr<MFrontInterface::CommonData> commonDataPtr;
1749 moab::Interface &internalVarMesh;
1750 std::string fieldName;
1753template <ModelHypothesis MH, AssemblyType AT>
1754MoFEMErrorCode MFrontInterfaceImpl<MH, AT>::setUpdateInternalVariablesOperators(
1755 ForcesAndSourcesCore::RuleHookFun rule, std::string
field_name) {
1758 updateIntVariablesElePtr = boost::make_shared<DomainEle>(mField);
1760 updateIntVariablesElePtr->getRuleHook = rule;
1763 updateIntVariablesElePtr->getOpPtrVector(), {H1});
1765 updateIntVariablesElePtr->getOpPtrVector().push_back(
1766 new OpCalculateVectorFieldGradient<DIM, DIM>(
field_name,
1767 commonDataPtr->mGradPtr));
1768 updateIntVariablesElePtr->getOpPtrVector().push_back(
1769 new OpCalculateVectorFieldValues<DIM>(
field_name,
1770 commonDataPtr->mDispPtr));
1771 if (isFiniteKinematics)
1772 updateIntVariablesElePtr->getOpPtrVector().push_back(
1773 new OpUpdateVariablesFiniteStrains<MH>(
field_name, commonDataPtr,
1776 updateIntVariablesElePtr->getOpPtrVector().push_back(
1777 new OpUpdateVariablesSmallStrains<MH>(
field_name, commonDataPtr,
1779 if (saveGauss && (MH == TRIDIMENSIONAL)) {
1780 auto &moab_gauss = *moabGaussIntPtr;
1781 updateIntVariablesElePtr->getOpPtrVector().push_back(
1782 new OpSaveGaussPts<MH>(
field_name, moab_gauss, commonDataPtr));
1788template <
bool IS_LARGE_STRAIN, ModelHypothesis MH>
1789struct OpSaveStress :
public MFrontEleType<MH>
::DomainEleOp {
1790 static constexpr int DIM = MFrontEleType<MH>::SPACE_DIM;
1791 using DomainEleOp =
typename MFrontEleType<MH>::DomainEleOp;
1794 boost::shared_ptr<MFrontInterface::CommonData> common_data_ptr)
1796 commonDataPtr(common_data_ptr) {
1797 std::fill(&DomainEleOp::doEntities[MBEDGE],
1798 &DomainEleOp::doEntities[MBMAXTYPE],
false);
1803 const size_t nb_gauss_pts = DomainEleOp::getGaussPts().size2();
1804 auto fe_ent = DomainEleOp::getNumeredEntFiniteElementPtr()->getEnt();
1805 auto id = commonDataPtr->blocksIDmap.at(fe_ent);
1806 auto &dAta = commonDataPtr->setOfBlocksData.at(
id);
1808 int &size_of_stress = dAta.sizeStressVar;
1809 int &size_of_grad = dAta.sizeGradVar;
1811 CHKERR commonDataPtr->getInternalVar(fe_ent, nb_gauss_pts, dAta.sizeIntVar,
1812 dAta.sizeGradVar, dAta.sizeStressVar,
1815 MatrixDouble &mat_stress = *commonDataPtr->mPrevStressPtr;
1818 commonDataPtr->mFullStressPtr->resize(nb_gauss_pts, 3 * 3);
1819 commonDataPtr->mFullStressPtr->clear();
1820 auto t_full_stress =
1821 getFTensor2FromMat<3, 3>(*(commonDataPtr->mFullStressPtr));
1823 commonDataPtr->mFullStrainPtr->resize(nb_gauss_pts, 3 * 3);
1824 commonDataPtr->mFullStrainPtr->clear();
1825 auto t_full_strain =
1826 getFTensor2FromMat<3, 3>(*(commonDataPtr->mFullStrainPtr));
1831 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1834 &mat_stress.data()[gg * size_of_stress], size_of_stress);
1841 if constexpr (IS_LARGE_STRAIN) {
1842 if constexpr (DIM == 3) {
1845 }
else if constexpr (DIM == 2) {
1850 if constexpr (DIM == 3) {
1855 }
else if constexpr (DIM == 2) {
1863 t_full_stress(
i,
j) = t_stress(
i,
j);
1864 t_full_strain(
i,
j) = t_grad(
i,
j);
1874 boost::shared_ptr<MFrontInterface::CommonData> commonDataPtr;
1877template <ModelHypothesis MH, AssemblyType AT>
1878MoFEMErrorCode MFrontInterfaceImpl<MH, AT>::setPostProcessOperators(
1879 ForcesAndSourcesCore::RuleHookFun rule, std::string fe_name,
1883 postProcFe = boost::make_shared<PostProcDomainEle>(mField);
1885 auto &pip = postProcFe->getOpPtrVector();
1887 pip.push_back(
new OpCalculateVectorFieldValues<DIM>(
field_name,
1888 commonDataPtr->mDispPtr));
1890 auto entity_data_l2 = boost::make_shared<EntitiesFieldData>(MBENTITYSET);
1891 auto mass_ptr = boost::make_shared<MatrixDouble>();
1892 auto strain_coeffs_ptr = boost::make_shared<MatrixDouble>();
1893 auto stress_coeffs_ptr = boost::make_shared<MatrixDouble>();
1895 auto op_this =
new OpLoopThis<DomainEle>(mField, fe_name, Sev::noisy);
1896 pip.push_back(op_this);
1897 pip.push_back(
new OpDGProjectionEvaluation(
1898 commonDataPtr->mFullStrainPtr, strain_coeffs_ptr, entity_data_l2,
1899 fieldBase,
L2, Sev::noisy,
1900 OpDGProjectionEvaluation::OutputLayout::GaussByCoeffs));
1901 pip.push_back(
new OpDGProjectionEvaluation(
1902 commonDataPtr->mFullStressPtr, stress_coeffs_ptr, entity_data_l2,
1903 fieldBase,
L2, Sev::noisy,
1904 OpDGProjectionEvaluation::OutputLayout::GaussByCoeffs));
1906 auto fe_physics_ptr = op_this->getThisFEPtr();
1907 fe_physics_ptr->getRuleHook = rule;
1909 fe_physics_ptr->getOpPtrVector().push_back(
new OpDGProjectionMassMatrix(
1910 order, mass_ptr, entity_data_l2, fieldBase,
L2));
1911 if (isFiniteKinematics) {
1912 fe_physics_ptr->getOpPtrVector().push_back(
1913 new OpSaveStress<true, MH>(
field_name, commonDataPtr));
1915 fe_physics_ptr->getOpPtrVector().push_back(
1916 new OpSaveStress<false, MH>(
field_name, commonDataPtr));
1918 fe_physics_ptr->getOpPtrVector().push_back(
new OpDGProjectionCoefficients(
1919 commonDataPtr->mFullStrainPtr, strain_coeffs_ptr, mass_ptr,
1920 entity_data_l2, fieldBase,
L2, Sev::noisy, DataLayout::GaussByCoeffs));
1921 fe_physics_ptr->getOpPtrVector().push_back(
new OpDGProjectionCoefficients(
1922 commonDataPtr->mFullStressPtr, stress_coeffs_ptr, mass_ptr,
1923 entity_data_l2, fieldBase,
L2, Sev::noisy, DataLayout::GaussByCoeffs));
1925 using OpPPMapVec = OpPostProcMapInMoab<DIM, DIM>;
1926 using OpPPMapTen = OpPostProcMapInMoab<3, 3>;
1928 pip.push_back(
new OpPPMapVec(
1930 postProcFe->getPostProcMesh(), postProcFe->getMapGaussPts(),
1934 {{field_name, commonDataPtr->mDispPtr}},
1942 pip.push_back(
new OpPPMapTen(
1944 postProcFe->getPostProcMesh(), postProcFe->getMapGaussPts(),
1950 {{
"STRAIN", commonDataPtr->mFullStrainPtr},
1951 {
"STRESS", commonDataPtr->mFullStressPtr}},
1960template <ModelHypothesis MH, AssemblyType AT>
1962 SmartPetscObj<DM> dm,
1966 auto make_vtks = [&]() {
1971 CHKERR postProcFe->writeFile(
"out_" + optionsPrefix +
1972 boost::lexical_cast<std::string>(step) +
1977 string file_name =
"out_" + optionsPrefix +
"gauss_" +
1978 boost::lexical_cast<std::string>(step) +
".h5m";
1980 CHKERR moabGaussIntPtr->write_file(file_name.c_str(),
"MOAB",
1981 "PARALLEL=WRITE_PART");
1982 CHKERR moabGaussIntPtr->delete_mesh();
1993template <ModelHypothesis MH, AssemblyType AT>
1995MFrontInterfaceImpl<MH, AT>::updateInternalVariables(SmartPetscObj<DM> dm,
1996 std::string fe_name) {
2002template struct MFrontInterfaceImpl<TRIDIMENSIONAL, AssemblyType::PETSC>;
2003template struct MFrontInterfaceImpl<AXISYMMETRICAL, AssemblyType::PETSC>;
2004template struct MFrontInterfaceImpl<PLANESTRAIN, AssemblyType::PETSC>;
2006template struct MFrontInterfaceImpl<TRIDIMENSIONAL, AssemblyType::BLOCK_SCHUR>;
2007template struct MFrontInterfaceImpl<AXISYMMETRICAL, AssemblyType::BLOCK_SCHUR>;
2008template struct MFrontInterfaceImpl<PLANESTRAIN, AssemblyType::BLOCK_SCHUR>;
2020boost::shared_ptr<MFrontInterface>
2025 "MoFEM built without MFront support. MFrontInterface is not available.");
static MoFEMErrorCode setBlocks(MoFEM::Interface &m_field, boost::shared_ptr< map< int, BlockData > > &block_sets_ptr)
DomainEle::UserDataOperator DomainEleOp
Finire element operator type.
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#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()
@ L2
field with C-1 continuity
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
static const char *const ApproximationBaseNames[]
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define _IT_CUBITMESHSETS_BY_SET_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet having a particular BC meshset in a moFEM field.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'J', DIM1 > J
FTensor::Index< 'j', 3 > j
Tensors class implemented by Walter Landry.
Tensor2_Expr< Kronecker_Delta< T >, T, Dim0, Dim1, i, j > kronecker_delta(const Index< i, Dim0 > &, const Index< j, Dim1 > &)
Rank 2.
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
MatrixShallowArrayAdaptor< double > MatrixAdaptor
Matrix adaptor.
UBlasMatrix< double > MatrixDouble
UBlasVector< double > VectorDouble
MatrixBoundedArray< double, 9 > MatrixDouble3by3
implementation of Data Operators for Forces and Sources
auto getVectorAdaptor(T1 ptr, const size_t n)
Get Vector adaptor.
auto type_from_handle(const EntityHandle h)
get type from entity handle
auto getVoigtVecAxisymm(T &t_mat, const double hoop_term)
auto to_non_symm(const FTensor::Tensor2_symmetric< T, DIM > &symm)
boost::shared_ptr< MFrontInterface > createMFrontInterface(MoFEM::Interface &m_field, ModelHypothesis mh, AssemblyType at)
create mfront interface
ModelHypothesis
Enumeration of model hypotheses supported by MFront interface.
@ AXISYMMETRICAL
Axisymmetrical model hypothesis.
@ PLANESTRAIN
Plane strain model hypothesis.
@ TRIDIMENSIONAL
3D model hypothesis.
auto getVoigtVecSymmAxisymm(T &t_mat, const double hoop_term)
MoFEMErrorCode opFactoryDomainRhs(MoFEM::Interface &m_field, std::string block_name, Pip &pip, std::string u, std::string ep, std::string tau)
MoFEMErrorCode opFactoryDomainLhs(MoFEM::Interface &m_field, std::string block_name, Pip &pip, std::string u, std::string ep, std::string tau)
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
constexpr IntegrationType I
constexpr auto field_name
OpBaseImpl< PETSC, EdgeEleOp > OpBase
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
auto getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
CommonData(MoFEM::Interface &m_field)
int nbRows
number of dofs on rows
int nbIntegrationPts
number of integration points
virtual MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data)
Integrate grad-grad operator.
int nbCols
number if dof on column
int nbRowBaseFunctions
number or row base functions
Volume finite element base.
constexpr AssemblyType AT