453 {
454
456
457 try {
458
459 moab::Core mb_instance;
460 moab::Interface &moab = mb_instance;
461
462 PetscBool flg_block_config, flg_file;
463 char mesh_file_name[255];
464 char block_config_file[255];
465 PetscBool flg_order_force;
467 PetscInt order_force = 2;
468 PetscBool flg_eps_u, flg_eps_rho, flg_eps_l;
469 double eps_u = 1e-6;
470 double eps_rho = 1e-3;
471 double eps_l = 0;
472 PetscBool is_curl = PETSC_TRUE;
473 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Elastic Config", "none");
474 CHKERR PetscOptionsString(
"-my_file",
"mesh file name",
"",
"mesh.h5m",
475 mesh_file_name, 255, &flg_file);
476 CHKERR PetscOptionsInt(
"-my_order",
"default approximation order",
"",
479 "-my_order_force",
480 "default approximation order for traction approximation", "",
481 order_force, &order_force, &flg_order_force);
482 CHKERR PetscOptionsString(
"-my_block_config",
483 "elastic configuration file name", "",
484 "block_conf.in", block_config_file, 255,
485 &flg_block_config);
486 CHKERR PetscOptionsReal(
"-my_eps_rho",
"traction regularisation parameter",
487 "", eps_rho, &eps_rho, &flg_eps_rho);
489 "-my_eps_u", "displacement-misfit regularisation parameter", "", eps_u,
490 &eps_u, &flg_eps_u);
491 CHKERR PetscOptionsReal(
"-my_eps_l",
"curl regularisation parameter",
"",
492 eps_l, &eps_l, &flg_eps_l);
494 "-my_curl", "use H(curl) space to approximate tractions", "", is_curl,
495 &is_curl, PETSC_NULLPTR);
496 PetscOptionsEnd();
497
498
499 if (flg_file != PETSC_TRUE) {
501 "*** ERROR -my_file (MESH FILE NEEDED)");
502 }
503
504 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
505 if (pcomm == nullptr)
506 pcomm = new ParallelComm(&moab, PETSC_COMM_WORLD);
507
508
509 const char *option;
510 option = "PARALLEL=READ_PART;"
511 "PARALLEL_RESOLVE_SHARED_ENTS;"
512 "PARTITION=PARALLEL_PARTITION;";
513
514 CHKERR moab.load_file(mesh_file_name, 0, option);
515
516
519
522
523 CHKERR mmanager_ptr->printDisplacementSet();
524 CHKERR mmanager_ptr->printForceSet();
525
526 CHKERR mmanager_ptr->printMaterialsSet();
527
528
530 bit_level0.set(0);
531 {
533 CHKERR moab.get_entities_by_dimension(0, 3, ents3d);
535 ents3d, bit_level0, false);
536 }
537
538
539
540 std::vector<Range> setOrderToEnts(10);
541
542
543
544 Range set_order_ents;
545 std::map<int, BlockOptionData> block_data;
546 if (flg_block_config) {
547 double read_eps_u, read_eps_rho, read_eps_l;
548 try {
549 ifstream ini_file(block_config_file);
550 if (!ini_file.is_open()) {
551 SETERRQ(PETSC_COMM_SELF, 1,
552 "*** -my_block_config does not exist ***");
553 }
554
555 po::variables_map vm;
556 po::options_description config_file_options;
557 config_file_options.add_options()(
558 "eps_u", po::value<double>(&read_eps_u)->default_value(-1))(
559 "eps_rho", po::value<double>(&read_eps_rho)->default_value(-1))(
560 "eps_l", po::value<double>(&read_eps_l)->default_value(-1));
562 std::ostringstream str_order;
563 str_order << "block_" << it->getMeshsetId() << ".displacement_order";
564 config_file_options.add_options()(
565 str_order.str().c_str(),
566 po::value<int>(&block_data[it->getMeshsetId()].oRder)
567 ->default_value(
order));
568 std::ostringstream str_cond;
569 str_cond << "block_" << it->getMeshsetId() << ".young_modulus";
570 config_file_options.add_options()(
571 str_cond.str().c_str(),
572 po::value<double>(&block_data[it->getMeshsetId()].yOung)
573 ->default_value(-1));
574 std::ostringstream str_capa;
575 str_capa << "block_" << it->getMeshsetId() << ".poisson_ratio";
576 config_file_options.add_options()(
577 str_capa.str().c_str(),
578 po::value<double>(&block_data[it->getMeshsetId()].pOisson)
579 ->default_value(-2));
580 }
581 po::parsed_options parsed =
582 parse_config_file(ini_file, config_file_options, true);
583 store(parsed, vm);
584 po::notify(vm);
586 if (block_data[it->getMeshsetId()].oRder == -1)
587 continue;
588 if (block_data[it->getMeshsetId()].oRder ==
order)
589 continue;
590 PetscPrintf(PETSC_COMM_WORLD, "Set block %d order to %d\n",
591 it->getMeshsetId(), block_data[it->getMeshsetId()].oRder);
593 CHKERR moab.get_entities_by_handle(it->getMeshset(), block_ents,
594 true);
595
597 CHKERR moab.get_connectivity(block_ents, nodes,
true);
598 Range ents_to_set_order, ents3d;
599 CHKERR moab.get_adjacencies(nodes, 3,
false, ents3d,
600 moab::Interface::UNION);
601 CHKERR moab.get_adjacencies(ents3d, 2,
false, ents_to_set_order,
602 moab::Interface::UNION);
603 CHKERR moab.get_adjacencies(ents3d, 1,
false, ents_to_set_order,
604 moab::Interface::UNION);
605 ents_to_set_order = subtract(
606 ents_to_set_order, ents_to_set_order.subset_by_type(MBQUAD));
607 ents_to_set_order = subtract(
608 ents_to_set_order, ents_to_set_order.subset_by_type(MBPRISM));
609 set_order_ents.merge(ents3d);
610 set_order_ents.merge(ents_to_set_order);
611 setOrderToEnts[block_data[it->getMeshsetId()].oRder].merge(
612 set_order_ents);
613 }
614 CHKERR comm_interface_ptr->synchroniseEntities(set_order_ents, 0);
615 std::vector<std::string> additional_parameters;
616 additional_parameters =
617 collect_unrecognized(parsed.options, po::include_positional);
618 for (std::vector<std::string>::iterator vit =
619 additional_parameters.begin();
620 vit != additional_parameters.end(); vit++) {
621 CHKERR PetscPrintf(PETSC_COMM_WORLD,
622 "** WARNING Unrecognized option %s\n",
623 vit->c_str());
624 }
625 } catch (const std::exception &ex) {
626 std::ostringstream ss;
627 ss << ex.what() << std::endl;
629 }
630 if (read_eps_u > 0) {
631 eps_u = read_eps_u;
632 };
633 if (read_eps_rho > 0) {
634 eps_rho = read_eps_rho;
635 }
636 if (read_eps_l > 0) {
637 eps_l = read_eps_l;
638 }
639 }
640
641 PetscPrintf(PETSC_COMM_WORLD, "epsU = %6.4e epsRho = %6.4e\n", eps_u,
642 eps_rho);
643
644
649 if (is_curl) {
651 } else {
653 }
654
655
660
661 CHKERR comm_interface_ptr->synchroniseFieldEntities(
"U");
662 CHKERR comm_interface_ptr->synchroniseFieldEntities(
"UPSILON");
663 CHKERR comm_interface_ptr->synchroniseFieldEntities(
"RHO");
664
667 Range ents_1st_layer;
668
669 if (mmanager_ptr->checkMeshset(202,
SIDESET)) {
671 ents_1st_layer, true);
673 vertex_to_fix, false);
674 CHKERR mmanager_ptr->getEntitiesByDimension(202,
SIDESET, 1, edges_to_fix,
675 false);
676 if (vertex_to_fix.size() != 1 && !vertex_to_fix.empty()) {
678 "Should be one vertex only, but is %zu", vertex_to_fix.size());
679 }
680 }
681 CHKERR comm_interface_ptr->synchroniseEntities(ents_1st_layer, 0);
683 ents_1st_layer.subset_by_type(MBTRI), MBTRI, "RHO");
684 Range ents_2nd_layer;
685
686 if (mmanager_ptr->checkMeshset(101,
SIDESET)) {
688 ents_2nd_layer, true);
689 }
690 CHKERR comm_interface_ptr->synchroniseEntities(ents_2nd_layer, 0);
691
692 for (int oo = 2; oo != setOrderToEnts.size(); oo++) {
693 if (setOrderToEnts[oo].size() > 0) {
694 CHKERR comm_interface_ptr->synchroniseEntities(setOrderToEnts[oo], 0);
697 }
698 }
699
700 const int through_thickness_order = 2;
701 {
703 CHKERR moab.get_entities_by_dimension(0, 3, ents3d);
705 CHKERR moab.get_adjacencies(ents3d, 2,
false, ents,
706 moab::Interface::UNION);
707 CHKERR moab.get_adjacencies(ents3d, 1,
false, ents,
708 moab::Interface::UNION);
709
711 CHKERR moab.get_entities_by_type(0, MBPRISM, prisms);
712 {
714 CHKERR moab.get_adjacencies(prisms, 2,
false, quads,
715 moab::Interface::UNION);
717 prism_tris = quads.subset_by_type(MBTRI);
718 quads = subtract(quads, prism_tris);
720 CHKERR moab.get_adjacencies(quads, 1,
false, quads_edges,
721 moab::Interface::UNION);
722 Range prism_tris_edges;
723 CHKERR moab.get_adjacencies(prism_tris, 1,
false, prism_tris_edges,
724 moab::Interface::UNION);
725 quads_edges = subtract(quads_edges, prism_tris_edges);
726 prisms.merge(quads);
727 prisms.merge(quads_edges);
728 }
729
730 ents.merge(ents3d);
731 ents = subtract(ents, set_order_ents);
732 ents = subtract(ents, prisms);
733
734 CHKERR comm_interface_ptr->synchroniseEntities(ents, 0);
735 CHKERR comm_interface_ptr->synchroniseEntities(prisms, 0);
736
739
742 through_thickness_order);
743 }
746
747 if (is_curl) {
750 } else {
754 }
755
756
757
759 int default_block_id = -1;
761 CHKERR moab.tag_get_handle(
"BLOCK_ID", 1, MB_TYPE_INTEGER, block_id_tag,
762 MB_TAG_CREAT | MB_TAG_SPARSE, &default_block_id);
766 CHKERR it->getAttributeDataStructure(material);
767 const int block_id = it->getMeshsetId();
768 CHKERR moab.get_entities_by_handle(it->getMeshset(),
769 elastic_blocks[block_id], true);
770 const auto block_elements =
771 elastic_blocks[block_id].subset_by_type(MBTET);
772 CHKERR moab.tag_clear_data(block_id_tag, block_elements, &block_id);
773
774 const auto options_it = block_data.find(block_id);
775 if (options_it != block_data.end() && options_it->second.yOung > 0) {
776 material.
data.Young = options_it->second.yOung;
777 CHKERR PetscPrintf(PETSC_COMM_WORLD,
778 "Block %d set Young modulus %3.4g\n", block_id,
779 material.
data.Young);
780 }
781 if (options_it != block_data.end() && options_it->second.pOisson >= -1) {
782 material.
data.Poisson = options_it->second.pOisson;
783 CHKERR PetscPrintf(PETSC_COMM_WORLD,
784 "Block %d set Poisson ratio %3.4g\n", block_id,
785 material.
data.Poisson);
786 }
787 CHKERR mmanager_ptr->setAttributesByDataStructure(
BLOCKSET, block_id,
788 material);
789 }
790
795 for (const auto &[id, entities] : elastic_blocks)
796 CHKERR m_field.add_ents_to_finite_element_by_type(entities, MBTET,
797 "ELASTIC");
798
802 double elastic_energy = 0;
803 auto elastic_rhs_common =
804 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
805 m_field, elastic_rhs.getOpPtrVector(), "U", "MAT_ELASTIC",
806 Sev::verbose);
807 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
808 m_field, elastic_rhs.getOpPtrVector(), "U", elastic_rhs_common,
809 Sev::verbose, true);
810 auto elastic_lhs_common =
811 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
812 m_field, elastic_lhs.getOpPtrVector(), "U", "MAT_ELASTIC",
813 Sev::verbose);
814 CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
815 m_field, elastic_lhs.getOpPtrVector(), "U", elastic_lhs_common,
816 Sev::verbose);
817 auto elastic_energy_common =
818 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
819 m_field, elastic_energy_fe.getOpPtrVector(), "U", "MAT_ELASTIC",
820 Sev::verbose);
822 elastic_energy_common->getMatStrain(),
823 elastic_energy_common->getMatCauchyStress(), elastic_energy));
824
825
828 {
833 auto block_it = elastic_blocks.find(2);
834 if (block_it == elastic_blocks.end()) {
836 "Elastic material block 2 is required for prism elements");
837 }
839 block_it->second);
841 block_it->second, MBPRISM, "ELASTIC_PRISM");
842
843 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
844 fat_prism_rhs.getOpPtrVector().push_back(
846 fat_prism_rhs.getOpPtrVector().push_back(
849 auto prism_rhs_common =
850 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, FatPrismOp>(
851 m_field, fat_prism_rhs.getOpPtrVector(), "U", "MAT_ELASTIC",
852 Sev::verbose);
853 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, FatPrismOp>(
854 m_field, fat_prism_rhs.getOpPtrVector(), "U", prism_rhs_common,
855 Sev::verbose, true);
856
857 fat_prism_lhs.getOpPtrVector().push_back(
859 fat_prism_lhs.getOpPtrVector().push_back(
861 auto prism_lhs_common =
862 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, FatPrismOp>(
863 m_field, fat_prism_lhs.getOpPtrVector(), "U", "MAT_ELASTIC",
864 Sev::verbose);
865 CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, FatPrismOp>(
866 m_field, fat_prism_lhs.getOpPtrVector(), "U", prism_lhs_common,
867 Sev::verbose);
868 }
869
870
872
873
880
883 "UPSILON");
885 "U");
887 "UPSILON");
889 "U");
891 "DISP_X");
893 "DISP_Y");
895 "DISPLACEMENTS_PENALTY");
896
897
906 "BT");
907
916 "B");
917
918
924 "D");
925
926
928
930
931
932 DMType dm_name = "MOFEM";
934
935 DM dm_control;
936 {
937
938 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_control);
939 CHKERR DMSetType(dm_control, dm_name);
940
942 bit_level0);
943 CHKERR DMSetFromOptions(dm_control);
946
954 CHKERR DMSetUp(dm_control);
955 }
956
958
959 ublas::matrix<Mat> nested_matrices(2, 2);
960 ublas::vector<IS> nested_is_rows(2);
961 ublas::vector<IS> nested_is_cols(2);
962 for (
int i = 0;
i != 2;
i++) {
963 nested_is_rows[
i] = PETSC_NULLPTR;
964 nested_is_cols[
i] = PETSC_NULLPTR;
965 for (
int j = 0;
j != 2;
j++) {
966 nested_matrices(
i,
j) = PETSC_NULLPTR;
967 }
968 }
969
970 ublas::matrix<Mat> sub_nested_matrices(2, 2);
971 ublas::vector<IS> sub_nested_is_rows(2);
972 ublas::vector<IS> sub_nested_is_cols(2);
973 for (
int i = 0;
i != 2;
i++) {
974 sub_nested_is_rows[
i] = PETSC_NULLPTR;
975 sub_nested_is_cols[
i] = PETSC_NULLPTR;
976 for (
int j = 0;
j != 2;
j++) {
977 sub_nested_matrices(
i,
j) = PETSC_NULLPTR;
978 }
979 }
980
981 DM dm_sub_volume_control;
982 {
983 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_volume_control);
984 CHKERR DMSetType(dm_sub_volume_control, dm_name);
985
986
988 "SUB_CONTROL_PROB");
994
995 CHKERR DMSetUp(dm_sub_volume_control);
996
999 boost::shared_ptr<Problem::SubProblemData> sub_data =
1001
1002 CHKERR sub_data->getRowIs(&nested_is_rows[0]);
1003 CHKERR sub_data->getColIs(&nested_is_cols[0]);
1004
1005 nested_matrices(0, 0) = PETSC_NULLPTR;
1006 }
1007
1008 {
1009 DM dm_sub_sub_elastic;
1010
1011 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_sub_elastic);
1012 CHKERR DMSetType(dm_sub_sub_elastic, dm_name);
1013
1014
1016 "ELASTIC_PROB");
1022
1023 CHKERR DMSetUp(dm_sub_sub_elastic);
1025 ->pushMarkDOFsOnEntities<DisplacementCubitBcData>("ELASTIC_PROB",
1026 "U");
1027
1028 Mat Kuu;
1030 CHKERR DMCreateMatrix(dm_sub_sub_elastic, &Kuu);
1031 CHKERR DMCreateGlobalVector(dm_sub_sub_elastic, &Du);
1032 CHKERR DMCreateGlobalVector(dm_sub_sub_elastic, &Fu);
1033 CHKERR MatZeroEntries(Kuu);
1034 CHKERR VecZeroEntries(Du);
1035 CHKERR VecZeroEntries(Fu);
1037 SCATTER_REVERSE);
1038
1039
1040 auto dirichlet_bc_ptr = boost::make_shared<FEMethod>();
1041 dirichlet_bc_ptr->vecAssembleSwitch =
1042 boost::movelib::make_unique<bool>(false);
1043 dirichlet_bc_ptr->matAssembleSwitch =
1044 boost::movelib::make_unique<bool>(false);
1045 dirichlet_bc_ptr->preProcessHook =
1047 m_field, dirichlet_bc_ptr,
1048 std::vector<boost::shared_ptr<ScalingMethod>>{}, false);
1049 dirichlet_bc_ptr->postProcessHook = [&]() {
1051 CHKERR VecGhostUpdateBegin(Fu, ADD_VALUES, SCATTER_REVERSE);
1052 CHKERR VecGhostUpdateEnd(Fu, ADD_VALUES, SCATTER_REVERSE);
1053 CHKERR VecAssemblyBegin(Fu);
1054 CHKERR VecAssemblyEnd(Fu);
1055 CHKERR MatAssemblyBegin(Kuu, MAT_FINAL_ASSEMBLY);
1056 CHKERR MatAssemblyEnd(Kuu, MAT_FINAL_ASSEMBLY);
1062 };
1063 dirichlet_bc_ptr->snes_ctx = FEMethod::CTX_SNESNONE;
1064 dirichlet_bc_ptr->ts_ctx = FEMethod::CTX_TSNONE;
1065
1067 dirichlet_bc_ptr.get());
1069 SCATTER_REVERSE);
1070
1071
1072 elastic_rhs.snes_f = Fu;
1073 fat_prism_rhs.snes_f = Fu;
1075 &elastic_rhs);
1077 &fat_prism_rhs);
1078
1079 elastic_lhs.snes_B = Kuu;
1080 fat_prism_lhs.snes_B = Kuu;
1082 &elastic_lhs);
1084 &fat_prism_lhs);
1085
1087 dirichlet_bc_ptr.get());
1088 CHKERR VecGhostUpdateBegin(Fu, ADD_VALUES, SCATTER_REVERSE);
1089 CHKERR VecGhostUpdateEnd(Fu, ADD_VALUES, SCATTER_REVERSE);
1090 CHKERR VecAssemblyBegin(Fu);
1091 CHKERR VecAssemblyEnd(Fu);
1095
1098 boost::shared_ptr<Problem::SubProblemData> sub_data =
1100
1101 CHKERR sub_data->getRowIs(&sub_nested_is_rows[0]);
1102 CHKERR sub_data->getColIs(&sub_nested_is_cols[0]);
1103 sub_nested_matrices(0, 0) = Kuu;
1104 IS isUpsilon;
1106 ->isCreateFromProblemFieldToOtherProblemField(
1107 "ELASTIC_PROB",
"U",
ROW,
"SUB_CONTROL_PROB",
"UPSILON",
ROW,
1108 PETSC_NULLPTR, &isUpsilon);
1109 sub_nested_is_rows[1] = isUpsilon;
1110 sub_nested_is_cols[1] = isUpsilon;
1111 sub_nested_matrices(1, 1) = Kuu;
1112 PetscObjectReference((PetscObject)Kuu);
1113 PetscObjectReference((PetscObject)isUpsilon);
1114
1115
1117 cerr << "Kuu" << endl;
1118 MatView(Kuu, PETSC_VIEWER_DRAW_WORLD);
1119 std::string wait;
1120 std::cin >> wait;
1121 }
1122
1123 CHKERR DMDestroy(&dm_sub_sub_elastic);
1124 }
1125
1126 {
1127 DM dm_sub_disp_penalty;
1128
1129
1130 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_disp_penalty);
1131 CHKERR DMSetType(dm_sub_disp_penalty, dm_name);
1132
1133
1135 "S_PROB");
1139
1141 CHKERR DMSetUp(dm_sub_disp_penalty);
1142
1143 Mat S;
1144 CHKERR DMCreateMatrix(dm_sub_disp_penalty, &S);
1145 CHKERR MatZeroEntries(S);
1146
1149 face_element.getOpPtrVector().push_back(
new OpCellS(S, eps_u));
1151 "DISPLACEMENTS_PENALTY", &face_element);
1152 CHKERR MatAssemblyBegin(S, MAT_FLUSH_ASSEMBLY);
1153 CHKERR MatAssemblyEnd(S, MAT_FLUSH_ASSEMBLY);
1154
1155
1157 cerr << "S" << endl;
1158 MatView(S, PETSC_VIEWER_DRAW_WORLD);
1159 std::string wait;
1160 std::cin >> wait;
1161 }
1162
1165 boost::shared_ptr<Problem::SubProblemData> sub_data =
1167
1168
1169 sub_nested_matrices(1, 0) = S;
1170
1171 CHKERR DMDestroy(&dm_sub_disp_penalty);
1172 }
1173
1174
1175 {
1176 DM dm_sub_force_penalty;
1177
1178
1179 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_force_penalty);
1180 CHKERR DMSetType(dm_sub_force_penalty, dm_name);
1181
1182
1187
1189 CHKERR DMSetUp(dm_sub_force_penalty);
1190
1192 CHKERR DMCreateMatrix(dm_sub_force_penalty, &
D);
1194
1195 {
1197
1198 if (is_curl) {
1200 {HCURL});
1201 face_d_matrix.getOpPtrVector().push_back(
1203 } else {
1205 face_d_matrix.getOpPtrVector().push_back(
1207 }
1209 &face_d_matrix);
1210 }
1211 CHKERR MatAssemblyBegin(
D, MAT_FINAL_ASSEMBLY);
1212 CHKERR MatAssemblyEnd(
D, MAT_FINAL_ASSEMBLY);
1213
1216
1217
1218
1219 if (is_curl == PETSC_FALSE) {
1220 int nb_dofs_to_fix = 0;
1221 int index_to_fix = 0;
1222 if (!vertex_to_fix.empty()) {
1223 boost::shared_ptr<NumeredDofEntity> dof_ptr;
1226 dof_ptr);
1227 if (dof_ptr) {
1229 nb_dofs_to_fix = 1;
1230 index_to_fix = dof_ptr->getPetscGlobalDofIdx();
1231 cerr << *dof_ptr << endl;
1232 }
1233 }
1234 }
1235 CHKERR MatZeroRowsColumns(
D, nb_dofs_to_fix, &index_to_fix,
1236 eps_rho / eps_u, PETSC_NULLPTR,
1237 PETSC_NULLPTR);
1238 } else {
1239 std::vector<int> dofs_to_fix;
1240 for (auto p_eit = edges_to_fix.pair_begin();
1241 p_eit != edges_to_fix.pair_end(); ++p_eit) {
1244 auto lo = row_dofs->lower_bound(
1246 auto hi =
1248 bit_number, p_eit->second));
1249 for (; lo != hi; ++lo)
1251 dofs_to_fix.push_back((*lo)->getPetscGlobalDofIdx());
1252 }
1253 CHKERR MatZeroRowsColumns(
D, dofs_to_fix.size(), &*dofs_to_fix.begin(),
1254 eps_rho / eps_u, PETSC_NULLPTR,
1255 PETSC_NULLPTR);
1256 }
1257
1258
1260 cerr << "D" << endl;
1261 MatView(
D, PETSC_VIEWER_DRAW_WORLD);
1262 std::string wait;
1263 std::cin >> wait;
1264 }
1265
1266 boost::shared_ptr<Problem::SubProblemData> sub_data =
1268 CHKERR sub_data->getRowIs(&nested_is_rows[1]);
1269 CHKERR sub_data->getColIs(&nested_is_cols[1]);
1270 nested_matrices(1, 1) =
D;
1271
1272 CHKERR DMDestroy(&dm_sub_force_penalty);
1273 }
1274
1275 {
1276 DM dm_sub_force;
1277
1278
1279 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_force);
1280 CHKERR DMSetType(dm_sub_force, dm_name);
1281
1287
1289 CHKERR DMSetUp(dm_sub_force);
1290
1291 Mat UB, UPSILONB;
1292 CHKERR DMCreateMatrix(dm_sub_force, &UB);
1293 CHKERR MatZeroEntries(UB);
1294
1295 CHKERR DMCreateMatrix(dm_sub_force, &UPSILONB);
1296 CHKERR MatZeroEntries(UPSILONB);
1297 {
1299 if (is_curl) {
1301 {H1, HCURL});
1302 face_b_matrices.getOpPtrVector().push_back(
new OpCellCurlB(UB,
"U"));
1303 face_b_matrices.getOpPtrVector().push_back(
1305 } else {
1307 {H1});
1308 face_b_matrices.getOpPtrVector().push_back(
1310 face_b_matrices.getOpPtrVector().push_back(
1312 }
1314 }
1315 CHKERR MatAssemblyBegin(UB, MAT_FINAL_ASSEMBLY);
1316 CHKERR MatAssemblyBegin(UPSILONB, MAT_FINAL_ASSEMBLY);
1317 CHKERR MatAssemblyEnd(UB, MAT_FINAL_ASSEMBLY);
1318 CHKERR MatAssemblyEnd(UPSILONB, MAT_FINAL_ASSEMBLY);
1319
1322
1323
1324
1325 if (is_curl == PETSC_FALSE) {
1326 int nb_dofs_to_fix = 0;
1327 int index_to_fix = 0;
1328 if (!vertex_to_fix.empty()) {
1329 boost::shared_ptr<NumeredDofEntity> dof_ptr;
1332 dof_ptr);
1333 if (dof_ptr) {
1335 nb_dofs_to_fix = 1;
1336 index_to_fix = dof_ptr->getPetscGlobalDofIdx();
1337 cerr << *dof_ptr << endl;
1338 }
1339 }
1340 }
1341 CHKERR MatZeroRows(UB, nb_dofs_to_fix, &index_to_fix, 0, PETSC_NULLPTR,
1342 PETSC_NULLPTR);
1343 CHKERR MatZeroRows(UPSILONB, nb_dofs_to_fix, &index_to_fix, 0,
1344 PETSC_NULLPTR, PETSC_NULLPTR);
1345 } else {
1346 std::vector<int> dofs_to_fix;
1347 for (auto p_eit = edges_to_fix.pair_begin();
1348 p_eit != edges_to_fix.pair_end(); ++p_eit) {
1351 auto lo = row_dofs->lower_bound(
1353 auto hi =
1355 bit_number, p_eit->second));
1356 for (; lo != hi; ++lo)
1358 dofs_to_fix.push_back((*lo)->getPetscGlobalDofIdx());
1359 }
1360 CHKERR MatZeroRows(UB, dofs_to_fix.size(), &*dofs_to_fix.begin(), 0,
1361 PETSC_NULLPTR, PETSC_NULLPTR);
1362 CHKERR MatZeroRows(UPSILONB, dofs_to_fix.size(), &*dofs_to_fix.begin(),
1363 0, PETSC_NULLPTR, PETSC_NULLPTR);
1364 }
1365
1366 Mat UBT;
1367 CHKERR MatTranspose(UB, MAT_INITIAL_MATRIX, &UBT);
1369
1370
1372 cerr << "UBT" << endl;
1373 MatView(UBT, PETSC_VIEWER_DRAW_WORLD);
1374 std::string wait;
1375 std::cin >> wait;
1376 }
1377
1378 boost::shared_ptr<Problem::SubProblemData> sub_data =
1380
1381
1382 nested_matrices(0, 1) = UBT;
1383
1385 cerr << "UPSILONB" << endl;
1386 MatView(UPSILONB, PETSC_VIEWER_DRAW_WORLD);
1387 std::string wait;
1388 std::cin >> wait;
1389 }
1390
1391
1392
1393 nested_matrices(1, 0) = UPSILONB;
1394
1395 CHKERR DMDestroy(&dm_sub_force);
1396 }
1397
1398 Mat SubA;
1399 CHKERR MatCreateNest(PETSC_COMM_WORLD, 2, &sub_nested_is_rows[0], 2,
1400 &sub_nested_is_cols[0], &sub_nested_matrices(0, 0),
1401 &SubA);
1402 nested_matrices(0, 0) = SubA;
1403
1404 CHKERR MatAssemblyBegin(SubA, MAT_FINAL_ASSEMBLY);
1405 CHKERR MatAssemblyEnd(SubA, MAT_FINAL_ASSEMBLY);
1406
1408 cerr << "Nested SubA" << endl;
1409 MatView(SubA, PETSC_VIEWER_STDOUT_WORLD);
1410 }
1411
1413 CHKERR MatCreateNest(PETSC_COMM_WORLD, 2, &nested_is_rows[0], 2,
1414 &nested_is_cols[0], &nested_matrices(0, 0), &A);
1415
1416 CHKERR MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);
1417 CHKERR MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);
1418
1420 cerr << "Nested A" << endl;
1421 MatView(A, PETSC_VIEWER_STDOUT_WORLD);
1422 }
1423
1425 CHKERR DMCreateGlobalVector(dm_control, &
D);
1426 CHKERR DMCreateGlobalVector(dm_control, &
F);
1427
1428
1429 {
1432 face_element.getOpPtrVector().push_back(
new OpGetDispX(common_data));
1433 face_element.getOpPtrVector().push_back(
new OpGetDispY(common_data));
1434 face_element.getOpPtrVector().push_back(
1437 &face_element);
1438 CHKERR VecGhostUpdateBegin(
F, ADD_VALUES, SCATTER_REVERSE);
1439 CHKERR VecGhostUpdateEnd(
F, ADD_VALUES, SCATTER_REVERSE);
1442 }
1443
1444 KSP solver;
1445
1446 {
1447 CHKERR KSPCreate(PETSC_COMM_WORLD, &solver);
1448 CHKERR KSPSetDM(solver, dm_control);
1449 CHKERR KSPSetFromOptions(solver);
1450 CHKERR KSPSetOperators(solver, A, A);
1451 CHKERR KSPSetDMActive(solver, PETSC_FALSE);
1452 CHKERR KSPSetInitialGuessKnoll(solver, PETSC_FALSE);
1453 CHKERR KSPSetInitialGuessNonzero(solver, PETSC_FALSE);
1454 PC pc;
1455 CHKERR KSPGetPC(solver, &pc);
1456 CHKERR PCSetType(pc, PCFIELDSPLIT);
1457 PetscBool is_pcfs = PETSC_FALSE;
1458 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
1459 if (is_pcfs) {
1460 CHKERR PCSetOperators(pc, A, A);
1461 CHKERR PCFieldSplitSetIS(pc, NULL, nested_is_rows[0]);
1462 CHKERR PCFieldSplitSetIS(pc, NULL, nested_is_rows[1]);
1463 CHKERR PCFieldSplitSetType(pc, PC_COMPOSITE_SCHUR);
1465 KSP *sub_ksp;
1467 CHKERR PCFieldSplitGetSubKSP(pc, &
n, &sub_ksp);
1468 {
1469 PC sub_pc_0;
1470 CHKERR KSPGetPC(sub_ksp[0], &sub_pc_0);
1471 CHKERR PCSetOperators(sub_pc_0, SubA, SubA);
1472 CHKERR PCSetType(sub_pc_0, PCFIELDSPLIT);
1473 CHKERR PCFieldSplitSetIS(sub_pc_0, NULL, sub_nested_is_rows[0]);
1474 CHKERR PCFieldSplitSetIS(sub_pc_0, NULL, sub_nested_is_rows[1]);
1475 CHKERR PCFieldSplitSetType(sub_pc_0, PC_COMPOSITE_MULTIPLICATIVE);
1476
1477
1478
1479 CHKERR PCSetUp(sub_pc_0);
1480 }
1481 } else {
1483 "This solver requires the PCFIELDSPLIT preconditioner");
1484 }
1486 }
1487
1488
1490
1491 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1492 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1494 SCATTER_REVERSE);
1495
1497 CHKERR VecView(
D, PETSC_VIEWER_DRAW_WORLD);
1498 std::string wait;
1499 std::cin >> wait;
1500 }
1501
1502
1503 for (
int i = 0;
i != 2;
i++) {
1504 if (sub_nested_is_rows[
i]) {
1505 CHKERR ISDestroy(&sub_nested_is_rows[
i]);
1506 }
1507 if (sub_nested_is_cols[
i]) {
1508 CHKERR ISDestroy(&sub_nested_is_cols[
i]);
1509 }
1510 for (
int j = 0;
j != 2;
j++) {
1511 if (sub_nested_matrices(
i,
j)) {
1512 CHKERR MatDestroy(&sub_nested_matrices(
i,
j));
1513 }
1514 }
1515 }
1516 for (
int i = 0;
i != 2;
i++) {
1517 if (nested_is_rows[
i]) {
1518 CHKERR ISDestroy(&nested_is_rows[
i]);
1519 }
1520 if (nested_is_cols[
i]) {
1521 CHKERR ISDestroy(&nested_is_cols[
i]);
1522 }
1523 for (
int j = 0;
j != 2;
j++) {
1524 if (nested_matrices(
i,
j)) {
1525 CHKERR MatDestroy(&nested_matrices(
i,
j));
1526 }
1527 }
1528 }
1529
1530 CHKERR MatDestroy(&SubA);
1534
1535 CHKERR DMDestroy(&dm_sub_volume_control);
1536
1537 using PostProcVolume =
1540
1541 PostProcVolume post_proc(m_field, "my");
1542 {
1544
1545 auto u_ptr = boost::make_shared<MatrixDouble>();
1546 post_proc.getOpPtrVector().push_back(
1548 auto hooke_common =
1549 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
1550 m_field, post_proc.getOpPtrVector(), "U", "MAT_ELASTIC",
1551 Sev::verbose);
1552 post_proc.getOpPtrVector().push_back(new OpPPVolume(
1553 post_proc.getPostProcMesh(), post_proc.getMapGaussPts(),
1554 OpPPVolume::DataMapVec{}, OpPPVolume::DataMapMat{{"U", u_ptr}},
1555 OpPPVolume::DataMapMat{{"U_GRAD", hooke_common->matGradPtr}},
1556 OpPPVolume::DataMapMat{
1557 {"STRESS", hooke_common->getMatCauchyStress()}}));
1558 CHKERR post_proc.setTagsToTransfer({block_id_tag});
1559
1561 CHKERR post_proc.writeFile(
"out.h5m");
1562 elastic_energy = 0;
1564 &elastic_energy_fe);
1565 double global_elastic_energy = 0;
1566 CHKERR MPI_Allreduce(&elastic_energy, &global_elastic_energy, 1,
1567 MPI_DOUBLE, MPI_SUM, m_field.
get_comm());
1568 PetscPrintf(PETSC_COMM_WORLD, "Elastic energy %6.4e\n",
1569 global_elastic_energy);
1570 }
1571
1572 {
1576 if (is_curl) {
1578 {HCURL});
1579 post_proc_face.getOpPtrVector().push_back(
1581 } else {
1583 post_proc_face.getOpPtrVector().push_back(
1585 }
1586 post_proc_face.getOpPtrVector().push_back(
1588 post_proc_face.getMapGaussPts(), common_data));
1590 CHKERR post_proc_face.writeFile(
"out_tractions.h5m");
1591 }
1592
1593 CHKERR DMDestroy(&dm_control);
1594 }
1596
1598 return 0;
1599}
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
@ HCURL
field with continuous tangents
#define MYPCOMM_INDEX
default communicator number PCOMM
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MAT_ELASTICSET
block name is "MAT_ELASTIC"
@ MOFEM_STD_EXCEPTION_THROW
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
PetscErrorCode DMMoFEMCreateMoFEM(DM dm, MoFEM::Interface *m_field_ptr, const char problem_name[], const MoFEM::BitRefLevel bit_level, const MoFEM::BitRefLevel bit_mask=MoFEM::BitRefLevel().set())
Must be called by user to set MoFEM data structures.
PetscErrorCode DMoFEMPostProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
PetscErrorCode DMoFEMPreProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
virtual const Problem * get_problem(const std::string problem_name) const =0
Get the problem object.
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode add_ents_to_finite_element_by_type(const EntityHandle entities, const EntityType type, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
virtual MoFEMErrorCode add_ents_to_field_by_type(const Range &ents, const EntityType type, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
#define _IT_CUBITMESHSETS_BY_BCDATA_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet in a moFEM field.
#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 n
refractive index of diffusive medium
FTensor::Index< 'j', 3 > j
std::map< int, Range > ElasticBlockMap
const FTensor::Tensor2< T, Dim, Dim > Vec
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Calculate and assemble Z matrix.
Calculate and assemble Z matrix.
Calculate and assemble B matrix.
Calculate and assemble D matrix.
Calculate and assemble S matrix.
Calculate and assemble g vector.
Shave results on mesh tags for post-processing.
Add operators pushing bases from local to physical configuration.
Boundary condition manager for finite element problem setup.
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MoFEMErrorCode add_field(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_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Deprecated interface functions.
Class (Function) to enforce essential constrains on the left hand side diagonal.
Class (Function) to enforce essential constrains on the right hand side diagonal.
Class (Function) to enforce essential constrains.
default operator for Flat Prism element
static UId getLoLocalEntityBitNumber(const char bit_number, const EntityHandle ent)
static UId getHiLocalEntityBitNumber(const char bit_number, const EntityHandle ent)
Section manager is used to create indexes and sections.
Elastic material data structure.
Interface for managing meshsets containing materials and boundary conditions.
Calculate inverse of jacobian for face element.
Specialization for MatrixDouble vector field values calculation.
Post post-proc data at points from hash maps.
Transform local reference derivatives of shape functions to global derivatives.
keeps basic data about problem
MoFEMErrorCode getDofByNameEntAndEntDofIdx(const int field_bit_number, const EntityHandle ent, const int ent_dof_idx, const RowColData row_or_col, boost::shared_ptr< NumeredDofEntity > &dof_ptr) const
get DOFs from problem
boost::shared_ptr< SubProblemData > & getSubData() const
Get main problem of sub-problem is.
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredRowDofsPtr
store DOFs on rows for this problem
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.