MoFEMErrorCode set_contact_dm(MoFEM::Interface &m_field, SmartPetscObj<DM> &dm,
SmartPetscObj<DM> &dm_contact) {
MoFEMFunctionBegin;
auto simple = m_field.getInterface<Simple>();
dm_contact = createSmartDM(m_field.get_comm(), "DMMOFEM");
CHKERR DMMoFEMCreateSubDM(dm_contact, dm, "CONTACT_PROBLEM");
CHKERR DMMoFEMSetDestroyProblem(dm_contact, PETSC_TRUE);
CHKERR DMMoFEMAddSubFieldRow(dm_contact, "U");
if (m_field.check_field("TAU"))
CHKERR DMMoFEMAddSubFieldRow(dm_contact, "TAU");
if (m_field.check_field("EP"))
CHKERR DMMoFEMAddSubFieldRow(dm_contact, "EP");
CHKERR DMMoFEMAddElement(dm_contact, simple->getDomainFEName().c_str());
CHKERR DMMoFEMAddElement(dm_contact, simple->getBoundaryFEName().c_str());
// CHKERR DMMoFEMAddElement(dm_contact, simple->getSkeletonFEName().c_str());
CHKERR DMMoFEMSetSquareProblem(dm_contact, PETSC_TRUE);
CHKERR DMMoFEMSetIsPartitioned(dm_contact, PETSC_TRUE);
CHKERR DMSetUp(dm_contact);
if (1) {
SmartPetscObj<Mat> m;
CHKERR m_field.getInterface<MatrixManager>()
->createMPIAIJWithArrays<PetscGlobalIdx_mi_tag>("CONTACT_PROBLEM", m);
// MatView(m, PETSC_VIEWER_STDOUT_WORLD);
// MatView(m, PETSC_VIEWER_DRAW_WORLD);
// MatView(m, PETSC_VIEWER_MATLAB_WORLD);
// std::string wait;
// std::cin >> wait;
CHKERR m_field.getInterface<MatrixManager>()
->checkMPIAIJWithArraysMatrixFillIn<PetscGlobalIdx_mi_tag>(
"CONTACT_PROBLEM", 1, 1, 1);
}
MoFEMFunctionReturn(0);
}
[0] <warning> Warning: Number of Dofs in Col diffrent than number of dofs for given entity order 24 28
[0] <warning> Warning: Number of Dofs in Row diffrent than number of dofs for given entity order 4 28
// Setup fieldsplit (block) solver - optional: yes/no
if (is_pcfs == PETSC_TRUE && !data.is_fieldsplit_bc_only) {
CHKERR set_global_mat_and_vec();
PetscBool is_l0_field_split; // level0 fieldsplit
PetscBool is_l1_field_split = PETSC_TRUE; // level1 fieldsplit
PetscObjectTypeCompare((PetscObject)pC, PCFIELDSPLIT, &is_l0_field_split);
// optional fieldsplit on top
auto set_fieldsplit_contact = [&]() {
MoFEMFunctionBeginHot;
const MoFEM::Problem *fs_sig_ptr;
CHKERR DMMoFEMGetProblemPtr(dmContact, &fs_sig_ptr);
if (auto sig_data = fs_sig_ptr->subProblemData) {
is_map["E_IS_SIG"] = sig_data->rowIs;
sigma_ao = sig_data->getSmartRowMap();
CHKERR PCFieldSplitSetIS(pC, NULL, is_map["SIGMA"]);
CHKERR PCFieldSplitSetIS(pC, NULL, is_map["E_IS_SIG"]);
CHKERR PCSetUp(pC);
PetscInt n;
KSP *ct_ksp;
CHKERR PCFieldSplitGetSubKSP(pC, &n, &ct_ksp);
PC l1_pc;
CHKERR KSPGetPC(ct_ksp[1], &l1_pc);
PetscObjectTypeCompare((PetscObject)l1_pc, PCFIELDSPLIT,
&is_l1_field_split);
// important!
// in case of contact analysis we swap the first preconditioner
pC = l1_pc;
CHKERR PetscFree(ct_ksp);
}
MoFEMFunctionReturnHot(0);
};
if (data.with_contact && is_l0_field_split)
CHKERR set_fieldsplit_contact();
PetscObjectTypeCompare((PetscObject)pC, PCFIELDSPLIT, &is_l1_field_split);
if (data.with_plasticity && is_l0_field_split && is_l1_field_split) {
const MoFEM::Problem *schur_ep_ptr;
CHKERR DMMoFEMGetProblemPtr(dmEP, &schur_ep_ptr);
if (auto ep_data = schur_ep_ptr->subProblemData) {
is_map["E_IS_EP"] = ep_data->rowIs;
if (sigma_ao)
CHKERR AOApplicationToPetscIS(sigma_ao, is_map["EP"]);
CHKERR PCFieldSplitSetIS(pC, NULL, is_map["EP"]);
CHKERR PCFieldSplitSetIS(pC, NULL, is_map["E_IS_EP"]);
PCCompositeType pc_type;
CHKERR PCFieldSplitGetType(pC, &pc_type);
if (pc_type == PC_COMPOSITE_SCHUR) {
CHKERR DMCreateMatrix_MoFEM(dmEP, commonDataPtr->SEpEp);
commonDataPtr->aoSEpEp = ep_data->getSmartRowMap();
commonDataPtr->blockMatContainerPtr =
boost::make_shared<BlockMatContainer>();
MoFEM::block_mat_container_ptr =
commonDataPtr->blockMatContainerPtr;
CHKERR PCFieldSplitSetSchurPre(pC, PC_FIELDSPLIT_SCHUR_PRE_USER,
commonDataPtr->SEpEp);
CHKERR PCSetUp(pC);
}
PetscInt n;
KSP *tt_ksp;
CHKERR PCFieldSplitGetSubKSP(pC, &n, &tt_ksp);
PC tau_pc;
CHKERR KSPGetPC(tt_ksp[1], &tau_pc);
PetscBool is_tau_field_split;
PetscObjectTypeCompare((PetscObject)tau_pc, PCFIELDSPLIT,
&is_tau_field_split);
if (is_tau_field_split) {
const MoFEM::Problem *schur_tau_ptr;
CHKERR DMMoFEMGetProblemPtr(dmTAU, &schur_tau_ptr);
if (auto tau_data = schur_tau_ptr->subProblemData) {
// CHKERR tau_data->getRowIs(is_map["E_IS_TAU"]);
is_map["E_IS_TAU"] = tau_data->rowIs;
AO ep_ao;
CHKERR ep_data->getRowMap(&ep_ao);
if (sigma_ao)
CHKERR AOApplicationToPetscIS(sigma_ao, is_map["TAU"]);
CHKERR AOApplicationToPetscIS(ep_ao, is_map["TAU"]);
CHKERR PCFieldSplitSetIS(tau_pc, NULL, is_map["TAU"]);
CHKERR PCFieldSplitSetIS(tau_pc, NULL, is_map["E_IS_TAU"]);
CHKERR DMCreateMatrix_MoFEM(dmTAU, commonDataPtr->STauTau);
commonDataPtr->aoSTauTau = tau_data->getSmartRowMap();
CHKERR PCFieldSplitSetSchurPre(
tau_pc, PC_FIELDSPLIT_SCHUR_PRE_USER, commonDataPtr->STauTau);
CHKERR PCSetUp(tau_pc);
PetscInt bc_n;
KSP *bc_ksp;
CHKERR PCFieldSplitGetSubKSP(tau_pc, &bc_n, &bc_ksp);
PC bc_pc;
CHKERR KSPGetPC(bc_ksp[1], &bc_pc);
CHKERR set_fieldsplit_on_bc(bc_pc, schur_tau_ptr->getName());
CHKERR PetscFree(bc_ksp);
}
}
CHKERR PetscFree(tt_ksp);
// for (auto &m : is_map)
// CHKERR ISDestroy(&m.second);
}
}
}
MoFEMErrorCode set_plastic_ep_dm(MoFEM::Interface &m_field,
SmartPetscObj<DM> &dm,
SmartPetscObj<DM> &dm_plastic) {
MoFEMFunctionBegin;
auto simple = m_field.getInterface<Simple>();
dm_plastic = createSmartDM(m_field.get_comm(), "DMMOFEM");
CHKERR DMMoFEMCreateSubDM(dm_plastic, dm, "PLASTIC_EP_PROBLEM");
CHKERR DMMoFEMSetDestroyProblem(dm_plastic, PETSC_TRUE);
CHKERR DMMoFEMAddSubFieldRow(dm_plastic, "U");
CHKERR DMMoFEMAddSubFieldRow(dm_plastic, "TAU");
// if (m_field.check_field("SIGMA"))
// CHKERR DMMoFEMAddSubFieldRow(dm_plastic, "SIGMA");
CHKERR DMMoFEMAddElement(dm_plastic, simple->getDomainFEName().c_str());
CHKERR DMMoFEMAddElement(dm_plastic, simple->getBoundaryFEName().c_str());
CHKERR DMMoFEMSetSquareProblem(dm_plastic, PETSC_TRUE);
CHKERR DMMoFEMSetIsPartitioned(dm_plastic, PETSC_TRUE);
CHKERR DMSetUp(dm_plastic);
MoFEMFunctionReturn(0);
}
MoFEMErrorCode set_plastic_tau_dm(MoFEM::Interface &m_field,
SmartPetscObj<DM> &dm,
SmartPetscObj<DM> &dm_plastic_tau) {
MoFEMFunctionBegin;
auto simple = m_field.getInterface<Simple>();
dm_plastic_tau = createSmartDM(m_field.get_comm(), "DMMOFEM");
CHKERR DMMoFEMCreateSubDM(dm_plastic_tau, dm, "PLASTIC_TAU_PROBLEM");
CHKERR DMMoFEMSetDestroyProblem(dm_plastic_tau, PETSC_TRUE);
CHKERR DMMoFEMAddSubFieldRow(dm_plastic_tau, "U");
// if (m_field.check_field("SIGMA"))
// CHKERR DMMoFEMAddSubFieldRow(dm_plastic_tau, "SIGMA");
CHKERR DMMoFEMAddElement(dm_plastic_tau, simple->getDomainFEName().c_str());
CHKERR DMMoFEMAddElement(dm_plastic_tau, simple->getBoundaryFEName().c_str());
CHKERR DMMoFEMSetSquareProblem(dm_plastic_tau, PETSC_TRUE);
CHKERR DMMoFEMSetIsPartitioned(dm_plastic_tau, PETSC_TRUE);
CHKERR DMSetUp(dm_plastic_tau);
MoFEMFunctionReturn(0);
}
MoFEMErrorCode set_contact_dm(MoFEM::Interface &m_field, SmartPetscObj<DM> &dm,
SmartPetscObj<DM> &dm_contact) {
MoFEMFunctionBegin;
auto simple = m_field.getInterface<Simple>();
dm_contact = createSmartDM(m_field.get_comm(), "DMMOFEM");
CHKERR DMMoFEMCreateSubDM(dm_contact, dm, "CONTACT_PROBLEM");
CHKERR DMMoFEMSetDestroyProblem(dm_contact, PETSC_TRUE);
CHKERR DMMoFEMAddSubFieldRow(dm_contact, "U");
if (m_field.check_field("TAU"))
CHKERR DMMoFEMAddSubFieldRow(dm_contact, "TAU");
if (m_field.check_field("EP"))
CHKERR DMMoFEMAddSubFieldRow(dm_contact, "EP"
);
CHKERR DMMoFEMAddElement(dm_contact, simple->getDomainFEName().c_str());
CHKERR DMMoFEMAddElement(dm_contact, simple->getBoundaryFEName().c_str());
CHKERR DMMoFEMSetSquareProblem(dm_contact, PETSC_TRUE);
CHKERR DMMoFEMSetIsPartitioned(dm_contact, PETSC_TRUE);
CHKERR DMSetUp(dm_contact);
MoFEMFunctionReturn(0);
}
auto dm = simple->getDM();
if (data.with_contact && data.with_plasticity) {
CHKERR set_contact_dm(mField, dm, dmContact);
CHKERR set_plastic_ep_dm(mField, dmContact, dmEP);
CHKERR set_plastic_tau_dm(mField, dmEP, dmTAU);
} else if (data.with_plasticity) {
CHKERR set_plastic_ep_dm(mField, dm, dmEP);
CHKERR set_plastic_tau_dm(mField, dmEP, dmTAU);
}