842 auto set_section_monitor = [&](
auto solver) {
845 CHKERR TSGetSNES(solver, &snes);
846 CHKERR SNESMonitorSet(snes,
849 (
void *)(snes_ctx_ptr.get()),
nullptr);
853 auto create_post_process_elements = [&]() {
854 auto push_vol_ops = [
this](
auto &pip) {
856 pip, {
H1,
HDIV},
"GEOMETRY");
858 auto [common_plastic_ptr, common_hencky_ptr] =
859 PlasticOps::createCommonPlasticOps<SPACE_DIM, IT, DomainEleOp>(
860 mField,
"MAT_PLASTIC", pip,
"U",
"EP",
"TAU", 1., Sev::inform);
862 if (common_hencky_ptr) {
863 if (common_plastic_ptr->mGradPtr != common_hencky_ptr->matGradPtr)
867 return std::make_pair(common_plastic_ptr, common_hencky_ptr);
870 auto push_vol_post_proc_ops = [
this](
auto &pp_fe,
auto &&p) {
873 auto &pip = pp_fe->getOpPtrVector();
875 auto [common_plastic_ptr, common_hencky_ptr] = p;
879 auto x_ptr = boost::make_shared<MatrixDouble>();
882 auto u_ptr = boost::make_shared<MatrixDouble>();
891 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
894 common_plastic_ptr->getPlasticSurfacePtr()},
895 {
"PLASTIC_MULTIPLIER",
896 common_plastic_ptr->getPlasticTauPtr()}},
898 {{
"U", u_ptr}, {
"GEOMETRY", x_ptr}},
900 {{
"GRAD", common_hencky_ptr->matGradPtr},
901 {
"FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()}},
903 {{
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()},
904 {
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
905 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
917 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
920 common_plastic_ptr->getPlasticSurfacePtr()},
921 {
"PLASTIC_MULTIPLIER",
922 common_plastic_ptr->getPlasticTauPtr()}},
924 {{
"U", u_ptr}, {
"GEOMETRY", x_ptr}},
928 {{
"STRAIN", common_plastic_ptr->mStrainPtr},
929 {
"STRESS", common_plastic_ptr->mStressPtr},
930 {
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
931 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
941 PetscBool post_proc_vol;
942 PetscBool post_proc_skin;
945 post_proc_vol = PETSC_TRUE;
946 post_proc_skin = PETSC_FALSE;
948 post_proc_vol = PETSC_FALSE;
949 post_proc_skin = PETSC_TRUE;
954 &post_proc_skin, PETSC_NULLPTR);
956 auto vol_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops,
958 if (post_proc_vol == PETSC_FALSE)
959 return boost::shared_ptr<PostProcEle>();
960 auto pp_fe = boost::make_shared<PostProcEle>(mField);
962 push_vol_post_proc_ops(pp_fe, push_vol_ops(pp_fe->getOpPtrVector())),
963 "push_vol_post_proc_ops");
967 auto skin_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops,
969 if (post_proc_skin == PETSC_FALSE)
970 return boost::shared_ptr<SkinPostProcEle>();
973 auto pp_fe = boost::make_shared<SkinPostProcEle>(mField);
976 pp_fe->getOpPtrVector().push_back(op_side);
978 pp_fe, push_vol_ops(op_side->getOpPtrVector())),
979 "push_vol_post_proc_ops");
983 return std::make_pair(vol_post_proc(), skin_post_proc());
986 auto scatter_create = [&](
auto D,
auto coeff) {
988 CHKERR is_manager->isCreateProblemFieldAndRank(
simple->getProblemName(),
989 ROW,
"U", coeff, coeff, is);
991 CHKERR ISGetLocalSize(is, &loc_size);
993 CHKERR VecCreateMPI(mField.get_comm(), loc_size, PETSC_DETERMINE, &
v);
995 CHKERR VecScatterCreate(
D, is,
v, PETSC_NULLPTR, &scatter);
1000 boost::shared_ptr<SetPtsData> field_eval_data;
1001 boost::shared_ptr<MatrixDouble> u_field_ptr;
1003 std::array<double, 3> field_eval_coords{0.0, 0.0, 0.0};
1006 field_eval_coords.data(), &coords_dim,
1009 boost::shared_ptr<std::map<std::string, boost::shared_ptr<VectorDouble>>>
1010 scalar_field_ptrs = boost::make_shared<
1011 std::map<std::string, boost::shared_ptr<VectorDouble>>>();
1012 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
1013 vector_field_ptrs = boost::make_shared<
1014 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
1015 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
1016 sym_tensor_field_ptrs = boost::make_shared<
1017 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
1018 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
1019 tensor_field_ptrs = boost::make_shared<
1020 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
1023 auto u_field_ptr = boost::make_shared<MatrixDouble>();
1028 field_eval_data,
simple->getDomainFEName());
1030 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
1031 auto no_rule = [](
int,
int,
int) {
return -1; };
1032 auto field_eval_fe_ptr = field_eval_data->feMethodPtr;
1033 field_eval_fe_ptr->getRuleHook = no_rule;
1036 field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV},
"GEOMETRY");
1038 auto [common_plastic_ptr, common_hencky_ptr] =
1039 PlasticOps::createCommonPlasticOps<SPACE_DIM, IT, DomainEleOp>(
1040 mField,
"MAT_PLASTIC", field_eval_fe_ptr->getOpPtrVector(),
"U",
1041 "EP",
"TAU", 1., Sev::inform);
1043 field_eval_fe_ptr->getOpPtrVector().push_back(
1046 if ((common_plastic_ptr) && (common_hencky_ptr) && (scalar_field_ptrs)) {
1048 scalar_field_ptrs->insert(
1049 {
"PLASTIC_SURFACE", common_plastic_ptr->getPlasticSurfacePtr()});
1050 scalar_field_ptrs->insert(
1051 {
"PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()});
1052 vector_field_ptrs->insert({
"U", u_field_ptr});
1053 sym_tensor_field_ptrs->insert(
1054 {
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()});
1055 sym_tensor_field_ptrs->insert(
1056 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()});
1057 sym_tensor_field_ptrs->insert(
1058 {
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()});
1059 tensor_field_ptrs->insert({
"GRAD", common_hencky_ptr->matGradPtr});
1060 tensor_field_ptrs->insert(
1061 {
"FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()});
1063 scalar_field_ptrs->insert(
1064 {
"PLASTIC_SURFACE", common_plastic_ptr->getPlasticSurfacePtr()});
1065 scalar_field_ptrs->insert(
1066 {
"PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()});
1067 vector_field_ptrs->insert({
"U", u_field_ptr});
1068 sym_tensor_field_ptrs->insert(
1069 {
"STRAIN", common_plastic_ptr->mStrainPtr});
1070 sym_tensor_field_ptrs->insert(
1071 {
"STRESS", common_plastic_ptr->mStressPtr});
1072 sym_tensor_field_ptrs->insert(
1073 {
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()});
1074 sym_tensor_field_ptrs->insert(
1075 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()});
1080 auto test_monitor_ptr = boost::make_shared<FEMethod>();
1082 auto set_time_monitor = [&](
auto dm,
auto solver) {
1085 dm, create_post_process_elements(), uXScatter, uYScatter, uZScatter,
1086 field_eval_coords, field_eval_data, scalar_field_ptrs,
1087 vector_field_ptrs, sym_tensor_field_ptrs, tensor_field_ptrs));
1088 boost::shared_ptr<ForcesAndSourcesCore> null;
1090 test_monitor_ptr->postProcessHook = [&]() {
1093 if (
atom_test && fabs(test_monitor_ptr->ts_t - 0.5) < 1e-12 &&
1094 test_monitor_ptr->ts_step == 25) {
1096 if (scalar_field_ptrs->at(
"PLASTIC_MULTIPLIER")->size()) {
1099 MOFEM_LOG(
"PlasticSync", Sev::inform) <<
"Eval point tau: " << t_tau;
1101 if (
atom_test == 1 && fabs(t_tau - 0.688861) > 1e-5) {
1103 "atom test %d failed: wrong plastic multiplier value",
1108 if (vector_field_ptrs->at(
"U")->size1()) {
1111 getFTensor1FromMat<SPACE_DIM>(*vector_field_ptrs->at(
"U"));
1112 MOFEM_LOG(
"PlasticSync", Sev::inform) <<
"Eval point U: " << t_disp;
1114 if (
atom_test == 1 && fabs(t_disp(0) - 0.25 / 2.) > 1e-5 ||
1115 fabs(t_disp(1) + 0.0526736) > 1e-5) {
1117 "atom test %d failed: wrong displacement value",
1122 if (sym_tensor_field_ptrs->at(
"PLASTIC_STRAIN")->size1()) {
1123 auto t_plastic_strain = getFTensor2SymmetricFromMat<SPACE_DIM>(
1124 *sym_tensor_field_ptrs->at(
"PLASTIC_STRAIN"));
1126 <<
"Eval point EP: " << t_plastic_strain;
1129 fabs(t_plastic_strain(0, 0) - 0.221943) > 1e-5 ||
1130 fabs(t_plastic_strain(0, 1)) > 1e-5 ||
1131 fabs(t_plastic_strain(1, 1) + 0.110971) > 1e-5) {
1133 "atom test %d failed: wrong plastic strain value",
1138 if (tensor_field_ptrs->at(
"FIRST_PIOLA")->size1()) {
1139 auto t_piola_stress = getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(
1140 *tensor_field_ptrs->at(
"FIRST_PIOLA"));
1142 <<
"Eval point Piola stress: " << t_piola_stress;
1144 if (
atom_test == 1 && fabs((t_piola_stress(0, 0) - 198.775) /
1145 t_piola_stress(0, 0)) > 1e-5 ||
1146 fabs(t_piola_stress(0, 1)) + fabs(t_piola_stress(1, 0)) +
1147 fabs(t_piola_stress(1, 1)) >
1150 "atom test %d failed: wrong Piola stress value",
1161 monitor_ptr, null, test_monitor_ptr);
1166 auto set_schur_pc = [&](
auto solver,
1167 boost::shared_ptr<SetUpSchur> &schur_ptr) {
1170 auto name_prb =
simple->getProblemName();
1176 dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
1181 for (
auto f : {
"U"}) {
1193 dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
1199 for (
auto f : {
"SIGMA",
"EP",
"TAU"}) {
1204 for (
auto f : {
"EP",
"TAU"}) {
1214 if constexpr (
AT == AssemblyType::BLOCK_SCHUR) {
1223 auto get_nested_mat_data = [&](
auto schur_dm,
auto block_dm) {
1229 {simple->getDomainFEName(),
1245 {simple->getBoundaryFEName(),
1247 {{
"SIGMA",
"SIGMA"}, {
"U",
"SIGMA"}, {
"SIGMA",
"U"}
1257 {dm_schur, dm_block}, block_mat_data,
1259 {
"SIGMA",
"EP",
"TAU"}, {
nullptr,
nullptr,
nullptr}, true
1266 auto get_nested_mat_data = [&](
auto schur_dm,
auto block_dm) {
1267 auto block_mat_data =
1270 {{simple->getDomainFEName(),
1287 {dm_schur, dm_block}, block_mat_data,
1289 {
"EP",
"TAU"}, {
nullptr,
nullptr}, false
1296 auto nested_mat_data = get_nested_mat_data(dm_schur, dm_block);
1299 auto block_is =
getDMSubData(dm_block)->getSmartRowIs();
1300 auto ao_schur =
getDMSubData(dm_schur)->getSmartRowMap();
1306 CHKERR schur_ptr->setUp(solver);
1312 auto dm =
simple->getDM();
1315 CHKERR VecSetDM(
D, PETSC_NULLPTR);
1316 CHKERR VecSetDM(DD, PETSC_NULLPTR);
1317 uXScatter = scatter_create(
D, 0);
1318 uYScatter = scatter_create(
D, 1);
1320 uZScatter = scatter_create(
D, 2);
1322 auto create_solver = [pip_mng]() {
1324 return pip_mng->createTSIM();
1326 return pip_mng->createTSIM2();
1329 auto solver = create_solver();
1331 auto active_pre_lhs = []() {
1338 auto active_post_lhs = [&]() {
1340 auto get_iter = [&]() {
1345 "Can not get iter");
1349 auto iter = get_iter();
1352 std::array<int, 5> activity_data;
1353 std::fill(activity_data.begin(), activity_data.end(), 0);
1355 activity_data.data(), activity_data.size(), MPI_INT,
1356 MPI_SUM, mField.get_comm());
1358 int &active_points = activity_data[0];
1359 int &avtive_full_elems = activity_data[1];
1360 int &avtive_elems = activity_data[2];
1361 int &nb_points = activity_data[3];
1362 int &nb_elements = activity_data[4];
1366 double proc_nb_points =
1367 100 *
static_cast<double>(active_points) / nb_points;
1368 double proc_nb_active =
1369 100 *
static_cast<double>(avtive_elems) / nb_elements;
1370 double proc_nb_full_active = 100;
1372 proc_nb_full_active =
1373 100 *
static_cast<double>(avtive_full_elems) / avtive_elems;
1376 "Iter %d nb pts %d nb active pts %d (%3.3f\%) nb active "
1378 "(%3.3f\%) nb full active elems %d (%3.3f\%)",
1379 iter, nb_points, active_points, proc_nb_points,
1380 avtive_elems, proc_nb_active, avtive_full_elems,
1381 proc_nb_full_active, iter);
1388 auto add_active_dofs_elem = [&](
auto dm) {
1390 auto fe_pre_proc = boost::make_shared<FEMethod>();
1391 fe_pre_proc->preProcessHook = active_pre_lhs;
1392 auto fe_post_proc = boost::make_shared<FEMethod>();
1393 fe_post_proc->postProcessHook = active_post_lhs;
1395 ts_ctx_ptr->getPreProcessIJacobian().push_front(fe_pre_proc);
1396 ts_ctx_ptr->getPostProcessIJacobian().push_back(fe_post_proc);
1400 auto set_essential_bc = [&](
auto dm,
auto solver) {
1404 auto pre_proc_ptr = boost::make_shared<FEMethod>();
1405 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
1406 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
1408 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
1409 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
1410 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
1411 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
1414 auto disp_time_scale = boost::make_shared<TimeScale>();
1416 auto get_bc_hook_rhs = [&]() {
1418 mField, pre_proc_ptr, {disp_time_scale},
false);
1420 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
1422 auto waak_post_proc_rhs_ptr = boost::weak_ptr<FEMethod>(
1424 auto get_post_proc_hook_rhs = [
this, waak_post_proc_rhs_ptr]() {
1427 mField, waak_post_proc_rhs_ptr.lock(),
nullptr, Sev::verbose)();
1429 mField, waak_post_proc_rhs_ptr.lock(), 1.)();
1432 auto get_post_proc_hook_lhs = [&]() {
1434 mField, post_proc_lhs_ptr, 1.);
1437 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
1438 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
1445 CHKERR TSSetIJacobian(solver,
B,
B, PETSC_NULLPTR, PETSC_NULLPTR);
1447 CHKERR TSSetI2Jacobian(solver,
B,
B, PETSC_NULLPTR, PETSC_NULLPTR);
1450 CHKERR TSSetSolution(solver,
D);
1452 CHKERR TS2SetSolution(solver,
D, DD);
1454 CHKERR set_section_monitor(solver);
1455 CHKERR set_time_monitor(dm, solver);
1456 CHKERR TSSetFromOptions(solver);
1458 CHKERR add_active_dofs_elem(dm);
1459 boost::shared_ptr<SetUpSchur> schur_ptr;
1460 CHKERR set_schur_pc(solver, schur_ptr);
1461 CHKERR set_essential_bc(dm, solver);
1466 BOOST_LOG_SCOPED_THREAD_ATTR(
"Timeline", attrs::timer());
1467 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSetUp";
1469 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSetUp <= done";
1470 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSolve";
1471 CHKERR TSSolve(solver, NULL);
1472 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSolve <= done";
1474 if (mField.get_comm_rank() == 0) {
1477 "ts_manager_graph.dot");