453int main(
int argc,
char *argv[]) {
459 moab::Core mb_instance;
460 moab::Interface &moab = mb_instance;
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;
470 double eps_rho = 1e-3;
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",
"",
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,
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,
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);
499 if (flg_file != PETSC_TRUE) {
501 "*** ERROR -my_file (MESH FILE NEEDED)");
504 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
505 if (pcomm ==
nullptr)
506 pcomm =
new ParallelComm(&moab, PETSC_COMM_WORLD);
510 option =
"PARALLEL=READ_PART;"
511 "PARALLEL_RESOLVE_SHARED_ENTS;"
512 "PARTITION=PARALLEL_PARTITION;";
514 CHKERR moab.load_file(mesh_file_name, 0, option);
523 CHKERR mmanager_ptr->printDisplacementSet();
524 CHKERR mmanager_ptr->printForceSet();
526 CHKERR mmanager_ptr->printMaterialsSet();
533 CHKERR moab.get_entities_by_dimension(0, 3, ents3d);
535 ents3d, bit_level0,
false);
540 std::vector<Range> setOrderToEnts(10);
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;
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 ***");
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));
581 po::parsed_options parsed =
582 parse_config_file(ini_file, config_file_options,
true);
586 if (block_data[it->getMeshsetId()].oRder == -1)
588 if (block_data[it->getMeshsetId()].oRder ==
order)
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,
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(
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",
625 }
catch (
const std::exception &ex) {
626 std::ostringstream ss;
627 ss << ex.what() << std::endl;
630 if (read_eps_u > 0) {
633 if (read_eps_rho > 0) {
634 eps_rho = read_eps_rho;
636 if (read_eps_l > 0) {
641 PetscPrintf(PETSC_COMM_WORLD,
"epsU = %6.4e epsRho = %6.4e\n", eps_u,
661 CHKERR comm_interface_ptr->synchroniseFieldEntities(
"U");
662 CHKERR comm_interface_ptr->synchroniseFieldEntities(
"UPSILON");
663 CHKERR comm_interface_ptr->synchroniseFieldEntities(
"RHO");
667 Range ents_1st_layer;
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,
676 if (vertex_to_fix.size() != 1 && !vertex_to_fix.empty()) {
678 "Should be one vertex only, but is %zu", vertex_to_fix.size());
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;
686 if (mmanager_ptr->checkMeshset(101,
SIDESET)) {
688 ents_2nd_layer,
true);
690 CHKERR comm_interface_ptr->synchroniseEntities(ents_2nd_layer, 0);
692 for (
int oo = 2; oo != setOrderToEnts.size(); oo++) {
693 if (setOrderToEnts[oo].size() > 0) {
694 CHKERR comm_interface_ptr->synchroniseEntities(setOrderToEnts[oo], 0);
700 const int through_thickness_order = 2;
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);
711 CHKERR moab.get_entities_by_type(0, MBPRISM, prisms);
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);
727 prisms.merge(quads_edges);
731 ents = subtract(ents, set_order_ents);
732 ents = subtract(ents, prisms);
734 CHKERR comm_interface_ptr->synchroniseEntities(ents, 0);
735 CHKERR comm_interface_ptr->synchroniseEntities(prisms, 0);
742 through_thickness_order);
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);
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);
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);
787 CHKERR mmanager_ptr->setAttributesByDataStructure(
BLOCKSET, block_id,
795 for (
const auto &[
id, entities] : elastic_blocks)
802 double elastic_energy = 0;
803 auto elastic_rhs_common =
804 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
807 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
810 auto elastic_lhs_common =
811 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
814 CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
817 auto elastic_energy_common =
818 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
822 elastic_energy_common->getMatStrain(),
823 elastic_energy_common->getMatCauchyStress(), elastic_energy));
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");
841 block_it->second, MBPRISM,
"ELASTIC_PRISM");
843 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
849 auto prism_rhs_common =
850 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, FatPrismOp>(
853 CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, FatPrismOp>(
861 auto prism_lhs_common =
862 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, FatPrismOp>(
865 CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, FatPrismOp>(
895 "DISPLACEMENTS_PENALTY");
932 DMType dm_name =
"MOFEM";
938 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_control);
939 CHKERR DMSetType(dm_control, dm_name);
943 CHKERR DMSetFromOptions(dm_control);
954 CHKERR DMSetUp(dm_control);
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;
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;
981 DM dm_sub_volume_control;
983 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_volume_control);
984 CHKERR DMSetType(dm_sub_volume_control, dm_name);
995 CHKERR DMSetUp(dm_sub_volume_control);
999 boost::shared_ptr<Problem::SubProblemData> sub_data =
1002 CHKERR sub_data->getRowIs(&nested_is_rows[0]);
1003 CHKERR sub_data->getColIs(&nested_is_cols[0]);
1005 nested_matrices(0, 0) = PETSC_NULLPTR;
1009 DM dm_sub_sub_elastic;
1011 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_sub_elastic);
1012 CHKERR DMSetType(dm_sub_sub_elastic, dm_name);
1023 CHKERR DMSetUp(dm_sub_sub_elastic);
1025 ->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
"ELASTIC_PROB",
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);
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);
1063 dirichlet_bc_ptr->snes_ctx = FEMethod::CTX_SNESNONE;
1064 dirichlet_bc_ptr->ts_ctx = FEMethod::CTX_TSNONE;
1067 dirichlet_bc_ptr.get());
1073 fat_prism_rhs.
snes_f = Fu;
1079 elastic_lhs.
snes_B = Kuu;
1080 fat_prism_lhs.
snes_B = Kuu;
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);
1098 boost::shared_ptr<Problem::SubProblemData> sub_data =
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;
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);
1117 cerr <<
"Kuu" << endl;
1118 MatView(Kuu, PETSC_VIEWER_DRAW_WORLD);
1123 CHKERR DMDestroy(&dm_sub_sub_elastic);
1127 DM dm_sub_disp_penalty;
1130 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_disp_penalty);
1131 CHKERR DMSetType(dm_sub_disp_penalty, dm_name);
1141 CHKERR DMSetUp(dm_sub_disp_penalty);
1144 CHKERR DMCreateMatrix(dm_sub_disp_penalty, &S);
1145 CHKERR MatZeroEntries(S);
1151 "DISPLACEMENTS_PENALTY", &face_element);
1152 CHKERR MatAssemblyBegin(S, MAT_FLUSH_ASSEMBLY);
1153 CHKERR MatAssemblyEnd(S, MAT_FLUSH_ASSEMBLY);
1157 cerr <<
"S" << endl;
1158 MatView(S, PETSC_VIEWER_DRAW_WORLD);
1165 boost::shared_ptr<Problem::SubProblemData> sub_data =
1169 sub_nested_matrices(1, 0) = S;
1171 CHKERR DMDestroy(&dm_sub_disp_penalty);
1176 DM dm_sub_force_penalty;
1179 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_force_penalty);
1180 CHKERR DMSetType(dm_sub_force_penalty, dm_name);
1189 CHKERR DMSetUp(dm_sub_force_penalty);
1192 CHKERR DMCreateMatrix(dm_sub_force_penalty, &
D);
1211 CHKERR MatAssemblyBegin(
D, MAT_FINAL_ASSEMBLY);
1212 CHKERR MatAssemblyEnd(
D, MAT_FINAL_ASSEMBLY);
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;
1230 index_to_fix = dof_ptr->getPetscGlobalDofIdx();
1231 cerr << *dof_ptr << endl;
1235 CHKERR MatZeroRowsColumns(
D, nb_dofs_to_fix, &index_to_fix,
1236 eps_rho / eps_u, PETSC_NULLPTR,
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(
1248 bit_number, p_eit->second));
1249 for (; lo != hi; ++lo)
1251 dofs_to_fix.push_back((*lo)->getPetscGlobalDofIdx());
1253 CHKERR MatZeroRowsColumns(
D, dofs_to_fix.size(), &*dofs_to_fix.begin(),
1254 eps_rho / eps_u, PETSC_NULLPTR,
1260 cerr <<
"D" << endl;
1261 MatView(
D, PETSC_VIEWER_DRAW_WORLD);
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;
1272 CHKERR DMDestroy(&dm_sub_force_penalty);
1279 CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_force);
1280 CHKERR DMSetType(dm_sub_force, dm_name);
1289 CHKERR DMSetUp(dm_sub_force);
1292 CHKERR DMCreateMatrix(dm_sub_force, &UB);
1293 CHKERR MatZeroEntries(UB);
1295 CHKERR DMCreateMatrix(dm_sub_force, &UPSILONB);
1296 CHKERR MatZeroEntries(UPSILONB);
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);
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;
1336 index_to_fix = dof_ptr->getPetscGlobalDofIdx();
1337 cerr << *dof_ptr << endl;
1341 CHKERR MatZeroRows(UB, nb_dofs_to_fix, &index_to_fix, 0, PETSC_NULLPTR,
1343 CHKERR MatZeroRows(UPSILONB, nb_dofs_to_fix, &index_to_fix, 0,
1344 PETSC_NULLPTR, PETSC_NULLPTR);
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(
1355 bit_number, p_eit->second));
1356 for (; lo != hi; ++lo)
1358 dofs_to_fix.push_back((*lo)->getPetscGlobalDofIdx());
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);
1367 CHKERR MatTranspose(UB, MAT_INITIAL_MATRIX, &UBT);
1372 cerr <<
"UBT" << endl;
1373 MatView(UBT, PETSC_VIEWER_DRAW_WORLD);
1378 boost::shared_ptr<Problem::SubProblemData> sub_data =
1382 nested_matrices(0, 1) = UBT;
1385 cerr <<
"UPSILONB" << endl;
1386 MatView(UPSILONB, PETSC_VIEWER_DRAW_WORLD);
1393 nested_matrices(1, 0) = UPSILONB;
1395 CHKERR DMDestroy(&dm_sub_force);
1399 CHKERR MatCreateNest(PETSC_COMM_WORLD, 2, &sub_nested_is_rows[0], 2,
1400 &sub_nested_is_cols[0], &sub_nested_matrices(0, 0),
1402 nested_matrices(0, 0) = SubA;
1404 CHKERR MatAssemblyBegin(SubA, MAT_FINAL_ASSEMBLY);
1405 CHKERR MatAssemblyEnd(SubA, MAT_FINAL_ASSEMBLY);
1408 cerr <<
"Nested SubA" << endl;
1409 MatView(SubA, PETSC_VIEWER_STDOUT_WORLD);
1413 CHKERR MatCreateNest(PETSC_COMM_WORLD, 2, &nested_is_rows[0], 2,
1414 &nested_is_cols[0], &nested_matrices(0, 0), &
A);
1416 CHKERR MatAssemblyBegin(
A, MAT_FINAL_ASSEMBLY);
1417 CHKERR MatAssemblyEnd(
A, MAT_FINAL_ASSEMBLY);
1420 cerr <<
"Nested A" << endl;
1421 MatView(
A, PETSC_VIEWER_STDOUT_WORLD);
1425 CHKERR DMCreateGlobalVector(dm_control, &
D);
1426 CHKERR DMCreateGlobalVector(dm_control, &
F);
1438 CHKERR VecGhostUpdateBegin(
F, ADD_VALUES, SCATTER_REVERSE);
1439 CHKERR VecGhostUpdateEnd(
F, ADD_VALUES, SCATTER_REVERSE);
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);
1455 CHKERR KSPGetPC(solver, &pc);
1456 CHKERR PCSetType(pc, PCFIELDSPLIT);
1457 PetscBool is_pcfs = PETSC_FALSE;
1458 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
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);
1467 CHKERR PCFieldSplitGetSubKSP(pc, &
n, &sub_ksp);
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);
1479 CHKERR PCSetUp(sub_pc_0);
1483 "This solver requires the PCFIELDSPLIT preconditioner");
1491 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1492 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1497 CHKERR VecView(
D, PETSC_VIEWER_DRAW_WORLD);
1503 for (
int i = 0;
i != 2;
i++) {
1504 if (sub_nested_is_rows[
i]) {
1505 CHKERR ISDestroy(&sub_nested_is_rows[
i]);
1507 if (sub_nested_is_cols[
i]) {
1508 CHKERR ISDestroy(&sub_nested_is_cols[
i]);
1510 for (
int j = 0;
j != 2;
j++) {
1511 if (sub_nested_matrices(
i,
j)) {
1512 CHKERR MatDestroy(&sub_nested_matrices(
i,
j));
1516 for (
int i = 0;
i != 2;
i++) {
1517 if (nested_is_rows[
i]) {
1518 CHKERR ISDestroy(&nested_is_rows[
i]);
1520 if (nested_is_cols[
i]) {
1521 CHKERR ISDestroy(&nested_is_cols[
i]);
1523 for (
int j = 0;
j != 2;
j++) {
1524 if (nested_matrices(
i,
j)) {
1525 CHKERR MatDestroy(&nested_matrices(
i,
j));
1530 CHKERR MatDestroy(&SubA);
1535 CHKERR DMDestroy(&dm_sub_volume_control);
1537 using PostProcVolume =
1541 PostProcVolume post_proc(m_field,
"my");
1545 auto u_ptr = boost::make_shared<MatrixDouble>();
1546 post_proc.getOpPtrVector().push_back(
1549 HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
1550 m_field, post_proc.getOpPtrVector(),
"U",
"MAT_ELASTIC",
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});
1561 CHKERR post_proc.writeFile(
"out.h5m");
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);
1593 CHKERR DMDestroy(&dm_control);