12#ifndef EXECUTABLE_DIMENSION
13 #define EXECUTABLE_DIMENSION 3
48 IntegrationType::GAUSS;
65 std::max(
static_cast<double>(std::numeric_limits<float>::min_exponent10),
79 auto r = [&](
auto tau) {
82 constexpr double eps = 1e-12;
83 return std::max(r(tau),
eps * r(0));
89template <
typename T,
int DIM>
96 if (
C1_k < std::numeric_limits<double>::epsilon()) {
100 t_alpha(
i,
j) =
C1_k * t_plastic_strain(
i,
j);
149 #include <boost/python.hpp>
150 #include <boost/python/def.hpp>
151 #include <boost/python/numpy.hpp>
152namespace bp = boost::python;
153namespace np = boost::python::numpy;
180template <
int FE_DIM,
int PROBLEM_DIM,
int SPACE_DIM>
struct AddHOOps;
185 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
186 std::vector<FieldSpace> space, std::string geom_field_name);
192 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
193 std::vector<FieldSpace> space, std::string geom_field_name);
199 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
200 std::vector<FieldSpace> space, std::string geom_field_name);
206 add(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
207 std::vector<FieldSpace> space, std::string geom_field_name);
247 boost::shared_ptr<ContactOps::SDFPython> sdfPythonPtr;
259 PetscBool test_ops = PETSC_FALSE;
262 if (test_ops == PETSC_FALSE) {
279 auto get_ents_by_dim = [&](
const auto dim) {
292 auto get_base = [&]() {
293 auto domain_ents = get_ents_by_dim(
SPACE_DIM);
294 if (domain_ents.empty())
312 const auto base = get_base();
323 PetscBool order_edge = PETSC_FALSE;
326 PetscBool order_face = PETSC_FALSE;
329 PetscBool order_volume = PETSC_FALSE;
333 if (order_edge || order_face || order_volume) {
335 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Order edge " << order_edge
338 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Order face " << order_face
341 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Order volume " << order_volume
345 auto ents = get_ents_by_dim(0);
347 ents.merge(get_ents_by_dim(1));
349 ents.merge(get_ents_by_dim(2));
351 ents.merge(get_ents_by_dim(3));
372 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
376 auto filter_blocks = [&](
auto skin) {
377 bool is_contact_block =
true;
382 (boost::format(
"%s(.*)") %
"CONTACT").str()
391 <<
"Find contact block set: " <<
m->getName();
392 auto meshset =
m->getMeshset();
393 Range contact_meshset_range;
395 meshset,
SPACE_DIM - 1, contact_meshset_range,
true);
398 contact_meshset_range);
399 contact_range.merge(contact_meshset_range);
401 if (is_contact_block) {
403 <<
"Nb entities in contact surface: " << contact_range.size();
405 skin = intersect(skin, contact_range);
412 ParallelComm *pcomm =
414 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
415 PSTATUS_NOT, -1, &boundary_ents);
416 return boundary_ents;
427 auto project_ho_geometry = [&]() {
431 PetscBool project_geometry = PETSC_TRUE;
433 &project_geometry, PETSC_NULL);
434 if (project_geometry) {
435 CHKERR project_ho_geometry();
438 auto get_volume = [&]() {
439 using VolOp = DomainEle::UserDataOperator;
441 std::array<double, 2> volume_and_count;
442 op_ptr->doWorkRhsHook = [&](
DataOperator *base_op_ptr,
int side, EntityType type,
445 auto op_ptr =
static_cast<VolOp *
>(base_op_ptr);
447 volume_and_count[
COUNT] += 1;
451 volume_and_count = {0, 0};
452 auto fe = boost::make_shared<DomainEle>(
mField);
453 fe->getOpPtrVector().push_back(op_ptr);
455 auto dm =
simple->getDM();
459 std::array<double, 2> tot_volume_and_count;
460 MPI_Allreduce(volume_and_count.data(), tot_volume_and_count.data(),
461 volume_and_count.size(), MPI_DOUBLE, MPI_SUM,
463 return tot_volume_and_count;
479 auto get_command_line_parameters = [&]() {
504 PetscBool tau_order_is_set;
507 PetscBool ep_order_is_set;
520 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Hardening " <<
H;
521 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Viscous hardening " <<
visH;
522 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Saturation yield stress " <<
Qinf;
523 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Saturation exponent " <<
b_iso;
524 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Kinematic hardening " <<
C1_k;
529 if (tau_order_is_set == PETSC_FALSE)
531 if (ep_order_is_set == PETSC_FALSE)
534 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Approximation order " <<
order;
536 <<
"Ep approximation order " <<
ep_order;
538 <<
"Tau approximation order " <<
tau_order;
540 <<
"Geometry approximation order " <<
geom_order;
542 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Density " <<
rho;
545 PetscBool is_scale = PETSC_TRUE;
569 CHKERR get_command_line_parameters();
573 sdfPythonPtr = boost::make_shared<ContactOps::SDFPython>();
574 CHKERR sdfPythonPtr->sdfInit(
"sdf.py");
575 ContactOps::sdfPythonWeakPtr = sdfPythonPtr;
590 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_X",
592 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Y",
594 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Z",
596 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
597 "REMOVE_ALL",
"U", 0, 3);
600 for (
auto b : {
"FIX_X",
"REMOVE_X"})
601 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(), b,
602 "SIGMA", 0, 0,
false,
true);
603 for (
auto b : {
"FIX_Y",
"REMOVE_Y"})
604 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(), b,
605 "SIGMA", 1, 1,
false,
true);
606 for (
auto b : {
"FIX_Z",
"REMOVE_Z"})
607 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(), b,
608 "SIGMA", 2, 2,
false,
true);
609 for (
auto b : {
"FIX_ALL",
"REMOVE_ALL"})
610 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(), b,
611 "SIGMA", 0, 3,
false,
true);
612 CHKERR bc_mng->removeBlockDOFsOnEntities(
613 simple->getProblemName(),
"NO_CONTACT",
"SIGMA", 0, 3,
false,
true);
617 simple->getProblemName(),
"U");
619 auto &bc_map = bc_mng->getBcMapByBlockName();
620 for (
auto bc : bc_map)
621 MOFEM_LOG(
"PLASTICITY", Sev::verbose) <<
"Marker " << bc.first;
632 auto integration_rule_bc = [](int, int,
int ao) {
return 2 * ao; };
634 auto vol_rule = [](int, int,
int ao) {
return 2 * ao +
geom_order - 1; };
636 auto add_boundary_ops_lhs_mechanical = [&](
auto &pip) {
640 pip, {
HDIV},
"GEOMETRY");
645 pip,
mField,
"U", Sev::inform);
654 mField, pip,
simple->getDomainFEName(),
"SIGMA",
"U",
"GEOMETRY",
661 auto add_boundary_ops_rhs_mechanical = [&](
auto &pip) {
665 pip, {
HDIV},
"GEOMETRY");
670 pip,
mField,
"U", {boost::make_shared<ScaledTimeScale>()}, Sev::inform);
680 auto add_domain_ops_lhs = [
this](
auto &pip) {
683 pip, {
H1,
HDIV},
"GEOMETRY");
692 auto get_inertia_and_mass_damping = [
this](
const double,
const double,
696 return (
rho /
scale) * fe_domain_lhs->ts_aa +
699 pip.push_back(
new OpMass(
"U",
"U", get_inertia_and_mass_damping));
703 mField,
"MAT_PLASTIC", pip,
"U",
"EP",
"TAU");
708 auto add_domain_ops_rhs = [
this](
auto &pip) {
712 pip, {
H1,
HDIV},
"GEOMETRY");
716 {boost::make_shared<ScaledTimeScale>(
"body_force_hist.txt")},
727 auto mat_acceleration = boost::make_shared<MatrixDouble>();
729 "U", mat_acceleration));
731 new OpInertiaForce(
"U", mat_acceleration, [](
double,
double,
double) {
735 auto mat_velocity = boost::make_shared<MatrixDouble>();
739 new OpInertiaForce(
"U", mat_velocity, [](
double,
double,
double) {
746 mField,
"MAT_PLASTIC", pip,
"U",
"EP",
"TAU");
756 CHKERR add_domain_ops_lhs(pip_mng->getOpDomainLhsPipeline());
757 CHKERR add_domain_ops_rhs(pip_mng->getOpDomainRhsPipeline());
760 CHKERR add_boundary_ops_lhs_mechanical(pip_mng->getOpBoundaryLhsPipeline());
761 CHKERR add_boundary_ops_rhs_mechanical(pip_mng->getOpBoundaryRhsPipeline());
763 CHKERR pip_mng->setDomainRhsIntegrationRule(vol_rule);
764 CHKERR pip_mng->setDomainLhsIntegrationRule(vol_rule);
766 CHKERR pip_mng->setBoundaryLhsIntegrationRule(integration_rule_bc);
767 CHKERR pip_mng->setBoundaryRhsIntegrationRule(integration_rule_bc);
769 auto create_reaction_pipeline = [&](
auto &pip) {
772 pip, {
H1},
"GEOMETRY");
774 mField,
"MAT_PLASTIC", pip,
"U",
"EP",
"TAU");
821 auto set_section_monitor = [&](
auto solver) {
824 CHKERR TSGetSNES(solver, &snes);
825 CHKERR SNESMonitorSet(snes,
828 (
void *)(snes_ctx_ptr.get()),
nullptr);
832 auto create_post_process_elements = [&]() {
834 auto push_vol_ops = [
this](
auto &pip) {
836 pip, {
H1,
HDIV},
"GEOMETRY");
838 auto [common_plastic_ptr, common_hencky_ptr] =
840 mField,
"MAT_PLASTIC", pip,
"U",
"EP",
"TAU", 1., Sev::inform);
842 if (common_hencky_ptr) {
843 if (common_plastic_ptr->mGradPtr != common_hencky_ptr->matGradPtr)
847 return std::make_pair(common_plastic_ptr, common_hencky_ptr);
850 auto push_vol_post_proc_ops = [
this](
auto &pp_fe,
auto &&p) {
853 auto &pip = pp_fe->getOpPtrVector();
855 auto [common_plastic_ptr, common_hencky_ptr] = p;
859 auto x_ptr = boost::make_shared<MatrixDouble>();
862 auto u_ptr = boost::make_shared<MatrixDouble>();
871 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
874 common_plastic_ptr->getPlasticSurfacePtr()},
875 {
"PLASTIC_MULTIPLIER",
876 common_plastic_ptr->getPlasticTauPtr()}},
878 {{
"U", u_ptr}, {
"GEOMETRY", x_ptr}},
880 {{
"GRAD", common_hencky_ptr->matGradPtr},
881 {
"FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()}},
883 {{
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
884 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
896 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
899 common_plastic_ptr->getPlasticSurfacePtr()},
900 {
"PLASTIC_MULTIPLIER",
901 common_plastic_ptr->getPlasticTauPtr()}},
903 {{
"U", u_ptr}, {
"GEOMETRY", x_ptr}},
907 {{
"STRAIN", common_plastic_ptr->mStrainPtr},
908 {
"STRESS", common_plastic_ptr->mStressPtr},
909 {
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
910 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
920 auto vol_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops]() {
921 PetscBool post_proc_vol = PETSC_FALSE;
923 &post_proc_vol, PETSC_NULL);
924 if (post_proc_vol == PETSC_FALSE)
925 return boost::shared_ptr<PostProcEle>();
926 auto pp_fe = boost::make_shared<PostProcEle>(mField);
928 push_vol_post_proc_ops(pp_fe, push_vol_ops(pp_fe->getOpPtrVector())),
929 "push_vol_post_proc_ops");
933 auto skin_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops]() {
934 PetscBool post_proc_skin = PETSC_TRUE;
936 &post_proc_skin, PETSC_NULL);
937 if (post_proc_skin == PETSC_FALSE)
938 return boost::shared_ptr<SkinPostProcEle>();
941 auto pp_fe = boost::make_shared<SkinPostProcEle>(mField);
944 pp_fe->getOpPtrVector().push_back(op_side);
946 pp_fe, push_vol_ops(op_side->getOpPtrVector())),
947 "push_vol_post_proc_ops");
951 return std::make_pair(vol_post_proc(), skin_post_proc());
954 auto scatter_create = [&](
auto D,
auto coeff) {
956 CHKERR is_manager->isCreateProblemFieldAndRank(
simple->getProblemName(),
957 ROW,
"U", coeff, coeff, is);
959 CHKERR ISGetLocalSize(is, &loc_size);
961 CHKERR VecCreateMPI(mField.get_comm(), loc_size, PETSC_DETERMINE, &
v);
963 CHKERR VecScatterCreate(
D, is,
v, PETSC_NULL, &scatter);
968 auto set_time_monitor = [&](
auto dm,
auto solver) {
970 boost::shared_ptr<Monitor> monitor_ptr(
971 new Monitor(dm, create_post_process_elements(), reactionFe, uXScatter,
972 uYScatter, uZScatter));
973 boost::shared_ptr<ForcesAndSourcesCore> null;
975 monitor_ptr, null, null);
979 auto set_schur_pc = [&](
auto solver,
980 boost::shared_ptr<SetUpSchur> &schur_ptr) {
983 auto name_prb =
simple->getProblemName();
989 dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
994 for (
auto f : {
"U"}) {
1006 dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
1012 for (
auto f : {
"SIGMA",
"EP",
"TAU"}) {
1017 for (
auto f : {
"EP",
"TAU"}) {
1027 if constexpr (
AT == AssemblyType::BLOCK_SCHUR) {
1036 auto get_nested_mat_data = [&](
auto schur_dm,
auto block_dm) {
1042 {simple->getDomainFEName(),
1058 {simple->getBoundaryFEName(),
1060 {{
"SIGMA",
"SIGMA"}, {
"U",
"SIGMA"}, {
"SIGMA",
"U"}
1070 {dm_schur, dm_block}, block_mat_data,
1072 {
"SIGMA",
"EP",
"TAU"}, {
nullptr,
nullptr,
nullptr}, true
1079 auto get_nested_mat_data = [&](
auto schur_dm,
auto block_dm) {
1080 auto block_mat_data =
1083 {{simple->getDomainFEName(),
1100 {dm_schur, dm_block}, block_mat_data,
1102 {
"EP",
"TAU"}, {
nullptr,
nullptr}, false
1109 auto nested_mat_data = get_nested_mat_data(dm_schur, dm_block);
1112 auto block_is =
getDMSubData(dm_block)->getSmartRowIs();
1113 auto ao_schur =
getDMSubData(dm_schur)->getSmartRowMap();
1119 CHKERR schur_ptr->setUp(solver);
1125 auto dm =
simple->getDM();
1128 uXScatter = scatter_create(
D, 0);
1129 uYScatter = scatter_create(
D, 1);
1131 uZScatter = scatter_create(
D, 2);
1133 auto create_solver = [pip_mng]() {
1135 return pip_mng->createTSIM();
1137 return pip_mng->createTSIM2();
1140 auto solver = create_solver();
1142 auto active_pre_lhs = []() {
1149 auto active_post_lhs = [&]() {
1151 auto get_iter = [&]() {
1156 "Can not get iter");
1160 auto iter = get_iter();
1163 std::array<int, 5> activity_data;
1164 std::fill(activity_data.begin(), activity_data.end(), 0);
1166 activity_data.data(), activity_data.size(), MPI_INT,
1167 MPI_SUM, mField.get_comm());
1169 int &active_points = activity_data[0];
1170 int &avtive_full_elems = activity_data[1];
1171 int &avtive_elems = activity_data[2];
1172 int &nb_points = activity_data[3];
1173 int &nb_elements = activity_data[4];
1177 double proc_nb_points =
1178 100 *
static_cast<double>(active_points) / nb_points;
1179 double proc_nb_active =
1180 100 *
static_cast<double>(avtive_elems) / nb_elements;
1181 double proc_nb_full_active = 100;
1183 proc_nb_full_active =
1184 100 *
static_cast<double>(avtive_full_elems) / avtive_elems;
1187 "Iter %d nb pts %d nb active pts %d (%3.3f\%) nb active "
1189 "(%3.3f\%) nb full active elems %d (%3.3f\%)",
1190 iter, nb_points, active_points, proc_nb_points,
1191 avtive_elems, proc_nb_active, avtive_full_elems,
1192 proc_nb_full_active, iter);
1199 auto add_active_dofs_elem = [&](
auto dm) {
1201 auto fe_pre_proc = boost::make_shared<FEMethod>();
1202 fe_pre_proc->preProcessHook = active_pre_lhs;
1203 auto fe_post_proc = boost::make_shared<FEMethod>();
1204 fe_post_proc->postProcessHook = active_post_lhs;
1206 ts_ctx_ptr->getPreProcessIJacobian().push_front(fe_pre_proc);
1207 ts_ctx_ptr->getPostProcessIJacobian().push_back(fe_post_proc);
1211 auto set_essential_bc = [&](
auto dm,
auto solver) {
1215 auto pre_proc_ptr = boost::make_shared<FEMethod>();
1216 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
1217 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
1220 auto disp_time_scale = boost::make_shared<TimeScale>();
1222 auto get_bc_hook_rhs = [
this, pre_proc_ptr, disp_time_scale]() {
1224 {disp_time_scale},
false);
1227 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
1229 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
1232 mField, post_proc_rhs_ptr,
nullptr, Sev::verbose)();
1234 mField, post_proc_rhs_ptr, 1.)();
1237 auto get_post_proc_hook_lhs = [
this, post_proc_lhs_ptr]() {
1239 mField, post_proc_lhs_ptr, 1.);
1241 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
1244 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
1245 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
1246 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
1247 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
1248 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
1254 CHKERR TSSetSolution(solver,
D);
1256 CHKERR TS2SetSolution(solver,
D, DD);
1259 CHKERR set_section_monitor(solver);
1260 CHKERR set_time_monitor(dm, solver);
1261 CHKERR TSSetFromOptions(solver);
1264 CHKERR add_active_dofs_elem(dm);
1265 boost::shared_ptr<SetUpSchur> schur_ptr;
1266 CHKERR set_schur_pc(solver, schur_ptr);
1267 CHKERR set_essential_bc(dm, solver);
1272 BOOST_LOG_SCOPED_THREAD_ATTR(
"Timeline", attrs::timer());
1273 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSetUp";
1275 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSetUp <= done";
1276 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSolve";
1277 CHKERR TSSolve(solver, NULL);
1278 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSolve <= done";
1295 constexpr double eps = 1e-9;
1297 auto x = opt->setRandomFields(
simple->getDM(), {
1299 {
"U", {-1e-6, 1e-6}},
1301 {
"EP", {-1e-6, 1e-6}},
1307 auto dot_x_plastic_active =
1308 opt->setRandomFields(
simple->getDM(), {
1317 auto diff_x_plastic_active =
1318 opt->setRandomFields(
simple->getDM(), {
1328 auto dot_x_elastic =
1329 opt->setRandomFields(
simple->getDM(), {
1338 auto diff_x_elastic =
1339 opt->setRandomFields(
simple->getDM(), {
1349 auto test_domain_ops = [&](
auto fe_name,
auto lhs_pipeline,
auto rhs_pipeline,
1350 auto dot_x,
auto diff_x) {
1353 auto diff_res = opt->checkCentralFiniteDifference(
1354 simple->getDM(), fe_name, rhs_pipeline, lhs_pipeline, x, dot_x,
1360 CHKERR VecNorm(diff_res, NORM_2, &fnorm);
1362 "Test consistency of tangent matrix %3.4e", fnorm);
1364 constexpr double err = 1e-5;
1367 "Norm of directional derivative too large err = %3.4e", fnorm);
1372 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Elastic active";
1373 CHKERR test_domain_ops(
simple->getDomainFEName(), pip->getDomainLhsFE(),
1374 pip->getDomainRhsFE(), dot_x_elastic, diff_x_elastic);
1376 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Plastic active";
1377 CHKERR test_domain_ops(
simple->getDomainFEName(), pip->getDomainLhsFE(),
1378 pip->getDomainRhsFE(), dot_x_plastic_active,
1379 diff_x_plastic_active);
1400 const char param_file[] =
"param_file.petsc";
1404 auto core_log = logging::core::get();
1422 DMType dm_name =
"DMMOFEM";
1427 moab::Core mb_instance;
1428 moab::Interface &moab = mb_instance;
1453 if (Py_FinalizeEx() < 0) {
1470 "Is expected that schur matrix is not "
1471 "allocated. This is "
1472 "possible only is PC is set up twice");
1496 CHKERR TSGetSNES(solver, &snes);
1498 CHKERR SNESGetKSP(snes, &ksp);
1499 CHKERR KSPSetFromOptions(ksp);
1502 CHKERR KSPGetPC(ksp, &pc);
1503 PetscBool is_pcfs = PETSC_FALSE;
1504 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
1508 "Is expected that schur matrix is not "
1509 "allocated. This is "
1510 "possible only is PC is set up twice");
1518 CHKERR TSGetDM(solver, &solver_dm);
1519 CHKERR DMSetMatType(solver_dm, MATSHELL);
1526 auto swap_assemble = [](TS ts, PetscReal
t, Vec u, Vec u_t, PetscReal
a,
1527 Mat
A, Mat
B,
void *ctx) {
1530 CHKERR TSSetIJacobian(solver, A, P, swap_assemble, ts_ctx_ptr.get());
1532 auto swap_assemble = [](TS ts, PetscReal
t, Vec u, Vec u_t, Vec utt,
1533 PetscReal
a, PetscReal aa, Mat
A, Mat
B,
1537 CHKERR TSSetI2Jacobian(solver, A, P, swap_assemble, ts_ctx_ptr.get());
1539 CHKERR KSPSetOperators(ksp, A, P);
1541 auto set_ops = [&]() {
1547 pip_mng->getOpBoundaryLhsPipeline().push_front(
1551 {
"EP",
"TAU"}, {
nullptr,
nullptr},
aoSchur,
S,
false, false
1555 pip_mng->getOpDomainLhsPipeline().push_front(
1559 {
"EP",
"TAU"}, {
nullptr,
nullptr},
aoSchur,
S,
false, false
1564 double eps_stab = 1e-4;
1570 using OpMassStab = B::OpMass<3, SPACE_DIM * SPACE_DIM>;
1573 pip_mng->getOpBoundaryLhsPipeline().push_front(
1575 pip_mng->getOpBoundaryLhsPipeline().push_back(
1576 new OpMassStab(
"SIGMA",
"SIGMA", [eps_stab](
double,
double,
double) {
1581 {
"SIGMA",
"EP",
"TAU"}, {
nullptr,
nullptr,
nullptr},
aoSchur,
S,
1586 pip_mng->getOpDomainLhsPipeline().push_front(
1590 {
"SIGMA",
"EP",
"TAU"}, {
nullptr,
nullptr,
nullptr},
aoSchur,
S,
1598 auto set_assemble_elems = [&]() {
1600 auto schur_asmb_pre_proc = boost::make_shared<FEMethod>();
1601 schur_asmb_pre_proc->preProcessHook = [
this]() {
1604 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"Lhs Assemble Begin";
1607 auto schur_asmb_post_proc = boost::make_shared<FEMethod>();
1609 schur_asmb_post_proc->postProcessHook = [
this, schur_asmb_post_proc]() {
1611 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"Lhs Assemble End";
1614 CHKERR MatAssemblyBegin(
S, MAT_FINAL_ASSEMBLY);
1615 CHKERR MatAssemblyEnd(
S, MAT_FINAL_ASSEMBLY);
1622 ts_ctx_ptr->getPreProcessIJacobian().push_front(schur_asmb_pre_proc);
1623 ts_ctx_ptr->getPostProcessIJacobian().push_front(schur_asmb_post_proc);
1627 auto set_pc = [&]() {
1630 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER,
S);
1634 auto set_diagonal_pc = [&]() {
1637 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULL, &subksp);
1638 auto get_pc = [](
auto ksp) {
1640 CHKERR KSPGetPC(ksp, &pc_raw);
1645 CHKERR PetscFree(subksp);
1651 CHKERR set_assemble_elems();
1655 CHKERR set_diagonal_pc();
1658 pip_mng->getOpBoundaryLhsPipeline().push_front(
1660 pip_mng->getOpBoundaryLhsPipeline().push_back(
1663 pip_mng->getOpDomainLhsPipeline().push_back(
1672boost::shared_ptr<SetUpSchur>
1676 return boost::shared_ptr<SetUpSchur>(
1683 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
1684 std::vector<FieldSpace> spaces, std::string geom_field_name) {
1691 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
1692 std::vector<FieldSpace> spaces, std::string geom_field_name) {
1698template <
int FE_DIM,
int PROBLEM_DIM,
int SPACE_DIM>
1700scaleL2(boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
1701 std::string geom_field_name) {
1704 auto jac_ptr = boost::make_shared<MatrixDouble>();
1705 auto det_ptr = boost::make_shared<VectorDouble>();
1707 geom_field_name, jac_ptr));
1710 auto scale_ptr = boost::make_shared<double>(1.);
1713 using OP = ForcesAndSourcesCore::UserDataOperator;
1714 auto op_scale =
new OP(
NOSPACE, OP::OPSPACE);
1715 op_scale->doWorkRhsHook = [scale_ptr, det_ptr,
1718 *scale_ptr =
scale / det_ptr->size();
1722 pipeline.push_back(op_scale);
1731 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
1732 std::vector<FieldSpace> spaces, std::string geom_field_name) {
1735 constexpr bool scale_l2 =
false;
1740 nullptr,
nullptr,
nullptr);
1745 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
1746 std::vector<FieldSpace> spaces, std::string geom_field_name) {
1748 constexpr bool scale_l2 =
false;
1753 nullptr,
nullptr,
nullptr);
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
static auto get_skin(MoFEM::Interface &m_field, Range body_ents)
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
#define MOFEM_LOG_C(channel, severity, format,...)
void simple(double P1[], double P2[], double P3[], double c[], const int N)
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
[Define dimension]
Kronecker Delta class symmetric.
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base nme:nme847.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
FieldSpace
approximation spaces
@ L2
field with C-1 continuity
@ HCURL
field with continuous tangents
@ HDIV
field with continuous normal traction
#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 ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_ATOM_TEST_INVALID
@ MOFEM_DATA_INCONSISTENCY
static const char *const ApproximationBaseNames[]
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesVector< 1, SPACE_DIM, 1 > OpInertiaForce
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 DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
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.
auto createDMVector(DM dm)
Get smart vector from DM.
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
auto createDMMatrix(DM dm)
Get smart matrix from DM.
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
auto type_from_handle(const EntityHandle h)
get type from entity handle
PetscErrorCode DMMoFEMTSSetMonitor(DM dm, TS ts, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
Set Monitor To TS solver.
PetscErrorCode TsSetIJacobian(TS ts, PetscReal t, Vec u, Vec u_t, PetscReal a, Mat A, Mat B, void *ctx)
Set function evaluating jacobian in TS solver.
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
OpSchurAssembleBase * createOpSchurAssembleEnd(std::vector< std::string > fields_name, std::vector< boost::shared_ptr< Range > > field_ents, SmartPetscObj< AO > ao, SmartPetscObj< Mat > schur, bool sym_schur, bool symm_op)
Construct a new Op Schur Assemble End object.
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
MoFEMErrorCode MoFEMSNESMonitorFields(SNES snes, PetscInt its, PetscReal fgnorm, SnesCtx *snes_ctx)
Sens monitor printing residual field by field.
MoFEMErrorCode setSchurA00MatSolvePC(SmartPetscObj< PC > pc)
Set PC for A00 block.
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
auto getDMSubData(DM dm)
Get sub problem data structure.
PetscErrorCode TsSetI2Jacobian(TS ts, PetscReal t, Vec u, Vec u_t, Vec u_tt, PetscReal a, PetscReal aa, Mat A, Mat B, void *ctx)
Calculation Jacobian for second order PDE in time.
boost::shared_ptr< BlockStructure > createBlockMatStructure(DM dm, SchurFEOpsFEandFields schur_fe_op_vec)
Create a Mat Diag Blocks object.
boost::shared_ptr< NestSchurData > createSchurNestedMatrixStruture(std::pair< SmartPetscObj< DM >, SmartPetscObj< DM > > dms, boost::shared_ptr< BlockStructure > block_mat_data_ptr, std::vector< std::string > fields_names, std::vector< boost::shared_ptr< Range > > field_ents, bool add_preconditioner_block)
Get the Schur Nest Mat Array object.
MoFEMErrorCode DMMoFEMSetNestSchurData(DM dm, boost::shared_ptr< NestSchurData >)
auto getDMSnesCtx(DM dm)
Get SNES context data structure used by DM.
auto createDMNestSchurMat(DM dm)
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
OpSchurAssembleBase * createOpSchurAssembleBegin()
auto createDMBlockMat(DM dm)
auto createCommonPlasticOps(MoFEM::Interface &m_field, std::string block_name, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string u, std::string ep, std::string tau, double scale, Sev sev)
MoFEMErrorCode opFactoryDomainReactions(MoFEM::Interface &m_field, std::string block_name, Pip &pip, std::string u, std::string ep, std::string tau)
MoFEMErrorCode opFactoryDomainRhs(MoFEM::Interface &m_field, std::string block_name, Pip &pip, std::string u, std::string ep, std::string tau)
MoFEMErrorCode scaleL2(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string geom_field_name)
MoFEMErrorCode opFactoryDomainLhs(MoFEM::Interface &m_field, std::string block_name, Pip &pip, std::string u, std::string ep, std::string tau)
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
double young_modulus
Young modulus.
constexpr AssemblyType AT
double C1_k
Kinematic hardening.
double Qinf
Saturation yield stress.
constexpr IntegrationType IT
static char help[]
[TestOperators]
#define EXECUTABLE_DIMENSION
PetscBool is_quasi_static
double visH
Viscous hardening.
double poisson_ratio
Poisson ratio.
auto kinematic_hardening(FTensor::Tensor2_symmetric< T, DIM > &t_plastic_strain, double C1_k)
PetscBool set_timer
Set timer.
double iso_hardening_dtau(double tau, double H, double Qinf, double b_iso)
double zeta
Viscous hardening.
int tau_order
Order of tau files.
double iso_hardening_exp(double tau, double b_iso)
int order
Order displacement.
double b_iso
Saturation exponent.
PetscBool is_large_strains
Large strains.
int geom_order
Order if fixed.
double sigmaY
Yield stress.
double iso_hardening(double tau, double H, double Qinf, double b_iso, double sigmaY)
auto kinematic_hardening_dplastic_strain(double C1_k)
ElementsAndOps< SPACE_DIM >::SideEle SideEle
int ep_order
Order of ep files.
constexpr FieldSpace CONTACT_SPACE
constexpr double t
plate stiffness
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMass
[Only used with Hooke equation (linear material model)]
FTensor::Index< 'm', 3 > m
PipelineManager::ElementsAndOpsByDim< 2 >::FaceSideEle SideEle
PipelineManager::ElementsAndOpsByDim< 3 >::FaceSideEle SideEle
double getScale(const double time)
Get scaling at given time.
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uZScatter
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
MoFEMErrorCode testOperators()
[Solve]
FieldApproximationBase base
MoFEMErrorCode createCommonData()
[Set up problem]
static std::array< double, 2 > meshVolumeAndCount
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uYScatter
Example(MoFEM::Interface &m_field)
MoFEMErrorCode OPs()
[Boundary condition]
MoFEMErrorCode runProblem()
[Run problem]
MoFEM::Interface & mField
MoFEMErrorCode setupProblem()
[Run problem]
MoFEMErrorCode bC()
[Create common data]
boost::shared_ptr< DomainEle > reactionFe
Add operators pushing bases from local to physical configuration.
Simple interface for fast problem set-up.
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() 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.
base operator to do operations at Gauss Pt. level
Deprecated interface functions.
Definition of the displacement bc data structure.
Data on single entity (This is passed as argument to DataOperator::doWork)
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.
Class (Function) to calculate residual side diagonal.
double getMeasure() const
get measure of element
@ OPSPACE
operator do Work is execute on space data
Section manager is used to create indexes and sections.
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
Interface for managing meshsets containing materials and boundary conditions.
Get field gradients at integration pts for scalar filed rank 0, i.e. vector field.
Approximate field values for given petsc vector.
Get values at integration pts for tensor filed rank 1, i.e. vector field.
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
Scale base functions by inverses of measure of element.
Calculate directional derivative of the right hand side and compare it with tangent matrix derivative...
PipelineManager interface.
MoFEM::VolumeElementForcesAndSourcesCore VolEle
boost::shared_ptr< FEMethod > & getDomainLhsFE()
MoFEM::FaceElementForcesAndSourcesCore FaceEle
MoFEM::EdgeElementForcesAndSourcesCore EdgeEle
Projection of edge entities with one mid-node on hierarchical basis.
Simple interface for fast problem set-up.
intrusive_ptr for managing petsc objects
Force scale operator for reading two columns.
double getScale(const double time)
Get scaling at a given time.
TimeScale(std::string file_name="", bool error_if_file_not_given=false, ScalingFun def_scaling_fun=[](double time) { return time;})
TimeScale constructor.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Volume finite element base.
static std::array< int, 5 > activityData
[Push operators to pipeline]
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field)
virtual MoFEMErrorCode setUp(TS solver)=0
SmartPetscObj< DM > subDM
field split sub dm
SmartPetscObj< AO > aoSchur
SetUpSchurImpl(MoFEM::Interface &m_field, SmartPetscObj< DM > sub_dm, SmartPetscObj< IS > field_split_is, SmartPetscObj< AO > ao_up)
MoFEMErrorCode setUp(SmartPetscObj< KSP >)
SmartPetscObj< IS > fieldSplitIS
IS for split Schur block.
virtual ~SetUpSchurImpl()
MoFEMErrorCode postProc()
MoFEM::Interface & mField
constexpr AssemblyType AT
VolEle::UserDataOperator VolOp