589 auto set_section_monitor = [&](
auto solver) {
592 CHKERR TSGetSNES(solver, &snes);
593 PetscViewerAndFormat *vf;
594 CHKERR PetscViewerAndFormatCreate(PETSC_VIEWER_STDOUT_WORLD,
595 PETSC_VIEWER_DEFAULT, &vf);
598 (
MoFEMErrorCode(*)(SNES, PetscInt, PetscReal,
void *))SNESMonitorFields,
603 auto scatter_create = [&](
auto D,
auto coeff) {
605 CHKERR is_manager->isCreateProblemFieldAndRank(
simple->getProblemName(),
606 ROW,
"U", coeff, coeff, is);
608 CHKERR ISGetLocalSize(is, &loc_size);
612 CHKERR VecScatterCreate(
D, is,
v, PETSC_NULL, &scatter);
617 auto create_post_process_elements = [&]() {
618 auto pp_fe = boost::make_shared<PostProcEle>(
mField);
620 auto push_vol_ops = [
this](
auto &pip) {
628 auto push_vol_post_proc_ops = [
this](
auto &pp_fe,
auto &&p) {
631 auto &pip = pp_fe->getOpPtrVector();
635 auto x_ptr = boost::make_shared<MatrixDouble>();
638 auto u_ptr = boost::make_shared<MatrixDouble>();
641 auto pressure_ptr = boost::make_shared<VectorDouble>();
644 auto div_u_ptr = boost::make_shared<VectorDouble>();
648 auto grad_u_ptr = boost::make_shared<MatrixDouble>();
652 auto strain_ptr = boost::make_shared<MatrixDouble>();
655 auto stress_ptr = boost::make_shared<MatrixDouble>();
657 mu, stress_ptr, strain_ptr, pressure_ptr));
663 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
665 {{
"P", pressure_ptr}},
667 {{
"U", u_ptr}, {
"GEOMETRY", x_ptr}},
671 {{
"STRAIN", strain_ptr}, {
"STRESS", stress_ptr}}
680 auto vol_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops]() {
681 PetscBool post_proc_vol = PETSC_FALSE;
683 &post_proc_vol, PETSC_NULL);
684 if (post_proc_vol == PETSC_FALSE)
685 return boost::shared_ptr<PostProcEle>();
686 auto pp_fe = boost::make_shared<PostProcEle>(
mField);
688 push_vol_post_proc_ops(pp_fe, push_vol_ops(pp_fe->getOpPtrVector())),
689 "push_vol_post_proc_ops");
693 auto skin_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops]() {
694 PetscBool post_proc_skin = PETSC_TRUE;
696 &post_proc_skin, PETSC_NULL);
697 if (post_proc_skin == PETSC_FALSE)
698 return boost::shared_ptr<SkinPostProcEle>();
701 auto pp_fe = boost::make_shared<SkinPostProcEle>(
mField);
704 pp_fe->getOpPtrVector().push_back(op_side);
706 pp_fe, push_vol_ops(op_side->getOpPtrVector())),
707 "push_vol_post_proc_ops");
711 return std::make_pair(vol_post_proc(), skin_post_proc());
714 boost::shared_ptr<SetPtsData> field_eval_data;
715 boost::shared_ptr<MatrixDouble> vector_field_ptr;
717 std::array<double, SPACE_DIM> field_eval_coords;
720 field_eval_coords.data(), &coords_dim,
724 vector_field_ptr = boost::make_shared<MatrixDouble>();
729 field_eval_data,
simple->getDomainFEName());
732 field_eval_data,
simple->getDomainFEName());
735 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
736 auto no_rule = [](
int,
int,
int) {
return -1; };
737 auto field_eval_fe_ptr = field_eval_data->feMethodPtr.lock();
738 field_eval_fe_ptr->getRuleHook = no_rule;
739 field_eval_fe_ptr->getOpPtrVector().push_back(
743 auto set_time_monitor = [&](
auto dm,
auto solver) {
745 boost::shared_ptr<MonitorIncompressible> monitor_ptr(
747 create_post_process_elements(),
uXScatter,
749 field_eval_data, vector_field_ptr));
750 boost::shared_ptr<ForcesAndSourcesCore>
null;
752 monitor_ptr,
null,
null);
756 auto set_essential_bc = [&]() {
760 auto pre_proc_ptr = boost::make_shared<FEMethod>();
761 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
764 auto time_scale = boost::make_shared<TimeScale>();
767 mField, pre_proc_ptr, {time_scale},
false);
768 post_proc_rhs_ptr->postProcessHook =
771 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
772 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
773 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
777 auto set_schur_pc = [&](
auto solver) {
779 CHKERR TSGetSNES(solver, &snes);
781 CHKERR SNESGetKSP(snes, &ksp);
783 CHKERR KSPGetPC(ksp, &pc);
784 PetscBool is_pcfs = PETSC_FALSE;
785 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
786 boost::shared_ptr<SetUpSchur> schur_ptr;
795 auto pre_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
796 auto post_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
797 pre_proc_schur_lhs_ptr->preProcessHook = [pre_proc_schur_lhs_ptr]() {
799 MOFEM_LOG(
"INCOMP_ELASTICITY", Sev::verbose) <<
"Lhs Zero matrices";
800 CHKERR MatZeroEntries(pre_proc_schur_lhs_ptr->A);
801 CHKERR MatZeroEntries(pre_proc_schur_lhs_ptr->B);
804 post_proc_schur_lhs_ptr->postProcessHook = [
this,
805 post_proc_schur_lhs_ptr]() {
807 MOFEM_LOG(
"INCOMP_ELASTICITY", Sev::verbose) <<
"Lhs Assemble Begin";
808 *(post_proc_schur_lhs_ptr->matAssembleSwitch) =
false;
809 CHKERR MatAssemblyBegin(post_proc_schur_lhs_ptr->A, MAT_FINAL_ASSEMBLY);
810 CHKERR MatAssemblyEnd(post_proc_schur_lhs_ptr->A, MAT_FINAL_ASSEMBLY);
812 mField, post_proc_schur_lhs_ptr, 1.,
815 CHKERR MatAssemblyBegin(post_proc_schur_lhs_ptr->B, MAT_FINAL_ASSEMBLY);
816 CHKERR MatAssemblyEnd(post_proc_schur_lhs_ptr->B, MAT_FINAL_ASSEMBLY);
817 CHKERR MatAXPY(post_proc_schur_lhs_ptr->B, 1, post_proc_schur_lhs_ptr->A,
818 SAME_NONZERO_PATTERN);
819 MOFEM_LOG(
"INCOMP_ELASTICITY", Sev::verbose) <<
"Lhs Assemble End";
822 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_schur_lhs_ptr);
823 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_schur_lhs_ptr);
825 if (is_pcfs == PETSC_TRUE) {
828 CHK_MOAB_THROW(schur_ptr->setUp(solver),
"setup schur preconditioner");
830 auto set_pcfieldsplit_preconditioned_ts = [&](
auto solver) {
832 auto name_prb =
simple->getProblemName();
835 name_prb,
ROW,
"P", 0, 1, is_p);
836 CHKERR PCFieldSplitSetIS(pc, PETSC_NULL, is_p);
840 "set pcfieldsplit preconditioned");
842 return boost::make_tuple(schur_ptr,
A, B);
845 return boost::make_tuple(schur_ptr,
A, B);
848 auto dm =
simple->getDM();
858 CHKERR set_essential_bc();
860 auto solver = pip_mng->createTSIM();
861 CHKERR TSSetFromOptions(solver);
863 CHKERR set_section_monitor(solver);
864 CHKERR set_time_monitor(dm, solver);
865 auto [schur_pc_ptr,
A, B] = set_schur_pc(solver);
867 CHKERR TSSetSolution(solver,
D);
869 CHKERR TSSolve(solver, NULL);