482 {
483
485
486 try {
487
488 moab::Core mb_instance;
489 moab::Interface &moab = mb_instance;
490
491 PetscBool flg_block_config, flg_file;
492 char mesh_file_name[255];
493 char block_config_file[255];
494 PetscBool flg_order_force;
496 PetscInt order_force = 2;
497 PetscBool flg_eps_u, flg_eps_rho, flg_eps_l;
498 double eps_u = 1e-6;
499 double eps_rho = 1e-3;
500 double eps_l = 0;
501 PetscBool is_curl = PETSC_TRUE;
502 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Elastic Config", "none");
503 CHKERR PetscOptionsString(
"-my_file",
"mesh file name",
"",
"mesh.h5m",
504 mesh_file_name, 255, &flg_file);
505 CHKERR PetscOptionsInt(
"-my_order",
"default approximation order",
"",
508 "-my_order_force",
509 "default approximation order for force approximation", "", order_force,
510 &order_force, &flg_order_force);
511 CHKERR PetscOptionsString(
"-my_block_config",
"elastic configure file name",
512 "", "block_conf.in", block_config_file, 255,
513 &flg_block_config);
514 CHKERR PetscOptionsReal(
"-my_eps_rho",
"foce optimality parameter ",
"",
515 eps_rho, &eps_rho, &flg_eps_rho);
516 CHKERR PetscOptionsReal(
"-my_eps_u",
"displacement optimality parameter ",
517 "", eps_u, &eps_u, &flg_eps_u);
518 CHKERR PetscOptionsReal(
"-my_eps_l",
"displacement optimality parameter ",
519 "", eps_l, &eps_l, &flg_eps_l);
520 CHKERR PetscOptionsBool(
"-my_curl",
"use Hcurl space to approximate forces",
521 "", is_curl, &is_curl, PETSC_NULLPTR);
522 PetscOptionsEnd();
523
524
525 if (flg_file != PETSC_TRUE) {
527 "*** ERROR -my_file (MESH FILE NEEDED)");
528 }
529
530 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
531 if (pcomm == nullptr)
532 pcomm = new ParallelComm(&moab, PETSC_COMM_WORLD);
533
534
535 const char *option;
536 option = "PARALLEL=READ_PART;"
537 "PARALLEL_RESOLVE_SHARED_ENTS;"
538 "PARTITION=PARALLEL_PARTITION;";
539
540 CHKERR moab.load_file(mesh_file_name, 0, option);
541
542
545
548
549 CHKERR mmanager_ptr->printDisplacementSet();
550 CHKERR mmanager_ptr->printForceSet();
551
552 CHKERR mmanager_ptr->printMaterialsSet();
553
554
556 bit_level0.set(0);
557 {
559 CHKERR moab.get_entities_by_dimension(0, 3, ents3d);
561 ents3d, bit_level0, false);
562 }
563
564
565
566 std::vector<Range> setOrderToEnts(10);
567
568
569
570 Range set_order_ents;
571 std::map<int, BlockOptionData> block_data;
572 if (flg_block_config) {
573 double read_eps_u, read_eps_rho, read_eps_l;
574 try {
575 ifstream ini_file(block_config_file);
576 if (!ini_file.is_open()) {
577 SETERRQ(PETSC_COMM_SELF, 1,
578 "*** -my_block_config does not exist ***");
579 }
580
581 po::variables_map vm;
582 po::options_description config_file_options;
583 config_file_options.add_options()(
584 "eps_u", po::value<double>(&read_eps_u)->default_value(-1))(
585 "eps_rho", po::value<double>(&read_eps_rho)->default_value(-1))(
586 "eps_l", po::value<double>(&read_eps_l)->default_value(-1));
588 std::ostringstream str_order;
589 str_order << "block_" << it->getMeshsetId() << ".displacement_order";
590 config_file_options.add_options()(
591 str_order.str().c_str(),
592 po::value<int>(&block_data[it->getMeshsetId()].oRder)
593 ->default_value(
order));
594 std::ostringstream str_cond;
595 str_cond << "block_" << it->getMeshsetId() << ".young_modulus";
596 config_file_options.add_options()(
597 str_cond.str().c_str(),
598 po::value<double>(&block_data[it->getMeshsetId()].yOung)
599 ->default_value(-1));
600 std::ostringstream str_capa;
601 str_capa << "block_" << it->getMeshsetId() << ".poisson_ratio";
602 config_file_options.add_options()(
603 str_capa.str().c_str(),
604 po::value<double>(&block_data[it->getMeshsetId()].pOisson)
605 ->default_value(-2));
606 }
607 po::parsed_options parsed =
608 parse_config_file(ini_file, config_file_options, true);
609 store(parsed, vm);
610 po::notify(vm);
612 if (block_data[it->getMeshsetId()].oRder == -1)
613 continue;
614 if (block_data[it->getMeshsetId()].oRder ==
order)
615 continue;
616 PetscPrintf(PETSC_COMM_WORLD, "Set block %d order to %d\n",
617 it->getMeshsetId(), block_data[it->getMeshsetId()].oRder);
619 CHKERR moab.get_entities_by_handle(it->getMeshset(), block_ents,
620 true);
621
623 CHKERR moab.get_connectivity(block_ents, nodes,
true);
624 Range ents_to_set_order, ents3d;
625 CHKERR moab.get_adjacencies(nodes, 3,
false, ents3d,
626 moab::Interface::UNION);
627 CHKERR moab.get_adjacencies(ents3d, 2,
false, ents_to_set_order,
628 moab::Interface::UNION);
629 CHKERR moab.get_adjacencies(ents3d, 1,
false, ents_to_set_order,
630 moab::Interface::UNION);
631 ents_to_set_order = subtract(
632 ents_to_set_order, ents_to_set_order.subset_by_type(MBQUAD));
633 ents_to_set_order = subtract(
634 ents_to_set_order, ents_to_set_order.subset_by_type(MBPRISM));
635 set_order_ents.merge(ents3d);
636 set_order_ents.merge(ents_to_set_order);
637 setOrderToEnts[block_data[it->getMeshsetId()].oRder].merge(
638 set_order_ents);
639 }
640 CHKERR comm_interface_ptr->synchroniseEntities(set_order_ents, 0);
641 std::vector<std::string> additional_parameters;
642 additional_parameters =
643 collect_unrecognized(parsed.options, po::include_positional);
644 for (std::vector<std::string>::iterator vit =
645 additional_parameters.begin();
646 vit != additional_parameters.end(); vit++) {
647 CHKERR PetscPrintf(PETSC_COMM_WORLD,
648 "** WARNING Unrecognized option %s\n",
649 vit->c_str());
650 }
651 } catch (const std::exception &ex) {
652 std::ostringstream ss;
653 ss << ex.what() << std::endl;
655 }
656 if (read_eps_u > 0) {
657 eps_u = read_eps_u;
658 };
659 if (read_eps_rho > 0) {
660 eps_rho = read_eps_rho;
661 }
662 if (read_eps_l > 0) {
663 eps_l = read_eps_l;
664 }
665 }
666
667 PetscPrintf(PETSC_COMM_WORLD, "epsU = %6.4e epsRho = %6.4e\n", eps_u,
668 eps_rho);
669
670
675 if (is_curl) {
677 } else {
679 }
680
681
686
687 CHKERR comm_interface_ptr->synchroniseFieldEntities(
"U");
688 CHKERR comm_interface_ptr->synchroniseFieldEntities(
"UPSILON");
689 CHKERR comm_interface_ptr->synchroniseFieldEntities(
"RHO");
690
693 Range ents_1st_layer;
694
695 if (mmanager_ptr->checkMeshset(202,
SIDESET)) {
697 ents_1st_layer, true);
699 vertex_to_fix, false);
700 CHKERR mmanager_ptr->getEntitiesByDimension(202,
SIDESET, 1, edges_to_fix,
701 false);
702 if (vertex_to_fix.size() != 1 && !vertex_to_fix.empty()) {
704 "Should be one vertex only, but is %zu", vertex_to_fix.size());
705 }
706 }
707 CHKERR comm_interface_ptr->synchroniseEntities(ents_1st_layer, 0);
709 ents_1st_layer.subset_by_type(MBTRI), MBTRI, "RHO");
710 Range ents_2nd_layer;
711
712 if (mmanager_ptr->checkMeshset(101,
SIDESET)) {
714 ents_2nd_layer, true);
715 }
716 CHKERR comm_interface_ptr->synchroniseEntities(ents_2nd_layer, 0);
717
718 for (int oo = 2; oo != setOrderToEnts.size(); oo++) {
719 if (setOrderToEnts[oo].size() > 0) {
720 CHKERR comm_interface_ptr->synchroniseEntities(setOrderToEnts[oo], 0);
723 }
724 }
725
726 const int through_thickness_order = 2;
727 {
729 CHKERR moab.get_entities_by_dimension(0, 3, ents3d);
731 CHKERR moab.get_adjacencies(ents3d, 2,
false, ents,
732 moab::Interface::UNION);
733 CHKERR moab.get_adjacencies(ents3d, 1,
false, ents,
734 moab::Interface::UNION);
735
737 CHKERR moab.get_entities_by_type(0, MBPRISM, prisms);
738 {
740 CHKERR moab.get_adjacencies(prisms, 2,
false, quads,
741 moab::Interface::UNION);
743 prism_tris = quads.subset_by_type(MBTRI);
744 quads = subtract(quads, prism_tris);
746 CHKERR moab.get_adjacencies(quads, 1,
false, quads_edges,
747 moab::Interface::UNION);
748 Range prism_tris_edges;
749 CHKERR moab.get_adjacencies(prism_tris, 1,
false, prism_tris_edges,
750 moab::Interface::UNION);
751 quads_edges = subtract(quads_edges, prism_tris_edges);
752 prisms.merge(quads);
753 prisms.merge(quads_edges);
754 }
755
756 ents.merge(ents3d);
757 ents = subtract(ents, set_order_ents);
758 ents = subtract(ents, prisms);
759
760 CHKERR comm_interface_ptr->synchroniseEntities(ents, 0);
761 CHKERR comm_interface_ptr->synchroniseEntities(prisms, 0);
762
765
768 through_thickness_order);
769 }
772
773 if (is_curl) {
776 } else {
780 }
781
782
783
785 int default_block_id = -1;
787 CHKERR moab.tag_get_handle(
"BLOCK_ID", 1, MB_TYPE_INTEGER, block_id_tag,
788 MB_TAG_CREAT | MB_TAG_SPARSE, &default_block_id);
792 CHKERR it->getAttributeDataStructure(material);
793 const int block_id = it->getMeshsetId();
794 CHKERR moab.get_entities_by_handle(it->getMeshset(),
795 elastic_blocks[block_id], true);
796 const auto block_elements =
797 elastic_blocks[block_id].subset_by_type(MBTET);
798 CHKERR moab.tag_clear_data(block_id_tag, block_elements, &block_id);
799
800 const auto options_it = block_data.find(block_id);
801 if (options_it != block_data.end() && options_it->second.yOung > 0) {
802 material.
data.Young = options_it->second.yOung;
803 CHKERR PetscPrintf(PETSC_COMM_WORLD,
804 "Block %d set Young modulus %3.4g\n", block_id,
805 material.
data.Young);
806 }
807 if (options_it != block_data.end() && options_it->second.pOisson >= -1) {
808 material.
data.Poisson = options_it->second.pOisson;
809 CHKERR PetscPrintf(PETSC_COMM_WORLD,
810 "Block %d set Poisson ratio %3.4g\n", block_id,
811 material.
data.Poisson);
812 }
813 CHKERR mmanager_ptr->setAttributesByDataStructure(
BLOCKSET, block_id,
814 material);
815 }
816
821 for (const auto &[id, entities] : elastic_blocks)
822 CHKERR m_field.add_ents_to_finite_element_by_type(entities, MBTET,
823 "ELASTIC");
824
828 double elastic_energy = 0;
829 auto elastic_rhs_common =
830 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
831 m_field, elastic_rhs.getOpPtrVector(), "U", "MAT_ELASTIC",
832 Sev::verbose);
833 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
834 m_field, elastic_rhs.getOpPtrVector(), "U", elastic_rhs_common,
835 Sev::verbose, true);
836 auto elastic_lhs_common =
837 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
838 m_field, elastic_lhs.getOpPtrVector(), "U", "MAT_ELASTIC",
839 Sev::verbose);
840 CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
841 m_field, elastic_lhs.getOpPtrVector(), "U", elastic_lhs_common,
842 Sev::verbose);
843 auto elastic_energy_common =
844 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
845 m_field, elastic_energy_fe.getOpPtrVector(), "U", "MAT_ELASTIC",
846 Sev::verbose);
848 elastic_energy_common->getMatStrain(),
849 elastic_energy_common->getMatCauchyStress(), elastic_energy));
850
851
854 {
859 auto block_it = elastic_blocks.find(2);
860 if (block_it == elastic_blocks.end()) {
862 "Elastic material block 2 is required for prism elements");
863 }
865 block_it->second);
867 block_it->second, MBPRISM, "ELASTIC_PRISM");
868
869 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
870 fat_prism_rhs.getOpPtrVector().push_back(
872 fat_prism_rhs.getOpPtrVector().push_back(
875 auto prism_rhs_common =
876 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, FatPrismOp>(
877 m_field, fat_prism_rhs.getOpPtrVector(), "U", "MAT_ELASTIC",
878 Sev::verbose);
879 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, FatPrismOp>(
880 m_field, fat_prism_rhs.getOpPtrVector(), "U", prism_rhs_common,
881 Sev::verbose, true);
882
883 fat_prism_lhs.getOpPtrVector().push_back(
885 fat_prism_lhs.getOpPtrVector().push_back(
887 auto prism_lhs_common =
888 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, FatPrismOp>(
889 m_field, fat_prism_lhs.getOpPtrVector(), "U", "MAT_ELASTIC",
890 Sev::verbose);
891 CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, FatPrismOp>(
892 m_field, fat_prism_lhs.getOpPtrVector(), "U", prism_lhs_common,
893 Sev::verbose);
894 }
895
896
898
899
906
909 "UPSILON");
911 "U");
913 "UPSILON");
915 "U");
917 "DISP_X");
919 "DISP_Y");
921 "DISPLACEMENTS_PENALTY");
922
923
932 "BT");
933
942 "B");
943
944
950 "D");
951
952
954
956
957
958 DMType dm_name = "MOFEM";
960
961 DM dm_control;
962 {
963
964 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_control);
965 CHKERR DMSetType(dm_control, dm_name);
966
968 bit_level0);
969 CHKERR DMSetFromOptions(dm_control);
972
980 CHKERR DMSetUp(dm_control);
981 }
982
984
985 ublas::matrix<Mat> nested_matrices(2, 2);
986 ublas::vector<IS> nested_is_rows(2);
987 ublas::vector<IS> nested_is_cols(2);
988 for (
int i = 0;
i != 2;
i++) {
989 nested_is_rows[
i] = PETSC_NULLPTR;
990 nested_is_cols[
i] = PETSC_NULLPTR;
991 for (
int j = 0;
j != 2;
j++) {
992 nested_matrices(
i,
j) = PETSC_NULLPTR;
993 }
994 }
995
996 ublas::matrix<Mat> sub_nested_matrices(2, 2);
997 ublas::vector<IS> sub_nested_is_rows(2);
998 ublas::vector<IS> sub_nested_is_cols(2);
999 for (
int i = 0;
i != 2;
i++) {
1000 sub_nested_is_rows[
i] = PETSC_NULLPTR;
1001 sub_nested_is_cols[
i] = PETSC_NULLPTR;
1002 for (
int j = 0;
j != 2;
j++) {
1003 sub_nested_matrices(
i,
j) = PETSC_NULLPTR;
1004 }
1005 }
1006
1007 DM dm_sub_volume_control;
1008 {
1009 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_volume_control);
1010 CHKERR DMSetType(dm_sub_volume_control, dm_name);
1011
1012
1014 "SUB_CONTROL_PROB");
1020
1021 CHKERR DMSetUp(dm_sub_volume_control);
1022
1025 boost::shared_ptr<Problem::SubProblemData> sub_data =
1027
1028 CHKERR sub_data->getRowIs(&nested_is_rows[0]);
1029 CHKERR sub_data->getColIs(&nested_is_cols[0]);
1030
1031 nested_matrices(0, 0) = PETSC_NULLPTR;
1032 }
1033
1034 {
1035 DM dm_sub_sub_elastic;
1036
1037 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_sub_elastic);
1038 CHKERR DMSetType(dm_sub_sub_elastic, dm_name);
1039
1040
1042 "ELASTIC_PROB");
1048
1049 CHKERR DMSetUp(dm_sub_sub_elastic);
1051 ->pushMarkDOFsOnEntities<DisplacementCubitBcData>("ELASTIC_PROB",
1052 "U");
1053
1054 Mat Kuu;
1056 CHKERR DMCreateMatrix(dm_sub_sub_elastic, &Kuu);
1057 CHKERR DMCreateGlobalVector(dm_sub_sub_elastic, &Du);
1058 CHKERR DMCreateGlobalVector(dm_sub_sub_elastic, &Fu);
1059 CHKERR MatZeroEntries(Kuu);
1060 CHKERR VecZeroEntries(Du);
1061 CHKERR VecZeroEntries(Fu);
1063 SCATTER_REVERSE);
1064
1065
1066 auto dirichlet_bc_ptr = boost::make_shared<FEMethod>();
1067 dirichlet_bc_ptr->vecAssembleSwitch =
1068 boost::movelib::make_unique<bool>(false);
1069 dirichlet_bc_ptr->matAssembleSwitch =
1070 boost::movelib::make_unique<bool>(false);
1071 dirichlet_bc_ptr->preProcessHook =
1073 m_field, dirichlet_bc_ptr,
1074 std::vector<boost::shared_ptr<ScalingMethod>>{}, false);
1075 dirichlet_bc_ptr->postProcessHook = [&]() {
1077 CHKERR VecGhostUpdateBegin(Fu, ADD_VALUES, SCATTER_REVERSE);
1078 CHKERR VecGhostUpdateEnd(Fu, ADD_VALUES, SCATTER_REVERSE);
1079 CHKERR VecAssemblyBegin(Fu);
1080 CHKERR VecAssemblyEnd(Fu);
1081 CHKERR MatAssemblyBegin(Kuu, MAT_FINAL_ASSEMBLY);
1082 CHKERR MatAssemblyEnd(Kuu, MAT_FINAL_ASSEMBLY);
1088 };
1089 dirichlet_bc_ptr->snes_ctx = FEMethod::CTX_SNESNONE;
1090 dirichlet_bc_ptr->ts_ctx = FEMethod::CTX_TSNONE;
1091
1093 dirichlet_bc_ptr.get());
1095 SCATTER_REVERSE);
1096
1097
1098 elastic_rhs.snes_f = Fu;
1099 fat_prism_rhs.snes_f = Fu;
1101 &elastic_rhs);
1103 &fat_prism_rhs);
1104
1105 elastic_lhs.snes_B = Kuu;
1106 fat_prism_lhs.snes_B = Kuu;
1108 &elastic_lhs);
1110 &fat_prism_lhs);
1111
1113 dirichlet_bc_ptr.get());
1114 CHKERR VecGhostUpdateBegin(Fu, ADD_VALUES, SCATTER_REVERSE);
1115 CHKERR VecGhostUpdateEnd(Fu, ADD_VALUES, SCATTER_REVERSE);
1116 CHKERR VecAssemblyBegin(Fu);
1117 CHKERR VecAssemblyEnd(Fu);
1121
1124 boost::shared_ptr<Problem::SubProblemData> sub_data =
1126
1127 CHKERR sub_data->getRowIs(&sub_nested_is_rows[0]);
1128 CHKERR sub_data->getColIs(&sub_nested_is_cols[0]);
1129 sub_nested_matrices(0, 0) = Kuu;
1130 IS isUpsilon;
1132 ->isCreateFromProblemFieldToOtherProblemField(
1133 "ELASTIC_PROB",
"U",
ROW,
"SUB_CONTROL_PROB",
"UPSILON",
ROW,
1134 PETSC_NULLPTR, &isUpsilon);
1135 sub_nested_is_rows[1] = isUpsilon;
1136 sub_nested_is_cols[1] = isUpsilon;
1137 sub_nested_matrices(1, 1) = Kuu;
1138 PetscObjectReference((PetscObject)Kuu);
1139 PetscObjectReference((PetscObject)isUpsilon);
1140
1141
1143 cerr << "Kuu" << endl;
1144 MatView(Kuu, PETSC_VIEWER_DRAW_WORLD);
1145 std::string wait;
1146 std::cin >> wait;
1147 }
1148
1149 CHKERR DMDestroy(&dm_sub_sub_elastic);
1150 }
1151
1152 {
1153 DM dm_sub_disp_penalty;
1154
1155
1156 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_disp_penalty);
1157 CHKERR DMSetType(dm_sub_disp_penalty, dm_name);
1158
1159
1161 "S_PROB");
1165
1167 CHKERR DMSetUp(dm_sub_disp_penalty);
1168
1169 Mat S;
1170 CHKERR DMCreateMatrix(dm_sub_disp_penalty, &S);
1171 CHKERR MatZeroEntries(S);
1172
1175 face_element.getOpPtrVector().push_back(
new OpCellS(S, eps_u));
1177 "DISPLACEMENTS_PENALTY", &face_element);
1178 CHKERR MatAssemblyBegin(S, MAT_FLUSH_ASSEMBLY);
1179 CHKERR MatAssemblyEnd(S, MAT_FLUSH_ASSEMBLY);
1180
1181
1183 cerr << "S" << endl;
1184 MatView(S, PETSC_VIEWER_DRAW_WORLD);
1185 std::string wait;
1186 std::cin >> wait;
1187 }
1188
1191 boost::shared_ptr<Problem::SubProblemData> sub_data =
1193
1194
1195 sub_nested_matrices(1, 0) = S;
1196
1197 CHKERR DMDestroy(&dm_sub_disp_penalty);
1198 }
1199
1200
1201 {
1202 DM dm_sub_force_penalty;
1203
1204
1205 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_force_penalty);
1206 CHKERR DMSetType(dm_sub_force_penalty, dm_name);
1207
1208
1213
1215 CHKERR DMSetUp(dm_sub_force_penalty);
1216
1218 CHKERR DMCreateMatrix(dm_sub_force_penalty, &
D);
1220
1221 {
1223
1224 if (is_curl) {
1226 {HCURL});
1227 face_d_matrix.getOpPtrVector().push_back(
1229 } else {
1231 face_d_matrix.getOpPtrVector().push_back(
1233 }
1235 &face_d_matrix);
1236 }
1237 CHKERR MatAssemblyBegin(
D, MAT_FINAL_ASSEMBLY);
1238 CHKERR MatAssemblyEnd(
D, MAT_FINAL_ASSEMBLY);
1239
1242
1243
1244
1245 if (is_curl == PETSC_FALSE) {
1246 int nb_dofs_to_fix = 0;
1247 int index_to_fix = 0;
1248 if (!vertex_to_fix.empty()) {
1249 boost::shared_ptr<NumeredDofEntity> dof_ptr;
1252 dof_ptr);
1253 if (dof_ptr) {
1255 nb_dofs_to_fix = 1;
1256 index_to_fix = dof_ptr->getPetscGlobalDofIdx();
1257 cerr << *dof_ptr << endl;
1258 }
1259 }
1260 }
1261 CHKERR MatZeroRowsColumns(
D, nb_dofs_to_fix, &index_to_fix,
1262 eps_rho / eps_u, PETSC_NULLPTR,
1263 PETSC_NULLPTR);
1264 } else {
1265 std::vector<int> dofs_to_fix;
1266 for (auto p_eit = edges_to_fix.pair_begin();
1267 p_eit != edges_to_fix.pair_end(); ++p_eit) {
1270 auto lo = row_dofs->lower_bound(
1272 auto hi =
1274 bit_number, p_eit->second));
1275 for (; lo != hi; ++lo)
1277 dofs_to_fix.push_back((*lo)->getPetscGlobalDofIdx());
1278 }
1279 CHKERR MatZeroRowsColumns(
D, dofs_to_fix.size(), &*dofs_to_fix.begin(),
1280 eps_rho / eps_u, PETSC_NULLPTR,
1281 PETSC_NULLPTR);
1282 }
1283
1284
1286 cerr << "D" << endl;
1287 MatView(
D, PETSC_VIEWER_DRAW_WORLD);
1288 std::string wait;
1289 std::cin >> wait;
1290 }
1291
1292 boost::shared_ptr<Problem::SubProblemData> sub_data =
1294 CHKERR sub_data->getRowIs(&nested_is_rows[1]);
1295 CHKERR sub_data->getColIs(&nested_is_cols[1]);
1296 nested_matrices(1, 1) =
D;
1297
1298 CHKERR DMDestroy(&dm_sub_force_penalty);
1299 }
1300
1301 {
1302 DM dm_sub_force;
1303
1304
1305 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_force);
1306 CHKERR DMSetType(dm_sub_force, dm_name);
1307
1313
1315 CHKERR DMSetUp(dm_sub_force);
1316
1317 Mat UB, UPSILONB;
1318 CHKERR DMCreateMatrix(dm_sub_force, &UB);
1319 CHKERR MatZeroEntries(UB);
1320
1321 CHKERR DMCreateMatrix(dm_sub_force, &UPSILONB);
1322 CHKERR MatZeroEntries(UPSILONB);
1323 {
1325 if (is_curl) {
1327 {H1, HCURL});
1328 face_b_matrices.getOpPtrVector().push_back(
new OpCellCurlB(UB,
"U"));
1329 face_b_matrices.getOpPtrVector().push_back(
1331 } else {
1333 {H1});
1334 face_b_matrices.getOpPtrVector().push_back(
1336 face_b_matrices.getOpPtrVector().push_back(
1338 }
1340 }
1341 CHKERR MatAssemblyBegin(UB, MAT_FINAL_ASSEMBLY);
1342 CHKERR MatAssemblyBegin(UPSILONB, MAT_FINAL_ASSEMBLY);
1343 CHKERR MatAssemblyEnd(UB, MAT_FINAL_ASSEMBLY);
1344 CHKERR MatAssemblyEnd(UPSILONB, MAT_FINAL_ASSEMBLY);
1345
1348
1349
1350
1351 if (is_curl == PETSC_FALSE) {
1352 int nb_dofs_to_fix = 0;
1353 int index_to_fix = 0;
1354 if (!vertex_to_fix.empty()) {
1355 boost::shared_ptr<NumeredDofEntity> dof_ptr;
1358 dof_ptr);
1359 if (dof_ptr) {
1361 nb_dofs_to_fix = 1;
1362 index_to_fix = dof_ptr->getPetscGlobalDofIdx();
1363 cerr << *dof_ptr << endl;
1364 }
1365 }
1366 }
1367 CHKERR MatZeroRows(UB, nb_dofs_to_fix, &index_to_fix, 0, PETSC_NULLPTR,
1368 PETSC_NULLPTR);
1369 CHKERR MatZeroRows(UPSILONB, nb_dofs_to_fix, &index_to_fix, 0,
1370 PETSC_NULLPTR, PETSC_NULLPTR);
1371 } else {
1372 std::vector<int> dofs_to_fix;
1373 for (auto p_eit = edges_to_fix.pair_begin();
1374 p_eit != edges_to_fix.pair_end(); ++p_eit) {
1377 auto lo = row_dofs->lower_bound(
1379 auto hi =
1381 bit_number, p_eit->second));
1382 for (; lo != hi; ++lo)
1384 dofs_to_fix.push_back((*lo)->getPetscGlobalDofIdx());
1385 }
1386 CHKERR MatZeroRows(UB, dofs_to_fix.size(), &*dofs_to_fix.begin(), 0,
1387 PETSC_NULLPTR, PETSC_NULLPTR);
1388 CHKERR MatZeroRows(UPSILONB, dofs_to_fix.size(), &*dofs_to_fix.begin(),
1389 0, PETSC_NULLPTR, PETSC_NULLPTR);
1390 }
1391
1392 Mat UBT;
1393 CHKERR MatTranspose(UB, MAT_INITIAL_MATRIX, &UBT);
1395
1396
1398 cerr << "UBT" << endl;
1399 MatView(UBT, PETSC_VIEWER_DRAW_WORLD);
1400 std::string wait;
1401 std::cin >> wait;
1402 }
1403
1404 boost::shared_ptr<Problem::SubProblemData> sub_data =
1406
1407
1408 nested_matrices(0, 1) = UBT;
1409
1411 cerr << "UPSILONB" << endl;
1412 MatView(UPSILONB, PETSC_VIEWER_DRAW_WORLD);
1413 std::string wait;
1414 std::cin >> wait;
1415 }
1416
1417
1418
1419 nested_matrices(1, 0) = UPSILONB;
1420
1421 CHKERR DMDestroy(&dm_sub_force);
1422 }
1423
1424 Mat SubA;
1425 CHKERR MatCreateNest(PETSC_COMM_WORLD, 2, &sub_nested_is_rows[0], 2,
1426 &sub_nested_is_cols[0], &sub_nested_matrices(0, 0),
1427 &SubA);
1428 nested_matrices(0, 0) = SubA;
1429
1430 CHKERR MatAssemblyBegin(SubA, MAT_FINAL_ASSEMBLY);
1431 CHKERR MatAssemblyEnd(SubA, MAT_FINAL_ASSEMBLY);
1432
1434 cerr << "Nested SubA" << endl;
1435 MatView(SubA, PETSC_VIEWER_STDOUT_WORLD);
1436 }
1437
1439 CHKERR MatCreateNest(PETSC_COMM_WORLD, 2, &nested_is_rows[0], 2,
1440 &nested_is_cols[0], &nested_matrices(0, 0), &A);
1441
1442 CHKERR MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY);
1443 CHKERR MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY);
1444
1446 cerr << "Nested A" << endl;
1447 MatView(A, PETSC_VIEWER_STDOUT_WORLD);
1448 }
1449
1451 CHKERR DMCreateGlobalVector(dm_control, &
D);
1452 CHKERR DMCreateGlobalVector(dm_control, &
F);
1453
1454
1455 {
1458 face_element.getOpPtrVector().push_back(
new OpGetDispX(common_data));
1459 face_element.getOpPtrVector().push_back(
new OpGetDispY(common_data));
1460 face_element.getOpPtrVector().push_back(
1463 &face_element);
1464 CHKERR VecGhostUpdateBegin(
F, ADD_VALUES, SCATTER_REVERSE);
1465 CHKERR VecGhostUpdateEnd(
F, ADD_VALUES, SCATTER_REVERSE);
1468 }
1469
1470 KSP solver;
1471
1472 {
1473 CHKERR KSPCreate(PETSC_COMM_WORLD, &solver);
1474 CHKERR KSPSetDM(solver, dm_control);
1475 CHKERR KSPSetFromOptions(solver);
1476 CHKERR KSPSetOperators(solver, A, A);
1477 CHKERR KSPSetDMActive(solver, PETSC_FALSE);
1478 CHKERR KSPSetInitialGuessKnoll(solver, PETSC_FALSE);
1479 CHKERR KSPSetInitialGuessNonzero(solver, PETSC_FALSE);
1480 PC pc;
1481 CHKERR KSPGetPC(solver, &pc);
1482 CHKERR PCSetType(pc, PCFIELDSPLIT);
1483 PetscBool is_pcfs = PETSC_FALSE;
1484 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
1485 if (is_pcfs) {
1486 CHKERR PCSetOperators(pc, A, A);
1487 CHKERR PCFieldSplitSetIS(pc, NULL, nested_is_rows[0]);
1488 CHKERR PCFieldSplitSetIS(pc, NULL, nested_is_rows[1]);
1489 CHKERR PCFieldSplitSetType(pc, PC_COMPOSITE_SCHUR);
1491 KSP *sub_ksp;
1493 CHKERR PCFieldSplitGetSubKSP(pc, &
n, &sub_ksp);
1494 {
1495 PC sub_pc_0;
1496 CHKERR KSPGetPC(sub_ksp[0], &sub_pc_0);
1497 CHKERR PCSetOperators(sub_pc_0, SubA, SubA);
1498 CHKERR PCSetType(sub_pc_0, PCFIELDSPLIT);
1499 CHKERR PCFieldSplitSetIS(sub_pc_0, NULL, sub_nested_is_rows[0]);
1500 CHKERR PCFieldSplitSetIS(sub_pc_0, NULL, sub_nested_is_rows[1]);
1501 CHKERR PCFieldSplitSetType(sub_pc_0, PC_COMPOSITE_MULTIPLICATIVE);
1502
1503
1504
1505 CHKERR PCSetUp(sub_pc_0);
1506 }
1507 } else {
1509 "Only works with pre-conditioner PCFIELDSPLIT");
1510 }
1512 }
1513
1514
1516
1517 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1518 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1520 SCATTER_REVERSE);
1521
1523 CHKERR VecView(
D, PETSC_VIEWER_DRAW_WORLD);
1524 std::string wait;
1525 std::cin >> wait;
1526 }
1527
1528
1529 for (
int i = 0;
i != 2;
i++) {
1530 if (sub_nested_is_rows[
i]) {
1531 CHKERR ISDestroy(&sub_nested_is_rows[
i]);
1532 }
1533 if (sub_nested_is_cols[
i]) {
1534 CHKERR ISDestroy(&sub_nested_is_cols[
i]);
1535 }
1536 for (
int j = 0;
j != 2;
j++) {
1537 if (sub_nested_matrices(
i,
j)) {
1538 CHKERR MatDestroy(&sub_nested_matrices(
i,
j));
1539 }
1540 }
1541 }
1542 for (
int i = 0;
i != 2;
i++) {
1543 if (nested_is_rows[
i]) {
1544 CHKERR ISDestroy(&nested_is_rows[
i]);
1545 }
1546 if (nested_is_cols[
i]) {
1547 CHKERR ISDestroy(&nested_is_cols[
i]);
1548 }
1549 for (
int j = 0;
j != 2;
j++) {
1550 if (nested_matrices(
i,
j)) {
1551 CHKERR MatDestroy(&nested_matrices(
i,
j));
1552 }
1553 }
1554 }
1555
1556 CHKERR MatDestroy(&SubA);
1560
1561 CHKERR DMDestroy(&dm_sub_volume_control);
1562
1563 using PostProcVolume =
1566
1567 PostProcVolume post_proc(m_field, "my");
1568 {
1570
1571 auto u_ptr = boost::make_shared<MatrixDouble>();
1572 post_proc.getOpPtrVector().push_back(
1574 auto hooke_common =
1575 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
1576 m_field, post_proc.getOpPtrVector(), "U", "MAT_ELASTIC",
1577 Sev::verbose);
1578 post_proc.getOpPtrVector().push_back(new OpPPVolume(
1579 post_proc.getPostProcMesh(), post_proc.getMapGaussPts(),
1580 OpPPVolume::DataMapVec{}, OpPPVolume::DataMapMat{{"U", u_ptr}},
1581 OpPPVolume::DataMapMat{{"U_GRAD", hooke_common->matGradPtr}},
1582 OpPPVolume::DataMapMat{
1583 {"STRESS", hooke_common->getMatCauchyStress()}}));
1584 CHKERR post_proc.setTagsToTransfer({block_id_tag});
1585
1587 CHKERR post_proc.writeFile(
"out.h5m");
1588 elastic_energy = 0;
1590 &elastic_energy_fe);
1591 double global_elastic_energy = 0;
1592 CHKERR MPI_Allreduce(&elastic_energy, &global_elastic_energy, 1,
1593 MPI_DOUBLE, MPI_SUM, m_field.
get_comm());
1594 PetscPrintf(PETSC_COMM_WORLD, "Elastic energy %6.4e\n",
1595 global_elastic_energy);
1596 }
1597
1598 {
1602 if (is_curl) {
1604 {HCURL});
1605 post_proc_face.getOpPtrVector().push_back(
1607 } else {
1609 post_proc_face.getOpPtrVector().push_back(
1611 }
1612 post_proc_face.getOpPtrVector().push_back(
1614 post_proc_face.getMapGaussPts(), common_data));
1616 CHKERR post_proc_face.writeFile(
"out_tractions.h5m");
1617 }
1618
1619 CHKERR DMDestroy(&dm_control);
1620 }
1622
1624 return 0;
1625}
#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.