482int main(
int argc,
char *argv[]) {
488 moab::Core mb_instance;
489 moab::Interface &moab = mb_instance;
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;
499 double eps_rho = 1e-3;
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",
"",
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,
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);
525 if (flg_file != PETSC_TRUE) {
527 "*** ERROR -my_file (MESH FILE NEEDED)");
530 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
531 if (pcomm ==
nullptr)
532 pcomm =
new ParallelComm(&moab, PETSC_COMM_WORLD);
536 option =
"PARALLEL=READ_PART;"
537 "PARALLEL_RESOLVE_SHARED_ENTS;"
538 "PARTITION=PARALLEL_PARTITION;";
540 CHKERR moab.load_file(mesh_file_name, 0, option);
549 CHKERR mmanager_ptr->printDisplacementSet();
550 CHKERR mmanager_ptr->printForceSet();
552 CHKERR mmanager_ptr->printMaterialsSet();
559 CHKERR moab.get_entities_by_dimension(0, 3, ents3d);
561 ents3d, bit_level0,
false);
566 std::vector<Range> setOrderToEnts(10);
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;
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 ***");
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));
607 po::parsed_options parsed =
608 parse_config_file(ini_file, config_file_options,
true);
612 if (block_data[it->getMeshsetId()].oRder == -1)
614 if (block_data[it->getMeshsetId()].oRder ==
order)
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,
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(
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",
651 }
catch (
const std::exception &ex) {
652 std::ostringstream ss;
653 ss << ex.what() << std::endl;
656 if (read_eps_u > 0) {
659 if (read_eps_rho > 0) {
660 eps_rho = read_eps_rho;
662 if (read_eps_l > 0) {
667 PetscPrintf(PETSC_COMM_WORLD,
"epsU = %6.4e epsRho = %6.4e\n", eps_u,
687 CHKERR comm_interface_ptr->synchroniseFieldEntities(
"U");
688 CHKERR comm_interface_ptr->synchroniseFieldEntities(
"UPSILON");
689 CHKERR comm_interface_ptr->synchroniseFieldEntities(
"RHO");
693 Range ents_1st_layer;
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,
702 if (vertex_to_fix.size() != 1 && !vertex_to_fix.empty()) {
704 "Should be one vertex only, but is %zu", vertex_to_fix.size());
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;
712 if (mmanager_ptr->checkMeshset(101,
SIDESET)) {
714 ents_2nd_layer,
true);
716 CHKERR comm_interface_ptr->synchroniseEntities(ents_2nd_layer, 0);
718 for (
int oo = 2; oo != setOrderToEnts.size(); oo++) {
719 if (setOrderToEnts[oo].size() > 0) {
720 CHKERR comm_interface_ptr->synchroniseEntities(setOrderToEnts[oo], 0);
726 const int through_thickness_order = 2;
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);
737 CHKERR moab.get_entities_by_type(0, MBPRISM, prisms);
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);
753 prisms.merge(quads_edges);
757 ents = subtract(ents, set_order_ents);
758 ents = subtract(ents, prisms);
760 CHKERR comm_interface_ptr->synchroniseEntities(ents, 0);
761 CHKERR comm_interface_ptr->synchroniseEntities(prisms, 0);
768 through_thickness_order);
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);
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);
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);
813 CHKERR mmanager_ptr->setAttributesByDataStructure(
BLOCKSET, block_id,
821 for (
const auto &[
id, entities] : elastic_blocks)
828 double elastic_energy = 0;
829 auto elastic_rhs_common =
830 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
833 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
836 auto elastic_lhs_common =
837 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
840 CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
843 auto elastic_energy_common =
844 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
848 elastic_energy_common->getMatStrain(),
849 elastic_energy_common->getMatCauchyStress(), elastic_energy));
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");
867 block_it->second, MBPRISM,
"ELASTIC_PRISM");
869 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
875 auto prism_rhs_common =
876 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, FatPrismOp>(
879 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, FatPrismOp>(
887 auto prism_lhs_common =
888 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, FatPrismOp>(
891 CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, FatPrismOp>(
921 "DISPLACEMENTS_PENALTY");
958 DMType dm_name =
"MOFEM";
964 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_control);
965 CHKERR DMSetType(dm_control, dm_name);
969 CHKERR DMSetFromOptions(dm_control);
980 CHKERR DMSetUp(dm_control);
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;
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;
1007 DM dm_sub_volume_control;
1009 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_volume_control);
1010 CHKERR DMSetType(dm_sub_volume_control, dm_name);
1014 "SUB_CONTROL_PROB");
1021 CHKERR DMSetUp(dm_sub_volume_control);
1025 boost::shared_ptr<Problem::SubProblemData> sub_data =
1028 CHKERR sub_data->getRowIs(&nested_is_rows[0]);
1029 CHKERR sub_data->getColIs(&nested_is_cols[0]);
1031 nested_matrices(0, 0) = PETSC_NULLPTR;
1035 DM dm_sub_sub_elastic;
1037 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_sub_elastic);
1038 CHKERR DMSetType(dm_sub_sub_elastic, dm_name);
1049 CHKERR DMSetUp(dm_sub_sub_elastic);
1051 ->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
"ELASTIC_PROB",
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);
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);
1089 dirichlet_bc_ptr->snes_ctx = FEMethod::CTX_SNESNONE;
1090 dirichlet_bc_ptr->ts_ctx = FEMethod::CTX_TSNONE;
1093 dirichlet_bc_ptr.get());
1099 fat_prism_rhs.
snes_f = Fu;
1105 elastic_lhs.
snes_B = Kuu;
1106 fat_prism_lhs.
snes_B = Kuu;
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);
1124 boost::shared_ptr<Problem::SubProblemData> sub_data =
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;
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);
1143 cerr <<
"Kuu" << endl;
1144 MatView(Kuu, PETSC_VIEWER_DRAW_WORLD);
1149 CHKERR DMDestroy(&dm_sub_sub_elastic);
1153 DM dm_sub_disp_penalty;
1156 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_disp_penalty);
1157 CHKERR DMSetType(dm_sub_disp_penalty, dm_name);
1167 CHKERR DMSetUp(dm_sub_disp_penalty);
1170 CHKERR DMCreateMatrix(dm_sub_disp_penalty, &S);
1171 CHKERR MatZeroEntries(S);
1177 "DISPLACEMENTS_PENALTY", &face_element);
1178 CHKERR MatAssemblyBegin(S, MAT_FLUSH_ASSEMBLY);
1179 CHKERR MatAssemblyEnd(S, MAT_FLUSH_ASSEMBLY);
1183 cerr <<
"S" << endl;
1184 MatView(S, PETSC_VIEWER_DRAW_WORLD);
1191 boost::shared_ptr<Problem::SubProblemData> sub_data =
1195 sub_nested_matrices(1, 0) = S;
1197 CHKERR DMDestroy(&dm_sub_disp_penalty);
1202 DM dm_sub_force_penalty;
1205 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_force_penalty);
1206 CHKERR DMSetType(dm_sub_force_penalty, dm_name);
1215 CHKERR DMSetUp(dm_sub_force_penalty);
1218 CHKERR DMCreateMatrix(dm_sub_force_penalty, &
D);
1237 CHKERR MatAssemblyBegin(
D, MAT_FINAL_ASSEMBLY);
1238 CHKERR MatAssemblyEnd(
D, MAT_FINAL_ASSEMBLY);
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;
1256 index_to_fix = dof_ptr->getPetscGlobalDofIdx();
1257 cerr << *dof_ptr << endl;
1261 CHKERR MatZeroRowsColumns(
D, nb_dofs_to_fix, &index_to_fix,
1262 eps_rho / eps_u, PETSC_NULLPTR,
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(
1274 bit_number, p_eit->second));
1275 for (; lo != hi; ++lo)
1277 dofs_to_fix.push_back((*lo)->getPetscGlobalDofIdx());
1279 CHKERR MatZeroRowsColumns(
D, dofs_to_fix.size(), &*dofs_to_fix.begin(),
1280 eps_rho / eps_u, PETSC_NULLPTR,
1286 cerr <<
"D" << endl;
1287 MatView(
D, PETSC_VIEWER_DRAW_WORLD);
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;
1298 CHKERR DMDestroy(&dm_sub_force_penalty);
1305 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_force);
1306 CHKERR DMSetType(dm_sub_force, dm_name);
1315 CHKERR DMSetUp(dm_sub_force);
1318 CHKERR DMCreateMatrix(dm_sub_force, &UB);
1319 CHKERR MatZeroEntries(UB);
1321 CHKERR DMCreateMatrix(dm_sub_force, &UPSILONB);
1322 CHKERR MatZeroEntries(UPSILONB);
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);
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;
1362 index_to_fix = dof_ptr->getPetscGlobalDofIdx();
1363 cerr << *dof_ptr << endl;
1367 CHKERR MatZeroRows(UB, nb_dofs_to_fix, &index_to_fix, 0, PETSC_NULLPTR,
1369 CHKERR MatZeroRows(UPSILONB, nb_dofs_to_fix, &index_to_fix, 0,
1370 PETSC_NULLPTR, PETSC_NULLPTR);
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(
1381 bit_number, p_eit->second));
1382 for (; lo != hi; ++lo)
1384 dofs_to_fix.push_back((*lo)->getPetscGlobalDofIdx());
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);
1393 CHKERR MatTranspose(UB, MAT_INITIAL_MATRIX, &UBT);
1398 cerr <<
"UBT" << endl;
1399 MatView(UBT, PETSC_VIEWER_DRAW_WORLD);
1404 boost::shared_ptr<Problem::SubProblemData> sub_data =
1408 nested_matrices(0, 1) = UBT;
1411 cerr <<
"UPSILONB" << endl;
1412 MatView(UPSILONB, PETSC_VIEWER_DRAW_WORLD);
1419 nested_matrices(1, 0) = UPSILONB;
1421 CHKERR DMDestroy(&dm_sub_force);
1425 CHKERR MatCreateNest(PETSC_COMM_WORLD, 2, &sub_nested_is_rows[0], 2,
1426 &sub_nested_is_cols[0], &sub_nested_matrices(0, 0),
1428 nested_matrices(0, 0) = SubA;
1430 CHKERR MatAssemblyBegin(SubA, MAT_FINAL_ASSEMBLY);
1431 CHKERR MatAssemblyEnd(SubA, MAT_FINAL_ASSEMBLY);
1434 cerr <<
"Nested SubA" << endl;
1435 MatView(SubA, PETSC_VIEWER_STDOUT_WORLD);
1439 CHKERR MatCreateNest(PETSC_COMM_WORLD, 2, &nested_is_rows[0], 2,
1440 &nested_is_cols[0], &nested_matrices(0, 0), &
A);
1442 CHKERR MatAssemblyBegin(
A, MAT_FINAL_ASSEMBLY);
1443 CHKERR MatAssemblyEnd(
A, MAT_FINAL_ASSEMBLY);
1446 cerr <<
"Nested A" << endl;
1447 MatView(
A, PETSC_VIEWER_STDOUT_WORLD);
1451 CHKERR DMCreateGlobalVector(dm_control, &
D);
1452 CHKERR DMCreateGlobalVector(dm_control, &
F);
1464 CHKERR VecGhostUpdateBegin(
F, ADD_VALUES, SCATTER_REVERSE);
1465 CHKERR VecGhostUpdateEnd(
F, ADD_VALUES, SCATTER_REVERSE);
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);
1481 CHKERR KSPGetPC(solver, &pc);
1482 CHKERR PCSetType(pc, PCFIELDSPLIT);
1483 PetscBool is_pcfs = PETSC_FALSE;
1484 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
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);
1493 CHKERR PCFieldSplitGetSubKSP(pc, &
n, &sub_ksp);
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);
1505 CHKERR PCSetUp(sub_pc_0);
1509 "Only works with pre-conditioner PCFIELDSPLIT");
1517 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1518 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1523 CHKERR VecView(
D, PETSC_VIEWER_DRAW_WORLD);
1529 for (
int i = 0;
i != 2;
i++) {
1530 if (sub_nested_is_rows[
i]) {
1531 CHKERR ISDestroy(&sub_nested_is_rows[
i]);
1533 if (sub_nested_is_cols[
i]) {
1534 CHKERR ISDestroy(&sub_nested_is_cols[
i]);
1536 for (
int j = 0;
j != 2;
j++) {
1537 if (sub_nested_matrices(
i,
j)) {
1538 CHKERR MatDestroy(&sub_nested_matrices(
i,
j));
1542 for (
int i = 0;
i != 2;
i++) {
1543 if (nested_is_rows[
i]) {
1544 CHKERR ISDestroy(&nested_is_rows[
i]);
1546 if (nested_is_cols[
i]) {
1547 CHKERR ISDestroy(&nested_is_cols[
i]);
1549 for (
int j = 0;
j != 2;
j++) {
1550 if (nested_matrices(
i,
j)) {
1551 CHKERR MatDestroy(&nested_matrices(
i,
j));
1556 CHKERR MatDestroy(&SubA);
1561 CHKERR DMDestroy(&dm_sub_volume_control);
1563 using PostProcVolume =
1567 PostProcVolume post_proc(m_field,
"my");
1571 auto u_ptr = boost::make_shared<MatrixDouble>();
1572 post_proc.getOpPtrVector().push_back(
1575 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
1576 m_field, post_proc.getOpPtrVector(),
"U",
"MAT_ELASTIC",
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});
1587 CHKERR post_proc.writeFile(
"out.h5m");
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);
1619 CHKERR DMDestroy(&dm_control);