v0.16.0
Loading...
Searching...
No Matches
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
SetUpSchurImpl Struct Reference
Inheritance diagram for SetUpSchurImpl:
[legend]
Collaboration diagram for SetUpSchurImpl:
[legend]

Classes

struct  P_MultiGridData
 

Public Member Functions

 SetUpSchurImpl (MoFEM::Interface &m_field)
 
virtual ~SetUpSchurImpl ()=default
 
MoFEMErrorCode setUp (SmartPetscObj< KSP >)
 
 SetUpSchurImpl (MoFEM::Interface &m_field, SmartPetscObj< DM > sub_dm, SmartPetscObj< IS > field_split_is, SmartPetscObj< AO > ao_up)
 
virtual ~SetUpSchurImpl ()
 
MoFEMErrorCode setUp (TS solver)
 
MoFEMErrorCode preProc ()
 
MoFEMErrorCode postProc ()
 
 SetUpSchurImpl (MoFEM::Interface &m_field)
 
virtual ~SetUpSchurImpl ()
 
MoFEMErrorCode setUp (SmartPetscObj< TS > solver)
 
 SetUpSchurImpl (MoFEM::Interface &m_field)
 
virtual ~SetUpSchurImpl ()
 
MoFEMErrorCode setUp (SmartPetscObj< TS > solver)
 
 SetUpSchurImpl (MoFEM::Interface &m_field)
 
virtual ~SetUpSchurImpl ()=default
 
MoFEMErrorCode setUp (SmartPetscObj< KSP > solver)
 
 SetUpSchurImpl (MoFEM::Interface &m_field, EshelbianCore *ep_core_ptr)
 
virtual ~SetUpSchurImpl ()
 
MoFEMErrorCode setUp (TS ts)
 
MoFEMErrorCode preProc ()
 
MoFEMErrorCode postProc ()
 
 SetUpSchurImpl (MoFEM::Interface &m_field, SmartPetscObj< DM > sub_dm, SmartPetscObj< IS > field_split_is, SmartPetscObj< AO > ao_up)
 
virtual ~SetUpSchurImpl ()
 
MoFEMErrorCode setUp (TS solver)
 
MoFEMErrorCode preProc ()
 
MoFEMErrorCode postProc ()
 
 SetUpSchurImpl (MoFEM::Interface &m_field, SmartPetscObj< DM > sub_dm, SmartPetscObj< IS > field_split_is, SmartPetscObj< AO > ao_up)
 
virtual ~SetUpSchurImpl ()
 
MoFEMErrorCode setUp (TS solver)
 
MoFEMErrorCode preProc ()
 
MoFEMErrorCode postProc ()
 
 SetUpSchurImpl (MoFEM::Interface &m_field)
 
virtual ~SetUpSchurImpl ()
 
MoFEMErrorCode setUp (SmartPetscObj< TS > solver)
 
 SetUpSchurImpl (MoFEM::Interface &m_field)
 
virtual ~SetUpSchurImpl ()=default
 
MoFEMErrorCode setUp (SmartPetscObj< KSP > solver)
 

Private Member Functions

MoFEMErrorCode createSubDM ()
 
MoFEMErrorCode setOperator ()
 
MoFEMErrorCode setPC (PC pc)
 
MoFEMErrorCode setDiagonalPC (PC pc)
 
MoFEMErrorCode setOperator ()
 
MoFEMErrorCode setPC (PC pc)
 
SmartPetscObj< DM > createSubDM ()
 
MoFEMErrorCode setEntities ()
 
MoFEMErrorCode createSubDM ()
 
MoFEMErrorCode setOperator ()
 
MoFEMErrorCode setPC (PC pc)
 
MoFEMErrorCode setDiagonalPC (PC pc)
 
auto getSchurFields ()
 
auto getA00Fields ()
 
MoFEMErrorCode createSubDM ()
 
MoFEMErrorCode setOperator ()
 
MoFEMErrorCode setPC (PC pc)
 
MoFEMErrorCode setDiagonalPC (PC pc)
 
MoFEMErrorCode setEntities ()
 
MoFEMErrorCode createSubDM ()
 
MoFEMErrorCode setOperator ()
 
MoFEMErrorCode setPC (PC pc)
 
MoFEMErrorCode setDiagonalPC (PC pc)
 

Private Attributes

MoFEM::InterfacemField
 
SmartPetscObj< Mat > S
 
SmartPetscObj< DM > subDM
 field split sub dm
 
SmartPetscObj< IS > fieldSplitIS
 IS for split Schur block.
 
SmartPetscObj< AO > aoSchur
 
SmartPetscObj< DM > schurDM
 
SmartPetscObj< DM > blockDM
 
Range volEnts
 
Range subEnts
 
EshelbianCoreepCorePtr
 
SmartPetscObj< AO > aoS
 
boost::shared_ptr< std::vector< boost::weak_ptr< NumeredDofEntity > > > piolaZeroDofsVec
 
boost::shared_ptr< std::vector< unsigned char > > piolaZeroDofsMarker
 
boost::shared_ptr< P_MultiGridDatapMGPtr
 

Additional Inherited Members

- Static Public Member Functions inherited from SetUpSchur
static boost::shared_ptr< SetUpSchurcreateSetUpSchur (MoFEM::Interface &m_field)
 
static boost::shared_ptr< SetUpSchurcreateSetUpSchur (MoFEM::Interface &m_field, SmartPetscObj< DM > sub_dm, SmartPetscObj< IS > field_split_it, SmartPetscObj< AO > ao_map)
 Create data structure for handling Schur complement.
 
static boost::shared_ptr< SetUpSchurcreateSetUpSchur (MoFEM::Interface &m_field)
 
static boost::shared_ptr< SetUpSchurcreateSetUpSchur (MoFEM::Interface &m_field)
 
static boost::shared_ptr< SetUpSchurcreateSetUpSchur (MoFEM::Interface &m_field)
 
static boost::shared_ptr< SetUpSchurcreateSetUpSchur (MoFEM::Interface &m_field, SmartPetscObj< DM > sub_dm, SmartPetscObj< IS > field_split_it, SmartPetscObj< AO > ao_map)
 Create data structure for handling Schur complement.
 
static boost::shared_ptr< SetUpSchurcreateSetUpSchur (MoFEM::Interface &m_field, SmartPetscObj< DM > sub_dm, SmartPetscObj< IS > field_split_it, SmartPetscObj< AO > ao_map)
 Create data structure for handling Schur complement.
 
static boost::shared_ptr< SetUpSchurcreateSetUpSchur (MoFEM::Interface &m_field)
 
static boost::shared_ptr< SetUpSchurcreateSetUpSchur (MoFEM::Interface &m_field)
 
- Static Public Member Functions inherited from EshelbianCore::SetUpSchur
static boost::shared_ptr< SetUpSchurcreateSetUpSchur (MoFEM::Interface &m_field, EshelbianCore *ep_core_ptr)
 
- Protected Member Functions inherited from SetUpSchur
 SetUpSchur ()=default
 
virtual ~SetUpSchur ()=default
 
 SetUpSchur ()=default
 
 SetUpSchur ()=default
 
 SetUpSchur ()=default
 
 SetUpSchur ()=default
 
 SetUpSchur ()=default
 
 SetUpSchur ()=default
 
 SetUpSchur ()=default
 
 SetUpSchur ()=default
 
- Protected Member Functions inherited from EshelbianCore::SetUpSchur
 SetUpSchur ()=default
 

Detailed Description

Examples
mofem/atom_tests/test_broken_space.cpp, mofem/tutorials/adv-0_plasticity/plastic.cpp, mofem/tutorials/vec-10_elasticity_schur/schur_elastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 552 of file test_broken_space.cpp.

Constructor & Destructor Documentation

◆ SetUpSchurImpl() [1/10]

SetUpSchurImpl::SetUpSchurImpl ( MoFEM::Interface m_field)
inline

Definition at line 554 of file test_broken_space.cpp.

554: SetUpSchur(), mField(m_field) {}
MoFEM::Interface & mField
SetUpSchur()=default

◆ ~SetUpSchurImpl() [1/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
virtualdefault

◆ SetUpSchurImpl() [2/10]

SetUpSchurImpl::SetUpSchurImpl ( MoFEM::Interface m_field,
SmartPetscObj< DM >  sub_dm,
SmartPetscObj< IS >  field_split_is,
SmartPetscObj< AO >  ao_up 
)
inline

Definition at line 1669 of file plastic.cpp.

1671 : SetUpSchur(), mField(m_field), subDM(sub_dm),
1672 fieldSplitIS(field_split_is), aoSchur(ao_up) {
1673 if (S) {
1675 "Is expected that schur matrix is not "
1676 "allocated. This is "
1677 "possible only is if PC is set up twice");
1678 }
1679 }
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
SmartPetscObj< DM > subDM
field split sub dm
Definition plastic.cpp:1690
SmartPetscObj< Mat > S
SmartPetscObj< AO > aoSchur
Definition plastic.cpp:1692
SmartPetscObj< IS > fieldSplitIS
IS for split Schur block.
Definition plastic.cpp:1691

◆ ~SetUpSchurImpl() [2/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
inlinevirtual

Definition at line 1680 of file plastic.cpp.

1680{ S.reset(); }

◆ SetUpSchurImpl() [3/10]

SetUpSchurImpl::SetUpSchurImpl ( MoFEM::Interface m_field)
inline

Definition at line 1025 of file contact.cpp.

1025: SetUpSchur(), mField(m_field) {}

◆ ~SetUpSchurImpl() [3/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
inlinevirtual

Definition at line 1027 of file contact.cpp.

1027{}

◆ SetUpSchurImpl() [4/10]

SetUpSchurImpl::SetUpSchurImpl ( MoFEM::Interface m_field)
inline

Definition at line 990 of file incompressible_elasticity.cpp.

990: SetUpSchur(), mField(m_field) {}

◆ ~SetUpSchurImpl() [4/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
inlinevirtual

Definition at line 991 of file incompressible_elasticity.cpp.

991{ S.reset(); }

◆ SetUpSchurImpl() [5/10]

SetUpSchurImpl::SetUpSchurImpl ( MoFEM::Interface m_field)
inline

Definition at line 178 of file schur_elastic.cpp.

178 : SetUpSchur(), mField(m_field) {
179 if (S) {
182 "Is expected that schur matrix is not allocated. This is "
183 "possible only is if PC is set up twice");
184 }
185 }

◆ ~SetUpSchurImpl() [5/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
virtualdefault

◆ SetUpSchurImpl() [6/10]

SetUpSchurImpl::SetUpSchurImpl ( MoFEM::Interface m_field,
EshelbianCore ep_core_ptr 
)
inline

Definition at line 11 of file SetUpSchurImpl.cpp.

12 : SetUpSchur(), mField(m_field), epCorePtr(ep_core_ptr) {}
EshelbianCore * epCorePtr

◆ ~SetUpSchurImpl() [6/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
inlinevirtual

Definition at line 13 of file SetUpSchurImpl.cpp.

13{}

◆ SetUpSchurImpl() [7/10]

SetUpSchurImpl::SetUpSchurImpl ( MoFEM::Interface m_field,
SmartPetscObj< DM >  sub_dm,
SmartPetscObj< IS >  field_split_is,
SmartPetscObj< AO >  ao_up 
)
inline

Definition at line 5849 of file thermoplastic.cpp.

5851 : SetUpSchur(), mField(m_field), subDM(sub_dm),
5852 fieldSplitIS(field_split_is), aoSchur(ao_up) {
5853 if (S) {
5855 "Is expected that schur matrix is not "
5856 "allocated. This is "
5857 "possible only is PC is set up twice");
5858 }
5859 }

◆ ~SetUpSchurImpl() [7/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
inlinevirtual

Definition at line 5860 of file thermoplastic.cpp.

5860{ S.reset(); }

◆ SetUpSchurImpl() [8/10]

SetUpSchurImpl::SetUpSchurImpl ( MoFEM::Interface m_field,
SmartPetscObj< DM >  sub_dm,
SmartPetscObj< IS >  field_split_is,
SmartPetscObj< AO >  ao_up 
)
inline

Definition at line 1655 of file plastic.cpp.

1657 : SetUpSchur(), mField(m_field), subDM(sub_dm),
1658 fieldSplitIS(field_split_is), aoSchur(ao_up) {
1659 if (S) {
1661 "Is expected that schur matrix is not "
1662 "allocated. This is "
1663 "possible only is PC is set up twice");
1664 }
1665 }

◆ ~SetUpSchurImpl() [8/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
inlinevirtual

Definition at line 1666 of file plastic.cpp.

1666{ S.reset(); }

◆ SetUpSchurImpl() [9/10]

SetUpSchurImpl::SetUpSchurImpl ( MoFEM::Interface m_field)
inline

Definition at line 1018 of file contact.cpp.

1018: SetUpSchur(), mField(m_field) {}

◆ ~SetUpSchurImpl() [9/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
inlinevirtual

Definition at line 1020 of file contact.cpp.

1020{}

◆ SetUpSchurImpl() [10/10]

SetUpSchurImpl::SetUpSchurImpl ( MoFEM::Interface m_field)
inline

Definition at line 756 of file elastic.cpp.

756 : SetUpSchur(), mField(m_field) {
757 if (S) {
760 "Is expected that schur matrix is not allocated. This is "
761 "possible only is PC is set up twice");
762 }
763 }

◆ ~SetUpSchurImpl() [10/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
virtualdefault

Member Function Documentation

◆ createSubDM() [1/5]

MoFEMErrorCode SetUpSchurImpl::createSubDM ( )
private
Examples
mofem/tutorials/vec-10_elasticity_schur/schur_elastic.cpp.

Definition at line 1119 of file contact.cpp.

1119 {
1121 auto simple = mField.getInterface<Simple>();
1122
1123 auto create_dm = [&](const char *name, const char *field_name, auto dm_type) {
1124 auto dm = createDM(mField.get_comm(), dm_type);
1125 auto create_dm_imp = [&]() {
1127 CHKERR DMMoFEMCreateSubDM(dm, simple->getDM(), name);
1128 CHKERR DMMoFEMSetSquareProblem(dm, PETSC_TRUE);
1129 CHKERR DMMoFEMAddElement(dm, simple->getDomainFEName());
1132 CHKERR DMSetUp(dm);
1134 };
1136 create_dm_imp(),
1137 "Error in creating schurDM. It is possible that schurDM is "
1138 "already created");
1139 return dm;
1140 };
1141
1142 // Note: here we can make block with bubbles of "U" and "SIGMA" fields. See
1143 // vec-0_elasticity where bubbles are added.
1144
1145 schurDM = create_dm("SCHUR", "U", "DMMOFEM_MG");
1146 blockDM = create_dm("BLOCK", "SIGMA", "DMMOFEM");
1147
1148 if constexpr (AT == AssemblyType::BLOCK_SCHUR) {
1149
1150 auto get_nested_mat_data = [&](auto schur_dm, auto block_dm) {
1151 auto block_mat_data = createBlockMatStructure(
1152 simple->getDM(),
1153
1154 {{
1155
1156 simple->getDomainFEName(),
1157
1158 {
1159
1160 {"U", "U"}, {"SIGMA", "U"}, {"U", "SIGMA"}, {"SIGMA", "SIGMA"}
1161
1162 }}}
1163
1164 );
1165
1167
1168 {schur_dm, block_dm}, block_mat_data,
1169
1170 {"SIGMA"}, {nullptr}, true
1171
1172 );
1173 };
1174
1175 auto nested_mat_data = get_nested_mat_data(schurDM, blockDM);
1176 CHKERR DMMoFEMSetNestSchurData(simple->getDM(), nested_mat_data);
1177
1178 } else {
1179 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1180 "Only BLOCK_SCHUR is implemented");
1181 }
1182
1184}
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
Definition DMMoFEM.cpp:215
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition DMMoFEM.cpp:488
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
Definition DMMoFEM.cpp:450
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
Definition DMMoFEM.cpp:238
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
Definition DMMoFEM.cpp:280
boost::shared_ptr< BlockStructure > createBlockMatStructure(DM dm, SchurFEOpsFEandFields schur_fe_op_vec)
Create a Mat Diag Blocks object.
Definition Schur.cpp:1082
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.
Definition Schur.cpp:2433
MoFEMErrorCode DMMoFEMSetNestSchurData(DM dm, boost::shared_ptr< NestSchurData >)
Definition DMMoFEM.cpp:1555
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
constexpr auto field_name
virtual MPI_Comm & get_comm() const =0
Simple interface for fast problem set-up.
Definition Simple.hpp:27
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
SmartPetscObj< DM > schurDM
Definition contact.cpp:1040
SmartPetscObj< DM > blockDM
Definition contact.cpp:1041
constexpr AssemblyType AT

◆ createSubDM() [2/5]

SmartPetscObj< DM > SetUpSchurImpl::createSubDM ( )
private

◆ createSubDM() [3/5]

MoFEMErrorCode SetUpSchurImpl::createSubDM ( )
private

◆ createSubDM() [4/5]

MoFEMErrorCode SetUpSchurImpl::createSubDM ( )
private

◆ createSubDM() [5/5]

MoFEMErrorCode SetUpSchurImpl::createSubDM ( )
private

◆ getA00Fields()

auto SetUpSchurImpl::getA00Fields ( )
inlineprivate

Definition at line 60 of file SetUpSchurImpl.cpp.

60 {
61 std::vector<std::string> a00_field_list{
62
64
66
68
70
72
73 };
74 std::vector<boost::shared_ptr<Range>> range_list_ptr(a00_field_list.size(),
75 nullptr);
76 return std::make_pair(a00_field_list, range_list_ptr);
77 }
const std::string spatialL2Disp
const std::string piolaStress
const std::string bubbleField
const std::string rotAxis
const std::string stretchTensor

◆ getSchurFields()

auto SetUpSchurImpl::getSchurFields ( )
inlineprivate

Definition at line 53 of file SetUpSchurImpl.cpp.

53 {
54 std::vector<std::string> schur_field_list{epCorePtr->hybridSpatialDisp,
56 std::vector<boost::shared_ptr<Range>> dm_range_list{nullptr, nullptr};
57 return std::make_pair(schur_field_list, dm_range_list);
58 };
const std::string contactDisp
const std::string hybridSpatialDisp

◆ postProc() [1/4]

MoFEMErrorCode SetUpSchurImpl::postProc ( )

◆ postProc() [2/4]

MoFEMErrorCode SetUpSchurImpl::postProc ( )

◆ postProc() [3/4]

MoFEMErrorCode SetUpSchurImpl::postProc ( )

◆ postProc() [4/4]

MoFEMErrorCode SetUpSchurImpl::postProc ( )

◆ preProc() [1/4]

MoFEMErrorCode SetUpSchurImpl::preProc ( )

◆ preProc() [2/4]

MoFEMErrorCode SetUpSchurImpl::preProc ( )

◆ preProc() [3/4]

MoFEMErrorCode SetUpSchurImpl::preProc ( )

◆ preProc() [4/4]

MoFEMErrorCode SetUpSchurImpl::preProc ( )

◆ setDiagonalPC() [1/4]

MoFEMErrorCode SetUpSchurImpl::setDiagonalPC ( PC  pc)
private
Examples
mofem/tutorials/vec-10_elasticity_schur/schur_elastic.cpp.

Definition at line 1269 of file contact.cpp.

1269 {
1271 KSP *subksp;
1272 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
1273 auto get_pc = [](auto ksp) {
1274 PC pc_raw;
1275 CHKERR KSPGetPC(ksp, &pc_raw);
1276 return SmartPetscObj<PC>(pc_raw, true); // bump reference
1277 };
1278 CHKERR setSchurA00MatSolvePC(get_pc(subksp[0]));
1279
1280 auto set_pc_p_mg = [](auto dm, auto pc, auto S) {
1282 CHKERR PCSetDM(pc, dm);
1283 PetscBool same = PETSC_FALSE;
1284 PetscObjectTypeCompare((PetscObject)pc, PCMG, &same);
1285 if (same) {
1287 pc, createPCMGSetUpViaApproxOrdersCtx(dm, S, true));
1288 CHKERR PCSetFromOptions(pc);
1289 }
1291 };
1292
1293 auto set_pc_ksp = [&](auto dm, auto pc, auto S) {
1295 PetscBool same = PETSC_FALSE;
1296 PetscObjectTypeCompare((PetscObject)pc, PCKSP, &same);
1297 if (same) {
1298 CHKERR PCSetFromOptions(pc);
1299 KSP inner_ksp;
1300 CHKERR PCKSPGetKSP(pc, &inner_ksp);
1301 CHKERR KSPSetFromOptions(inner_ksp);
1302 PC inner_pc;
1303 CHKERR KSPGetPC(inner_ksp, &inner_pc);
1304 CHKERR PCSetFromOptions(inner_pc);
1305 CHKERR set_pc_p_mg(dm, inner_pc, S);
1306 }
1308 };
1309
1310 CHKERR set_pc_ksp(schurDM, get_pc(subksp[1]), S);
1311 CHKERR set_pc_p_mg(schurDM, get_pc(subksp[1]), S);
1312
1313 CHKERR PetscFree(subksp);
1315}
MoFEMErrorCode setSchurA00MatSolvePC(SmartPetscObj< PC > pc)
Set PC for A00 block.
Definition Schur.cpp:2717
boost::shared_ptr< PCMGSetUpViaApproxOrdersCtx > createPCMGSetUpViaApproxOrdersCtx(DM dm, Mat A, bool use_shell_mat)
createPCMGSetUpViaApproxOrdersCtx
MoFEMErrorCode PCMGSetUpViaApproxOrders(PC pc, boost::shared_ptr< PCMGSetUpViaApproxOrdersCtx > ctx, int verb)
Function build MG structure.
intrusive_ptr for managing petsc objects

◆ setDiagonalPC() [2/4]

MoFEMErrorCode SetUpSchurImpl::setDiagonalPC ( PC  pc)
private

◆ setDiagonalPC() [3/4]

MoFEMErrorCode SetUpSchurImpl::setDiagonalPC ( PC  pc)
private

◆ setDiagonalPC() [4/4]

MoFEMErrorCode SetUpSchurImpl::setDiagonalPC ( PC  pc)
private

◆ setEntities() [1/2]

MoFEMErrorCode SetUpSchurImpl::setEntities ( )
private
Examples
mofem/tutorials/vec-10_elasticity_schur/schur_elastic.cpp.

Definition at line 251 of file schur_elastic.cpp.

251 {
254 CHKERR mField.get_moab().get_entities_by_dimension(simple->getMeshset(),
256 CHKERR mField.get_moab().get_entities_by_handle(simple->getMeshset(),
257 subEnts);
258 subEnts = subtract(subEnts, volEnts);
260};
virtual moab::Interface & get_moab()=0
constexpr int SPACE_DIM
[Define dimension]
Definition elastic.cpp:18

◆ setEntities() [2/2]

MoFEMErrorCode SetUpSchurImpl::setEntities ( )
private

◆ setOperator() [1/5]

MoFEMErrorCode SetUpSchurImpl::setOperator ( )
private
Examples
mofem/tutorials/vec-10_elasticity_schur/schur_elastic.cpp.

Definition at line 1186 of file contact.cpp.

1186 {
1188
1189 double eps_stab = 1e-4;
1190 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-eps_stab", &eps_stab,
1191 PETSC_NULLPTR);
1192
1195 using OpMassStab = B::OpMass<3, SPACE_DIM * SPACE_DIM>;
1196
1197 auto simple = mField.getInterface<Simple>();
1198 auto pip = mField.getInterface<PipelineManager>();
1199
1200 auto dm_is = getDMSubData(schurDM)->getSmartRowIs();
1201 auto ao_up = createAOMappingIS(dm_is, PETSC_NULLPTR);
1202
1203 // Boundary
1204 pip->getOpBoundaryLhsPipeline().push_front(createOpSchurAssembleBegin());
1205 pip->getOpBoundaryLhsPipeline().push_back(
1206 new OpMassStab("SIGMA", "SIGMA",
1207 [eps_stab](double, double, double) { return eps_stab; }));
1208 pip->getOpBoundaryLhsPipeline().push_back(
1209
1210 createOpSchurAssembleEnd({"SIGMA"}, {nullptr}, ao_up, S, false, false)
1211
1212 );
1213
1214 // Domain
1215 pip->getOpDomainLhsPipeline().push_front(createOpSchurAssembleBegin());
1216 pip->getOpDomainLhsPipeline().push_back(
1217
1218 createOpSchurAssembleEnd({"SIGMA"}, {nullptr}, ao_up, S, false, false)
1219
1220 );
1221
1222 auto pre_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
1223 auto post_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
1224
1225 pre_proc_schur_lhs_ptr->preProcessHook = [this]() {
1227 CHKERR MatZeroEntries(S);
1228 MOFEM_LOG("CONTACT", Sev::verbose) << "Lhs Assemble Begin";
1230 };
1231
1232 post_proc_schur_lhs_ptr->postProcessHook = [this, ao_up,
1233 post_proc_schur_lhs_ptr]() {
1235 MOFEM_LOG("CONTACT", Sev::verbose) << "Lhs Assemble End";
1236 [[maybe_unused]] auto print_mat_norm = [this](auto a, std::string prefix) {
1238 double nrm;
1239 CHKERR MatNorm(a, NORM_FROBENIUS, &nrm);
1240 MOFEM_LOG("CONTACT", Sev::noisy) << prefix << " norm = " << nrm;
1242 };
1243 CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
1244 CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
1246 mField, post_proc_schur_lhs_ptr, 1, S, ao_up)();
1247#ifndef NDEBUG
1248 CHKERR print_mat_norm(S, "S");
1249#endif // NDEBUG
1250 MOFEM_LOG("CONTACT", Sev::verbose) << "Lhs Assemble Finish";
1252 };
1253
1254 auto ts_ctx_ptr = getDMTsCtx(simple->getDM());
1255 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_schur_lhs_ptr);
1256 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_schur_lhs_ptr);
1257
1259}
constexpr double a
@ BLOCK_PRECONDITIONER_SCHUR
Block preconditioner Schur assembly.
#define MOFEM_LOG(channel, severity)
Log.
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
Definition DMMoFEM.hpp:1279
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.
Definition Schur.cpp:2675
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
auto getDMSubData(DM dm)
Get sub problem data structure.
Definition DMMoFEM.hpp:1295
auto createAOMappingIS(IS isapp, IS ispetsc)
Creates an application mapping using two index sets.
OpSchurAssembleBase * createOpSchurAssembleBegin()
Definition Schur.cpp:2670
Class (Function) to enforce essential constrains on the left hand side diagonal.
Definition Essential.hpp:33
PipelineManager interface.

◆ setOperator() [2/5]

MoFEMErrorCode SetUpSchurImpl::setOperator ( )
private

◆ setOperator() [3/5]

MoFEMErrorCode SetUpSchurImpl::setOperator ( )
private

◆ setOperator() [4/5]

MoFEMErrorCode SetUpSchurImpl::setOperator ( )
private

◆ setOperator() [5/5]

MoFEMErrorCode SetUpSchurImpl::setOperator ( )
private

◆ setPC() [1/5]

MoFEMErrorCode SetUpSchurImpl::setPC ( PC  pc)
private
Examples
mofem/tutorials/vec-10_elasticity_schur/schur_elastic.cpp.

Definition at line 1261 of file contact.cpp.

1261 {
1263 auto block_is = getDMSubData(blockDM)->getSmartRowIs();
1264 CHKERR PCFieldSplitSetIS(pc, NULL, block_is);
1265 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER, S);
1267}

◆ setPC() [2/5]

MoFEMErrorCode SetUpSchurImpl::setPC ( PC  pc)
private

◆ setPC() [3/5]

MoFEMErrorCode SetUpSchurImpl::setPC ( PC  pc)
private

◆ setPC() [4/5]

MoFEMErrorCode SetUpSchurImpl::setPC ( PC  pc)
private

◆ setPC() [5/5]

MoFEMErrorCode SetUpSchurImpl::setPC ( PC  pc)
private

◆ setUp() [1/10]

MoFEMErrorCode SetUpSchurImpl::setUp ( SmartPetscObj< KSP >  solver)
virtual

Implements SetUpSchur.

◆ setUp() [2/10]

MoFEMErrorCode SetUpSchurImpl::setUp ( SmartPetscObj< KSP >  solver)
virtual

Implements SetUpSchur.

◆ setUp() [3/10]

MoFEMErrorCode SetUpSchurImpl::setUp ( SmartPetscObj< KSP >  ksp)
virtual

Implements SetUpSchur.

Examples
mofem/atom_tests/test_broken_space.cpp, mofem/tutorials/adv-0_plasticity/plastic.cpp, mofem/tutorials/vec-10_elasticity_schur/schur_elastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 565 of file test_broken_space.cpp.

565 {
568 auto pip_mng = mField.getInterface<PipelineManager>();
569
570 CHKERR KSPSetFromOptions(ksp);
571 PC pc;
572 CHKERR KSPGetPC(ksp, &pc);
573
574 PetscBool is_pcfs = PETSC_FALSE;
575 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
576 if (is_pcfs) {
577
578 MOFEM_LOG("AT", Sev::inform) << "Setup Schur pc";
579
580 auto create_sub_dm = [&]() {
582
583 auto create_dm = [&](
584
585 std::string problem_name,
586 std::vector<std::string> fe_names,
587 std::vector<std::string> fields,
588
589 auto dm_type
590
591 ) {
592 auto dm = createDM(mField.get_comm(), dm_type);
593 auto create_dm_imp = [&]() {
595 CHKERR DMMoFEMCreateSubDM(dm, simple->getDM(), problem_name.c_str());
596 CHKERR DMMoFEMSetSquareProblem(dm, PETSC_TRUE);
597 for (auto fe : fe_names) {
599 }
600 CHKERR DMMoFEMAddElement(dm, simple->getSkeletonFEName());
601 for (auto field : fields) {
602 CHKERR DMMoFEMAddSubFieldRow(dm, field);
603 CHKERR DMMoFEMAddSubFieldCol(dm, field);
604 }
605 CHKERR DMSetUp(dm);
607 };
609 create_dm_imp(),
610 "Error in creating schurDM. It is possible that schurDM is "
611 "already created");
612 return dm;
613 };
614
615 auto schur_dm = create_dm(
616
617 "SCHUR",
618
619 {simple->getDomainFEName(), simple->getSkeletonFEName()},
620
621 {"HYBRID"},
622
623 "DMMOFEM_MG");
624
625 auto block_dm = create_dm(
626
627 "BLOCK",
628
629 {simple->getDomainFEName(), simple->getSkeletonFEName()},
630
631 {"BROKEN", "U"},
632
633 "DMMOFEM");
634
635 return std::make_tuple(schur_dm, block_dm);
636 };
637
638 auto get_nested_mat_data = [&](auto schur_dm, auto block_dm) {
639 auto block_mat_data = createBlockMatStructure(
640 simple->getDM(),
641
642 {
643
644 {
645
646 simple->getDomainFEName(),
647
648 {
649
650 {"BROKEN", "BROKEN"},
651 {"U", "U"},
652 {"BROKEN", "U"},
653 {"U", "BROKEN"}
654
655 }
656
657 },
658
659 {
660
661 simple->getSkeletonFEName(),
662
663 {
664
665 {"BROKEN", "HYBRID"}, {"HYBRID", "BROKEN"}
666
667 }
668
669 }
670
671 }
672
673 );
674
676
677 {schur_dm, block_dm}, block_mat_data,
678
679 {"BROKEN", "U"}, {nullptr, nullptr}, true
680
681 );
682 };
683
684 auto set_ops = [&](auto schur_dm) {
686 auto dm_is = getDMSubData(schur_dm)->getSmartRowIs();
687 auto ao_up = createAOMappingIS(dm_is, PETSC_NULLPTR);
688
689 boost::shared_ptr<BlockStructure> block_data;
690 CHKERR DMMoFEMGetBlocMatData(simple->getDM(), block_data);
691
692 if (AT == BLOCK_SCHUR) {
693 pip_mng->getOpDomainLhsPipeline().push_front(
695 pip_mng->getOpDomainLhsPipeline().push_back(
696
697 createOpSchurAssembleEnd({"BROKEN", "U"}, {nullptr, nullptr}, ao_up,
698 S, true, true)
699
700 );
701 }
702
703 auto pre_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
704 auto post_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
705
706 pre_proc_schur_lhs_ptr->preProcessHook = [this]() {
708 CHKERR MatZeroEntries(S);
709 MOFEM_LOG("AT", Sev::verbose) << "Lhs Assemble Begin";
711 };
712
713 post_proc_schur_lhs_ptr->postProcessHook = [this, ao_up,
714 post_proc_schur_lhs_ptr]() {
716 MOFEM_LOG("AT", Sev::verbose) << "Lhs Assemble End";
717
718 if (AT == BLOCK_SCHUR) {
719 CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
720 CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
721 if (1) {
722 auto S_from_block = matDuplicate(S, MAT_SHARE_NONZERO_PATTERN);
723 // Create matrix from block mat
724 CHKERR assembleBlockMatSchur(mField, post_proc_schur_lhs_ptr->B,
725 S_from_block, {"BROKEN", "U"},
726 {nullptr, nullptr}, ao_up);
727 CHKERR MatAssemblyBegin(S_from_block, MAT_FINAL_ASSEMBLY);
728 CHKERR MatAssemblyEnd(S_from_block, MAT_FINAL_ASSEMBLY);
729 CHKERR MatAYPX(S_from_block, -1, S, DIFFERENT_NONZERO_PATTERN);
730 double norm;
731 CHKERR MatNorm(S_from_block, NORM_FROBENIUS, &norm);
732 MOFEM_LOG("AT", Sev::inform) << "Norm of difference: " << norm;
733 if (norm > 1e-6)
734 SETERRQ(
735 PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
736 "Norm of difference between Schur and block matrix is larger "
737 "than accepted");
738 }
739 } else {
740 CHKERR assembleBlockMatSchur(mField, post_proc_schur_lhs_ptr->B, S,
741 {"BROKEN", "U"}, {nullptr, nullptr}, ao_up);
742 CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
743 CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
744 }
745
746 MOFEM_LOG("AT", Sev::verbose) << "Lhs Assemble Finish";
748 };
749
750 auto ksp_ctx_ptr = getDMKspCtx(simple->getDM());
751 ksp_ctx_ptr->getPreProcSetOperators().push_front(pre_proc_schur_lhs_ptr);
752 ksp_ctx_ptr->getPostProcSetOperators().push_back(post_proc_schur_lhs_ptr);
753
755 };
756
757 auto set_pc = [&](auto pc, auto block_dm) {
759 auto block_is = getDMSubData(block_dm)->getSmartRowIs();
760 CHKERR PCFieldSplitSetIS(pc, NULL, block_is);
761 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER, S);
763 };
764
765
766
767 auto [schur_dm, block_dm] = create_sub_dm();
768 if (AT == BLOCK_SCHUR || AT == BLOCK_MAT) {
769 auto nested_mat_data = get_nested_mat_data(schur_dm, block_dm);
770 CHKERR DMMoFEMSetNestSchurData(simple->getDM(), nested_mat_data);
771 }
772 S = createDMHybridisedL2Matrix(schur_dm);
773 CHKERR MatSetDM(S, PETSC_NULLPTR);
774
775 int bs = (SPACE_DIM == 2) ? NBEDGE_L2(hybrid_approx_order)
777 CHKERR MatSetBlockSize(S, bs);
778
779 CHKERR set_ops(schur_dm);
780 CHKERR set_pc(pc, block_dm);
781 DM solver_dm;
782 CHKERR KSPGetDM(ksp, &solver_dm);
783 if (AT == BLOCK_SCHUR || AT == BLOCK_MAT)
784 CHKERR DMSetMatType(solver_dm, MATSHELL);
785
786 auto get_pc = [](auto ksp) {
787 PC pc_raw;
788 CHKERR KSPGetPC(ksp, &pc_raw);
789 return pc_raw;
790 };
791
792 auto set_diagonal_pc = [&](auto pc) {
794
795 if (AT == BLOCK_SCHUR || AT == BLOCK_MAT) {
796 auto A = createDMBlockMat(simple->getDM());
797 auto P = createDMNestSchurMat(simple->getDM());
798 CHKERR PCSetOperators(pc, A, P);
799 }
800
801 KSP *subksp;
802 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
803 CHKERR setSchurA00MatSolvePC(SmartPetscObj<PC>(get_pc(subksp[0]), true));
804
805 CHKERR PetscFree(subksp);
807 };
808
809 auto set_mg_for_schur_complement = [&](auto pc, auto schur_dm, auto S) {
811
812 KSP *subksp;
813 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
814 auto subpc = get_pc(subksp[1]);
815
816 auto set_pc_p_mg = [](auto dm, auto pc, auto S) {
818 CHKERR PCSetDM(pc, dm);
819 PetscBool same = PETSC_FALSE;
820 PetscObjectTypeCompare((PetscObject)pc, PCMG, &same);
821 if (same) {
822 MOFEM_LOG("TIMER", Sev::inform) << "Set up MG";
824 pc, createPCMGSetUpViaApproxOrdersCtx(dm, S, true));
825 CHKERR PCSetFromOptions(pc);
826 }
828 };
829
830 PetscBool same = PETSC_FALSE;
831 PetscObjectTypeCompare((PetscObject)subpc, PCKSP, &same);
832 if (same) {
833 CHKERR PCSetFromOptions(subpc);
834 KSP inner_ksp;
835 CHKERR PCKSPGetKSP(subpc, &inner_ksp);
836 CHKERR KSPSetFromOptions(inner_ksp);
837 PC inner_pc;
838 CHKERR KSPGetPC(inner_ksp, &inner_pc);
839 CHKERR PCSetFromOptions(inner_pc);
840 CHKERR set_pc_p_mg(schur_dm, inner_pc, S);
841 }
842
843 CHKERR PetscFree(subksp);
845 };
846
847 CHKERR KSPSetUp(ksp);
848 if (AT == BLOCK_SCHUR || AT == BLOCK_MAT) {
849 CHKERR set_diagonal_pc(pc);
850 CHKERR set_mg_for_schur_complement(pc, schur_dm, S);
851 }
852
853 } else {
854 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
855 "PC is not set to PCFIELDSPLIT");
856 }
858}
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
@ BLOCK_MAT
Block matrix assembly.
@ BLOCK_SCHUR
Block Schur assembly.
#define NBFACETRI_L2(P)
Number of base functions on triangle for L2 space.
#define NBEDGE_L2(P)
Number of base functions on edge from L2 space.
MoFEMErrorCode DMMoFEMGetBlocMatData(DM dm, boost::shared_ptr< BlockStructure > &)
Get data for block mat.
Definition DMMoFEM.cpp:1535
auto getDMKspCtx(DM dm)
Get KSP context data structure used by DM.
Definition DMMoFEM.hpp:1251
auto createDMHybridisedL2Matrix(DM dm)
Get smart hybridised L2 matrix from DM.
Definition DMMoFEM.hpp:1207
SmartPetscObj< Mat > matDuplicate(Mat mat, MatDuplicateOption op)
auto createDMNestSchurMat(DM dm)
Definition DMMoFEM.hpp:1221
MoFEMErrorCode assembleBlockMatSchur(MoFEM::Interface &m_field, Mat B, Mat S, std::vector< std::string > fields_name, std::vector< boost::shared_ptr< Range > > field_ents, SmartPetscObj< AO > ao)
Assemble Schur matrix.
Definition Schur.cpp:1907
auto createDMBlockMat(DM dm)
Definition DMMoFEM.hpp:1214
int hybrid_approx_order
constexpr AssemblyType A
[Define dimension]
Definition elastic.cpp:21

◆ setUp() [4/10]

MoFEMErrorCode SetUpSchurImpl::setUp ( SmartPetscObj< TS >  solver)
virtual

Implements SetUpSchur.

Definition at line 1044 of file contact.cpp.

1044 {
1046 auto simple = mField.getInterface<Simple>();
1047 auto pip = mField.getInterface<PipelineManager>();
1048
1049 SNES snes;
1050 CHKERR TSGetSNES(solver, &snes);
1051 KSP ksp;
1052 CHKERR SNESGetKSP(snes, &ksp);
1053 CHKERR KSPSetFromOptions(ksp);
1054
1055 PC pc;
1056 CHKERR KSPGetPC(ksp, &pc);
1057
1058 PetscBool is_pcfs = PETSC_FALSE;
1059 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
1060 if (is_pcfs) {
1061
1062 MOFEM_LOG("CONTACT", Sev::inform) << "Setup Schur pc";
1063
1064 if (S) {
1067 "It is expected that Schur matrix is not allocated. This is "
1068 "possible only if PC is set up twice");
1069 }
1070
1072
1073 // Add data to DM storage
1075 CHKERR MatSetBlockSize(S, SPACE_DIM);
1076 // CHKERR MatSetOption(S, MAT_SYMMETRIC, PETSC_TRUE);
1077
1078 // Set DM to use shell block matrix
1079 DM solver_dm;
1080 CHKERR TSGetDM(solver, &solver_dm);
1081 CHKERR DMSetMatType(solver_dm, MATSHELL);
1082
1083 auto ts_ctx_ptr = getDMTsCtx(solver_dm);
1084 auto A = createDMBlockMat(simple->getDM());
1085 auto P = createDMNestSchurMat(simple->getDM());
1086
1087 if (is_quasi_static == PETSC_TRUE) {
1088 auto swap_assemble = [](TS ts, PetscReal t, Vec u, Vec u_t, PetscReal a,
1089 Mat A, Mat B, void *ctx) {
1090 return TsSetIJacobian(ts, t, u, u_t, a, B, A, ctx);
1091 };
1092 CHKERR TSSetIJacobian(solver, A, P, swap_assemble, ts_ctx_ptr.get());
1093 } else {
1094 auto swap_assemble = [](TS ts, PetscReal t, Vec u, Vec u_t, Vec utt,
1095 PetscReal a, PetscReal aa, Mat A, Mat B,
1096 void *ctx) {
1097 return TsSetI2Jacobian(ts, t, u, u_t, utt, a, aa, B, A, ctx);
1098 };
1099 CHKERR TSSetI2Jacobian(solver, A, P, swap_assemble, ts_ctx_ptr.get());
1100 }
1101 CHKERR KSPSetOperators(ksp, A, P);
1102
1104 CHKERR setPC(pc);
1105 CHKERR TSSetUp(solver);
1106 CHKERR KSPSetUp(ksp);
1108
1109 } else {
1110 MOFEM_LOG("CONTACT", Sev::inform) << "No Schur PC";
1111 pip->getOpBoundaryLhsPipeline().push_front(createOpSchurAssembleBegin());
1112 pip->getOpBoundaryLhsPipeline().push_back(createOpSchurAssembleEnd({}, {}));
1113 pip->getOpDomainLhsPipeline().push_front(createOpSchurAssembleBegin());
1114 pip->getOpDomainLhsPipeline().push_back(createOpSchurAssembleEnd({}, {}));
1115 }
1117}
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition DMMoFEM.hpp:1194
const FTensor::Tensor2< T, Dim, Dim > Vec
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.
Definition TsCtx.cpp:169
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.
Definition TsCtx.cpp:519
constexpr double t
plate stiffness
Definition plate.cpp:58
MoFEMErrorCode createSubDM()
Definition contact.cpp:1119
MoFEMErrorCode setDiagonalPC(PC pc)
Definition contact.cpp:1269
MoFEMErrorCode setPC(PC pc)
Definition contact.cpp:1261
MoFEMErrorCode setOperator()
Definition contact.cpp:1186
PetscBool is_quasi_static
Definition plastic.cpp:144

◆ setUp() [5/10]

MoFEMErrorCode SetUpSchurImpl::setUp ( SmartPetscObj< TS >  solver)
virtual

Implements SetUpSchur.

◆ setUp() [6/10]

MoFEMErrorCode SetUpSchurImpl::setUp ( SmartPetscObj< TS >  solver)
virtual

Implements SetUpSchur.

◆ setUp() [7/10]

MoFEMErrorCode SetUpSchurImpl::setUp ( TS  solver)
virtual

Implements SetUpSchur.

Definition at line 1695 of file plastic.cpp.

1695 {
1697 auto simple = mField.getInterface<Simple>();
1698 auto pip_mng = mField.getInterface<PipelineManager>();
1699
1700 SNES snes;
1701 CHKERR TSGetSNES(solver, &snes);
1702 KSP ksp;
1703 CHKERR SNESGetKSP(snes, &ksp);
1704 CHKERR KSPSetFromOptions(ksp);
1705
1706 PC pc;
1707 CHKERR KSPGetPC(ksp, &pc);
1708 PetscBool is_pcfs = PETSC_FALSE;
1709 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
1710 if (is_pcfs) {
1711 if (S) {
1713 "Is expected that schur matrix is not "
1714 "allocated. This is "
1715 "possible only is if PC is set up twice");
1716 }
1717
1719 CHKERR MatSetBlockSize(S, SPACE_DIM);
1720
1721 // Set DM to use shell block matrix
1722 DM solver_dm;
1723 CHKERR TSGetDM(solver, &solver_dm);
1724 CHKERR DMSetMatType(solver_dm, MATSHELL);
1725
1726 auto ts_ctx_ptr = getDMTsCtx(solver_dm);
1727 auto A = createDMBlockMat(simple->getDM());
1728 auto P = createDMNestSchurMat(simple->getDM());
1729
1730 if (is_quasi_static == PETSC_TRUE) {
1731 auto swap_assemble = [](TS ts, PetscReal t, Vec u, Vec u_t, PetscReal a,
1732 Mat A, Mat B, void *ctx) {
1733 return TsSetIJacobian(ts, t, u, u_t, a, B, A, ctx);
1734 };
1735 CHKERR TSSetIJacobian(solver, A, P, swap_assemble, ts_ctx_ptr.get());
1736 } else {
1737 auto swap_assemble = [](TS ts, PetscReal t, Vec u, Vec u_t, Vec utt,
1738 PetscReal a, PetscReal aa, Mat A, Mat B,
1739 void *ctx) {
1740 return TsSetI2Jacobian(ts, t, u, u_t, utt, a, aa, B, A, ctx);
1741 };
1742 CHKERR TSSetI2Jacobian(solver, A, P, swap_assemble, ts_ctx_ptr.get());
1743 }
1744 CHKERR KSPSetOperators(ksp, A, P);
1745
1746 auto set_ops = [&]() {
1748 auto pip_mng = mField.getInterface<PipelineManager>();
1749
1750#ifndef ADD_CONTACT
1751 // Boundary
1752 pip_mng->getOpBoundaryLhsPipeline().push_front(
1754 pip_mng->getOpBoundaryLhsPipeline().push_back(createOpSchurAssembleEnd(
1755
1756 {"EP", "TAU"}, {nullptr, nullptr}, aoSchur, S, false, false
1757
1758 ));
1759 // Domain
1760 pip_mng->getOpDomainLhsPipeline().push_front(
1762 pip_mng->getOpDomainLhsPipeline().push_back(createOpSchurAssembleEnd(
1763
1764 {"EP", "TAU"}, {nullptr, nullptr}, aoSchur, S, false, false
1765
1766 ));
1767#else
1768
1769 double eps_stab = 1e-4;
1770 CHKERR PetscOptionsGetScalar(PETSC_NULLPTR, "", "-eps_stab", &eps_stab,
1771 PETSC_NULLPTR);
1772
1775 using OpMassStab = B::OpMass<3, SPACE_DIM * SPACE_DIM>;
1776
1777 // Boundary
1778 pip_mng->getOpBoundaryLhsPipeline().push_front(
1780 pip_mng->getOpBoundaryLhsPipeline().push_back(
1781 new OpMassStab("SIGMA", "SIGMA", [eps_stab](double, double, double) {
1782 return eps_stab;
1783 }));
1784 pip_mng->getOpBoundaryLhsPipeline().push_back(createOpSchurAssembleEnd(
1785
1786 {"SIGMA", "EP", "TAU"}, {nullptr, nullptr, nullptr}, aoSchur, S,
1787 false, false
1788
1789 ));
1790 // Domain
1791 pip_mng->getOpDomainLhsPipeline().push_front(
1793 pip_mng->getOpDomainLhsPipeline().push_back(createOpSchurAssembleEnd(
1794
1795 {"SIGMA", "EP", "TAU"}, {nullptr, nullptr, nullptr}, aoSchur, S,
1796 false, false
1797
1798 ));
1799#endif // ADD_CONTACT
1801 };
1802
1803 auto set_assemble_elems = [&]() {
1805 auto schur_asmb_pre_proc = boost::make_shared<FEMethod>();
1806 schur_asmb_pre_proc->preProcessHook = [this]() {
1808 CHKERR MatZeroEntries(S);
1809 MOFEM_LOG("TIMER", Sev::verbose) << "Lhs Assemble Begin";
1811 };
1812 auto schur_asmb_post_proc = boost::make_shared<FEMethod>();
1813 auto weak_schur_asmb_post_proc = boost::weak_ptr<FEMethod>(
1814 schur_asmb_post_proc); // fe method passed to lambda, have to be weak ptr to avoid circular shared ptr reference
1815
1816 schur_asmb_post_proc->postProcessHook = [this,
1817 weak_schur_asmb_post_proc]() {
1819 MOFEM_LOG("TIMER", Sev::verbose) << "Lhs Assemble End";
1820
1821 // Apply essential constrains to Schur complement
1822 CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
1823 CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
1825 mField, weak_schur_asmb_post_proc.lock(), 1, S, aoSchur)();
1826
1828 };
1829 auto ts_ctx_ptr = getDMTsCtx(simple->getDM());
1830 ts_ctx_ptr->getPreProcessIJacobian().push_front(schur_asmb_pre_proc);
1831 ts_ctx_ptr->getPostProcessIJacobian().push_front(schur_asmb_post_proc);
1833 };
1834
1835 auto set_pc = [&]() {
1837 CHKERR PCFieldSplitSetIS(pc, NULL, fieldSplitIS);
1838 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER, S);
1840 };
1841
1842 auto set_diagonal_pc = [&]() {
1844 KSP *subksp;
1845 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
1846 auto get_pc = [](auto ksp) {
1847 PC pc_raw;
1848 CHKERR KSPGetPC(ksp, &pc_raw);
1849 return SmartPetscObj<PC>(pc_raw,
1850 true); // bump reference
1851 };
1852 CHKERR setSchurA00MatSolvePC(get_pc(subksp[0]));
1853 CHKERR PetscFree(subksp);
1855 };
1856
1857 CHKERR set_ops();
1858 CHKERR set_pc();
1859 CHKERR set_assemble_elems();
1860
1861 CHKERR TSSetUp(solver);
1862 CHKERR KSPSetUp(ksp);
1863 CHKERR set_diagonal_pc();
1864
1865 } else {
1866 pip_mng->getOpBoundaryLhsPipeline().push_front(
1868 pip_mng->getOpBoundaryLhsPipeline().push_back(
1869 createOpSchurAssembleEnd({}, {}));
1870 pip_mng->getOpDomainLhsPipeline().push_front(createOpSchurAssembleBegin());
1871 pip_mng->getOpDomainLhsPipeline().push_back(
1872 createOpSchurAssembleEnd({}, {}));
1873 }
1874
1875 // fieldSplitIS.reset();
1876 // aoSchur.reset();
1878}

◆ setUp() [8/10]

MoFEMErrorCode SetUpSchurImpl::setUp ( TS  solver)
virtual

Implements SetUpSchur.

◆ setUp() [9/10]

MoFEMErrorCode SetUpSchurImpl::setUp ( TS  solver)
virtual

Implements SetUpSchur.

◆ setUp() [10/10]

MoFEMErrorCode SetUpSchurImpl::setUp ( TS  ts)
virtual

Implements SetUpSchur.

Member Data Documentation

◆ aoS

SmartPetscObj<AO> SetUpSchurImpl::aoS
private

Definition at line 24 of file SetUpSchurImpl.cpp.

◆ aoSchur

SmartPetscObj< AO > SetUpSchurImpl::aoSchur
private

◆ blockDM

SmartPetscObj< DM > SetUpSchurImpl::blockDM
private

◆ epCorePtr

EshelbianCore* SetUpSchurImpl::epCorePtr
private

Definition at line 21 of file SetUpSchurImpl.cpp.

◆ fieldSplitIS

SmartPetscObj< IS > SetUpSchurImpl::fieldSplitIS
private

IS for split Schur block.

Examples
mofem/tutorials/adv-0_plasticity/plastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 1691 of file plastic.cpp.

◆ mField

MoFEM::Interface & SetUpSchurImpl::mField
private

◆ piolaZeroDofsMarker

boost::shared_ptr<std::vector<unsigned char> > SetUpSchurImpl::piolaZeroDofsMarker
private

Definition at line 29 of file SetUpSchurImpl.cpp.

◆ piolaZeroDofsVec

boost::shared_ptr<std::vector<boost::weak_ptr<NumeredDofEntity> > > SetUpSchurImpl::piolaZeroDofsVec
private

Definition at line 27 of file SetUpSchurImpl.cpp.

◆ pMGPtr

boost::shared_ptr<P_MultiGridData> SetUpSchurImpl::pMGPtr
private

Definition at line 51 of file SetUpSchurImpl.cpp.

◆ S

SmartPetscObj< Mat > SetUpSchurImpl::S
private

◆ schurDM

SmartPetscObj< DM > SetUpSchurImpl::schurDM
private

◆ subDM

SmartPetscObj< DM > SetUpSchurImpl::subDM
private

field split sub dm

Examples
mofem/tutorials/adv-0_plasticity/plastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 1690 of file plastic.cpp.

◆ subEnts

Range SetUpSchurImpl::subEnts
private

◆ volEnts

Range SetUpSchurImpl::volEnts
private

The documentation for this struct was generated from the following files: