v0.15.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/plastic.cpp, mofem/tutorials/vec-10/schur_elastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 519 of file test_broken_space.cpp.

Constructor & Destructor Documentation

◆ SetUpSchurImpl() [1/10]

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

Definition at line 521 of file test_broken_space.cpp.

521: 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 1659 of file plastic.cpp.

1659 {
1661 "Is expected that schur matrix is not "
1662 "allocated. This is "
1663 "possible only is PC is set up twice");
1664 }
1665 }
1666 virtual ~SetUpSchurImpl() { S.reset(); }
1667
1668 MoFEMErrorCode setUp(TS solver);
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
virtual ~SetUpSchurImpl()=default
SmartPetscObj< Mat > S
MoFEMErrorCode setUp(SmartPetscObj< KSP >)
MoFEMErrorCode preProc()

◆ ~SetUpSchurImpl() [2/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
inlinevirtual

Definition at line 1670 of file plastic.cpp.

◆ SetUpSchurImpl() [3/10]

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

Definition at line 1010 of file contact.cpp.

◆ ~SetUpSchurImpl() [3/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
inlinevirtual

Definition at line 1012 of file contact.cpp.

◆ 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 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 5434 of file thermoplastic.cpp.

5436 : SetUpSchur(), mField(m_field), subDM(sub_dm),
5437 fieldSplitIS(field_split_is), aoSchur(ao_up) {
5438 if (S) {
5440 "Is expected that schur matrix is not "
5441 "allocated. This is "
5442 "possible only is PC is set up twice");
5443 }
5444 }
SmartPetscObj< DM > subDM
field split sub dm
Definition plastic.cpp:1680
SmartPetscObj< AO > aoSchur
Definition plastic.cpp:1682
SmartPetscObj< IS > fieldSplitIS
IS for split Schur block.
Definition plastic.cpp:1681

◆ ~SetUpSchurImpl() [7/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
inlinevirtual

Definition at line 5445 of file thermoplastic.cpp.

5445{ 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/schur_elastic.cpp.

Definition at line 1104 of file contact.cpp.

1105 {}, {}));
1106 pip->getOpDomainLhsPipeline().push_front(createOpSchurAssembleBegin());
1107 pip->getOpDomainLhsPipeline().push_back(createOpSchurAssembleEnd({}, {}));
1108 }
1110}
1111
1114 auto simple = mField.getInterface<Simple>();
1115
1116 auto create_dm = [&](const char *name, const char *field_name, auto dm_type) {
1117 auto dm = createDM(mField.get_comm(), dm_type);
1118 auto create_dm_imp = [&]() {
1120 CHKERR DMMoFEMCreateSubDM(dm, simple->getDM(), name);
1121 CHKERR DMMoFEMSetSquareProblem(dm, PETSC_TRUE);
1122 CHKERR DMMoFEMAddElement(dm, simple->getDomainFEName());
1125 CHKERR DMSetUp(dm);
1127 };
1129 create_dm_imp(),
1130 "Error in creating schurDM. It is possible that schurDM is "
1131 "already created");
1132 return dm;
1133 };
1134
1135 // Note: here we can make block with bubbles of "U" and "SIGMA" fields. See
1136 // vec-0 where bubbles are added.
1137
1138 schurDM = create_dm("SCHUR", "U", "DMMOFEM_MG");
1139 blockDM = create_dm("BLOCK", "SIGMA", "DMMOFEM");
1140
1141 if constexpr (AT == AssemblyType::BLOCK_SCHUR) {
1142
1143 auto get_nested_mat_data = [&](auto schur_dm, auto block_dm) {
1144 auto block_mat_data = createBlockMatStructure(
1145 simple->getDM(),
1146
1147 {{
1148
1149 simple->getDomainFEName(),
1150
1151 {
1152
1153 {"U", "U"}, {"SIGMA", "U"}, {"U", "SIGMA"}, {"SIGMA", "SIGMA"}
1154
1155 }}}
1156
1157 );
1158
1160
1161 {schur_dm, block_dm}, block_mat_data,
1162
1163 {"SIGMA"}, {nullptr}, true
1164
1165 );
1166 };
1167
1168 auto nested_mat_data = get_nested_mat_data(schurDM, blockDM);
1169 CHKERR DMMoFEMSetNestSchurData(simple->getDM(), nested_mat_data);
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 ...
#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
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:2585
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:2343
MoFEMErrorCode DMMoFEMSetNestSchurData(DM dm, boost::shared_ptr< NestSchurData >)
Definition DMMoFEM.cpp:1554
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
OpSchurAssembleBase * createOpSchurAssembleBegin()
Definition Schur.cpp:2580
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.
MoFEMErrorCode createSubDM()
Definition contact.cpp:1104
SmartPetscObj< DM > schurDM
Definition contact.cpp:1025
SmartPetscObj< DM > blockDM
Definition contact.cpp:1026
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/schur_elastic.cpp.

Definition at line 1254 of file contact.cpp.

1254 {
1256 auto block_is = getDMSubData(blockDM)->getSmartRowIs();
1257 CHKERR PCFieldSplitSetIS(pc, NULL, block_is);
1258 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER, S);
1260}
1261
1264 KSP *subksp;
1265 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULL, &subksp);
1266 auto get_pc = [](auto ksp) {
1267 PC pc_raw;
1268 CHKERR KSPGetPC(ksp, &pc_raw);
1269 return SmartPetscObj<PC>(pc_raw, true); // bump reference
1270 };
1271 CHKERR setSchurA00MatSolvePC(get_pc(subksp[0]));
1272
1273 auto set_pc_p_mg = [](auto dm, auto pc, auto S) {
1275 CHKERR PCSetDM(pc, dm);
1276 PetscBool same = PETSC_FALSE;
1277 PetscObjectTypeCompare((PetscObject)pc, PCMG, &same);
1278 if (same) {
1280 pc, createPCMGSetUpViaApproxOrdersCtx(dm, S, true));
1281 CHKERR PCSetFromOptions(pc);
1282 }
1284 };
1285
1286 CHKERR set_pc_p_mg(schurDM, get_pc(subksp[1]), S);
1287
1288 CHKERR PetscFree(subksp);
1290}
1291
1292boost::shared_ptr<SetUpSchur>
1294 return boost::shared_ptr<SetUpSchur>(new SetUpSchurImpl(m_field));
1295}
MoFEMErrorCode setSchurA00MatSolvePC(SmartPetscObj< PC > pc)
Set PC for A00 block.
Definition Schur.cpp:2627
boost::shared_ptr< PCMGSetUpViaApproxOrdersCtx > createPCMGSetUpViaApproxOrdersCtx(DM dm, Mat A, bool use_shell_mat)
createPCMGSetUpViaApproxOrdersCtx
auto getDMSubData(DM dm)
Get sub problem data structure.
Definition DMMoFEM.hpp:1292
MoFEMErrorCode PCMGSetUpViaApproxOrders(PC pc, boost::shared_ptr< PCMGSetUpViaApproxOrdersCtx > ctx, int verb)
Function build MG structure.
Deprecated interface functions.
intrusive_ptr for managing petsc objects
MoFEMErrorCode setDiagonalPC(PC pc)
Definition contact.cpp:1254
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field)

◆ 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/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:19

◆ setEntities() [2/2]

MoFEMErrorCode SetUpSchurImpl::setEntities ( )
private

◆ setOperator() [1/5]

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

Definition at line 1171 of file contact.cpp.

1171 {
1172 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1173 "Only BLOCK_SCHUR is implemented");
1174 }
1175
1177}
1178
1181
1182 double eps_stab = 1e-4;
1183 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-eps_stab", &eps_stab,
1184 PETSC_NULL);
1185
1188 using OpMassStab = B::OpMass<3, SPACE_DIM * SPACE_DIM>;
1189
1190 auto simple = mField.getInterface<Simple>();
1191 auto pip = mField.getInterface<PipelineManager>();
1192
1193 auto dm_is = getDMSubData(schurDM)->getSmartRowIs();
1194 auto ao_up = createAOMappingIS(dm_is, PETSC_NULL);
1195
1196 // Boundary
1197 pip->getOpBoundaryLhsPipeline().push_front(createOpSchurAssembleBegin());
1198 pip->getOpBoundaryLhsPipeline().push_back(
1199 new OpMassStab("SIGMA", "SIGMA",
1200 [eps_stab](double, double, double) { return eps_stab; }));
1201 pip->getOpBoundaryLhsPipeline().push_back(
1202
1203 createOpSchurAssembleEnd({"SIGMA"}, {nullptr}, ao_up, S, false, false)
1204
1205 );
1206
1207 // Domain
1208 pip->getOpDomainLhsPipeline().push_front(createOpSchurAssembleBegin());
1209 pip->getOpDomainLhsPipeline().push_back(
1210
1211 createOpSchurAssembleEnd({"SIGMA"}, {nullptr}, ao_up, S, false, false)
1212
1213 );
1214
1215 auto pre_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
1216 auto post_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
1217
1218 pre_proc_schur_lhs_ptr->preProcessHook = [this]() {
1220 CHKERR MatZeroEntries(S);
1221 MOFEM_LOG("CONTACT", Sev::verbose) << "Lhs Assemble Begin";
1223 };
1224
1225 post_proc_schur_lhs_ptr->postProcessHook = [this, ao_up,
1226 post_proc_schur_lhs_ptr]() {
1228 MOFEM_LOG("CONTACT", Sev::verbose) << "Lhs Assemble End";
1229 auto print_mat_norm = [this](auto a, std::string prefix) {
1231 double nrm;
1232 CHKERR MatNorm(a, NORM_FROBENIUS, &nrm);
1233 MOFEM_LOG("CONTACT", Sev::noisy) << prefix << " norm = " << nrm;
1235 };
1236 CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
1237 CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
1239 mField, post_proc_schur_lhs_ptr, 1, S, ao_up)();
1240#ifndef NDEBUG
1241 CHKERR print_mat_norm(S, "S");
1242#endif // NDEBUG
1243 MOFEM_LOG("CONTACT", Sev::verbose) << "Lhs Assemble Finish";
constexpr double a
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
@ BLOCK_PRECONDITIONER_SCHUR
Block preconditioner Schur assembly.
#define MOFEM_LOG(channel, severity)
Log.
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
auto createAOMappingIS(IS isapp, IS ispetsc)
Creates an application mapping using two index sets.
Class (Function) to enforce essential constrains on the left hand side diagonal.
Definition Essential.hpp:33
PipelineManager interface.
MoFEMErrorCode setOperator()
Definition contact.cpp:1171

◆ 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/schur_elastic.cpp.

Definition at line 1246 of file contact.cpp.

◆ 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/plastic.cpp, mofem/tutorials/vec-10/schur_elastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 532 of file test_broken_space.cpp.

532 {
535 auto pip_mng = mField.getInterface<PipelineManager>();
536
537 CHKERR KSPSetFromOptions(ksp);
538 PC pc;
539 CHKERR KSPGetPC(ksp, &pc);
540
541 PetscBool is_pcfs = PETSC_FALSE;
542 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
543 if (is_pcfs) {
544
545 MOFEM_LOG("AT", Sev::inform) << "Setup Schur pc";
546
547 auto create_sub_dm = [&]() {
549
550 auto create_dm = [&](
551
552 std::string problem_name,
553 std::vector<std::string> fe_names,
554 std::vector<std::string> fields,
555
556 auto dm_type
557
558 ) {
559 auto dm = createDM(mField.get_comm(), dm_type);
560 auto create_dm_imp = [&]() {
562 CHKERR DMMoFEMCreateSubDM(dm, simple->getDM(), problem_name.c_str());
563 CHKERR DMMoFEMSetSquareProblem(dm, PETSC_TRUE);
564 for (auto fe : fe_names) {
566 }
567 CHKERR DMMoFEMAddElement(dm, simple->getSkeletonFEName());
568 for (auto field : fields) {
569 CHKERR DMMoFEMAddSubFieldRow(dm, field);
570 CHKERR DMMoFEMAddSubFieldCol(dm, field);
571 }
572 CHKERR DMSetUp(dm);
574 };
576 create_dm_imp(),
577 "Error in creating schurDM. It is possible that schurDM is "
578 "already created");
579 return dm;
580 };
581
582 auto schur_dm = create_dm(
583
584 "SCHUR",
585
586 {simple->getDomainFEName(), simple->getSkeletonFEName()},
587
588 {"HYBRID"},
589
590 "DMMOFEM_MG");
591
592 auto block_dm = create_dm(
593
594 "BLOCK",
595
596 {simple->getDomainFEName(), simple->getSkeletonFEName()},
597
598 {"BROKEN", "U"},
599
600 "DMMOFEM");
601
602 return std::make_tuple(schur_dm, block_dm);
603 };
604
605 auto get_nested_mat_data = [&](auto schur_dm, auto block_dm) {
606 auto block_mat_data = createBlockMatStructure(
607 simple->getDM(),
608
609 {
610
611 {
612
613 simple->getDomainFEName(),
614
615 {
616
617 {"BROKEN", "BROKEN"},
618 {"U", "U"},
619 {"BROKEN", "U"},
620 {"U", "BROKEN"}
621
622 }
623
624 },
625
626 {
627
628 simple->getSkeletonFEName(),
629
630 {
631
632 {"BROKEN", "HYBRID"}, {"HYBRID", "BROKEN"}
633
634 }
635
636 }
637
638 }
639
640 );
641
643
644 {schur_dm, block_dm}, block_mat_data,
645
646 {"BROKEN", "U"}, {nullptr, nullptr}, true
647
648 );
649 };
650
651 auto set_ops = [&](auto schur_dm) {
653 auto dm_is = getDMSubData(schur_dm)->getSmartRowIs();
654 auto ao_up = createAOMappingIS(dm_is, PETSC_NULLPTR);
655
656 boost::shared_ptr<BlockStructure> block_data;
657 CHKERR DMMoFEMGetBlocMatData(simple->getDM(), block_data);
658
659 if (AT == BLOCK_SCHUR) {
660 pip_mng->getOpDomainLhsPipeline().push_front(
662 pip_mng->getOpDomainLhsPipeline().push_back(
663
664 createOpSchurAssembleEnd({"BROKEN", "U"}, {nullptr, nullptr}, ao_up,
665 S, true, true)
666
667 );
668 }
669
670 auto pre_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
671 auto post_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
672
673 pre_proc_schur_lhs_ptr->preProcessHook = [this]() {
675 CHKERR MatZeroEntries(S);
676 MOFEM_LOG("AT", Sev::verbose) << "Lhs Assemble Begin";
678 };
679
680 post_proc_schur_lhs_ptr->postProcessHook = [this, ao_up,
681 post_proc_schur_lhs_ptr]() {
683 MOFEM_LOG("AT", Sev::verbose) << "Lhs Assemble End";
684
685 if (AT == BLOCK_SCHUR) {
686 CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
687 CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
688 if (1) {
689 auto S_from_block = matDuplicate(S, MAT_SHARE_NONZERO_PATTERN);
690 // Create matrix from block mat
691 CHKERR assembleBlockMatSchur(mField, post_proc_schur_lhs_ptr->B,
692 S_from_block, {"BROKEN", "U"},
693 {nullptr, nullptr}, ao_up);
694 CHKERR MatAssemblyBegin(S_from_block, MAT_FINAL_ASSEMBLY);
695 CHKERR MatAssemblyEnd(S_from_block, MAT_FINAL_ASSEMBLY);
696 CHKERR MatAYPX(S_from_block, -1, S, DIFFERENT_NONZERO_PATTERN);
697 double norm;
698 CHKERR MatNorm(S_from_block, NORM_FROBENIUS, &norm);
699 MOFEM_LOG("AT", Sev::inform) << "Norm of difference: " << norm;
700 if (norm > 1e-6)
701 SETERRQ(
702 PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
703 "Norm of difference between Schur and block matrix is larger "
704 "than accepted");
705 }
706 } else {
707 CHKERR assembleBlockMatSchur(mField, post_proc_schur_lhs_ptr->B, S,
708 {"BROKEN", "U"}, {nullptr, nullptr}, ao_up);
709 CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
710 CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
711 }
712
713 MOFEM_LOG("AT", Sev::verbose) << "Lhs Assemble Finish";
715 };
716
717 auto ksp_ctx_ptr = getDMKspCtx(simple->getDM());
718 ksp_ctx_ptr->getPreProcSetOperators().push_front(pre_proc_schur_lhs_ptr);
719 ksp_ctx_ptr->getPostProcSetOperators().push_back(post_proc_schur_lhs_ptr);
720
722 };
723
724 auto set_pc = [&](auto pc, auto block_dm) {
726 auto block_is = getDMSubData(block_dm)->getSmartRowIs();
727 CHKERR PCFieldSplitSetIS(pc, NULL, block_is);
728 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER, S);
730 };
731
732
733
734 auto [schur_dm, block_dm] = create_sub_dm();
735 if (AT == BLOCK_SCHUR || AT == BLOCK_MAT) {
736 auto nested_mat_data = get_nested_mat_data(schur_dm, block_dm);
737 CHKERR DMMoFEMSetNestSchurData(simple->getDM(), nested_mat_data);
738 }
739 S = createDMHybridisedL2Matrix(schur_dm);
740 CHKERR MatSetDM(S, PETSC_NULLPTR);
741
742 int bs = (SPACE_DIM == 2) ? NBEDGE_L2(approx_order - 1)
744 CHKERR MatSetBlockSize(S, bs);
745
746 CHKERR set_ops(schur_dm);
747 CHKERR set_pc(pc, block_dm);
748 DM solver_dm;
749 CHKERR KSPGetDM(ksp, &solver_dm);
750 if (AT == BLOCK_SCHUR || AT == BLOCK_MAT)
751 CHKERR DMSetMatType(solver_dm, MATSHELL);
752
753 auto get_pc = [](auto ksp) {
754 PC pc_raw;
755 CHKERR KSPGetPC(ksp, &pc_raw);
756 return pc_raw;
757 };
758
759 auto set_diagonal_pc = [&](auto pc) {
761
762 if (AT == BLOCK_SCHUR || AT == BLOCK_MAT) {
763 auto A = createDMBlockMat(simple->getDM());
764 auto P = createDMNestSchurMat(simple->getDM());
765 CHKERR PCSetOperators(pc, A, P);
766 }
767
768 KSP *subksp;
769 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
770 CHKERR setSchurA00MatSolvePC(SmartPetscObj<PC>(get_pc(subksp[0]), true));
771
772 CHKERR PetscFree(subksp);
774 };
775
776 auto set_mg_for_schur_complement = [&](auto pc, auto schur_dm, auto S) {
778
779 KSP *subksp;
780 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
781 auto subpc = get_pc(subksp[1]);
782
783 auto set_pc_p_mg = [](auto dm, auto pc, auto S) {
785 CHKERR PCSetDM(pc, dm);
786 PetscBool same = PETSC_FALSE;
787 PetscObjectTypeCompare((PetscObject)pc, PCMG, &same);
788 if (same) {
789 MOFEM_LOG("TIMER", Sev::inform) << "Set up MG";
791 pc, createPCMGSetUpViaApproxOrdersCtx(dm, S, true));
792 CHKERR PCSetFromOptions(pc);
793 }
795 };
796
797 PetscBool same = PETSC_FALSE;
798 PetscObjectTypeCompare((PetscObject)subpc, PCKSP, &same);
799 if (same) {
800 CHKERR PCSetFromOptions(subpc);
801 KSP inner_ksp;
802 CHKERR PCKSPGetKSP(subpc, &inner_ksp);
803 CHKERR KSPSetFromOptions(inner_ksp);
804 PC inner_pc;
805 CHKERR KSPGetPC(inner_ksp, &inner_pc);
806 CHKERR PCSetFromOptions(inner_pc);
807 CHKERR set_pc_p_mg(schur_dm, inner_pc, S);
808 }
809
810 CHKERR PetscFree(subksp);
812 };
813
814 CHKERR KSPSetUp(ksp);
815 if (AT == BLOCK_SCHUR || AT == BLOCK_MAT) {
816 CHKERR set_diagonal_pc(pc);
817 CHKERR set_mg_for_schur_complement(pc, schur_dm, S);
818 }
819
820 } else {
821 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
822 "PC is not set to PCFIELDSPLIT");
823 }
825}
@ 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:1534
auto getDMKspCtx(DM dm)
Get KSP context data structure used by DM.
Definition DMMoFEM.hpp:1248
auto createDMHybridisedL2Matrix(DM dm)
Get smart hybridised L2 matrix from DM.
Definition DMMoFEM.hpp:1204
SmartPetscObj< Mat > matDuplicate(Mat mat, MatDuplicateOption op)
auto createDMNestSchurMat(DM dm)
Definition DMMoFEM.hpp:1218
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:1817
auto createDMBlockMat(DM dm)
Definition DMMoFEM.hpp:1211
static constexpr int approx_order
constexpr AssemblyType A
[Define dimension]
Definition elastic.cpp:22

◆ setUp() [4/10]

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

Implements SetUpSchur.

Definition at line 1029 of file contact.cpp.

1037 {
1039 auto simple = mField.getInterface<Simple>();
1040 auto pip = mField.getInterface<PipelineManager>();
1041
1042 SNES snes;
1043 CHKERR TSGetSNES(solver, &snes);
1044 KSP ksp;
1045 CHKERR SNESGetKSP(snes, &ksp);
1046 CHKERR KSPSetFromOptions(ksp);
1047
1048 PC pc;
1049 CHKERR KSPGetPC(ksp, &pc);
1050
1051 PetscBool is_pcfs = PETSC_FALSE;
1052 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
1053 if (is_pcfs) {
1054
1055 MOFEM_LOG("CONTACT", Sev::inform) << "Setup Schur pc";
1056
1057 if (S) {
1060 "It is expected that Schur matrix is not allocated. This is "
1061 "possible only if PC is set up twice");
1062 }
1063
1065
1066 // Add data to DM storage
1068 CHKERR MatSetBlockSize(S, SPACE_DIM);
1069 // CHKERR MatSetOption(S, MAT_SYMMETRIC, PETSC_TRUE);
1070
1071 // Set DM to use shell block matrix
1072 DM solver_dm;
1073 CHKERR TSGetDM(solver, &solver_dm);
1074 CHKERR DMSetMatType(solver_dm, MATSHELL);
1075
1076 auto ts_ctx_ptr = getDMTsCtx(solver_dm);
1077 auto A = createDMBlockMat(simple->getDM());
1078 auto P = createDMNestSchurMat(simple->getDM());
1079
1080 if (is_quasi_static == PETSC_TRUE) {
1081 auto swap_assemble = [](TS ts, PetscReal t, Vec u, Vec u_t, PetscReal a,
1082 Mat A, Mat B, void *ctx) {
1083 return TsSetIJacobian(ts, t, u, u_t, a, B, A, ctx);
1084 };
1085 CHKERR TSSetIJacobian(solver, A, P, swap_assemble, ts_ctx_ptr.get());
1086 } else {
1087 auto swap_assemble = [](TS ts, PetscReal t, Vec u, Vec u_t, Vec utt,
1088 PetscReal a, PetscReal aa, Mat A, Mat B,
1089 void *ctx) {
1090 return TsSetI2Jacobian(ts, t, u, u_t, utt, a, aa, B, A, ctx);
1091 };
1092 CHKERR TSSetI2Jacobian(solver, A, P, swap_assemble, ts_ctx_ptr.get());
1093 }
1094 CHKERR KSPSetOperators(ksp, A, P);
1095
1097 CHKERR setPC(pc);
1098 CHKERR TSSetUp(solver);
1099 CHKERR KSPSetUp(ksp);
1101
1102 } else {
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition DMMoFEM.hpp:1191
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
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
Definition DMMoFEM.hpp:1276
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 setPC(PC pc)
Definition contact.cpp:1246
PetscBool is_quasi_static
[Operators used for contact]
Definition plastic.cpp:143

◆ 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 1685 of file plastic.cpp.

1696 {
1697 if (S) {
1699 "Is expected that schur matrix is not "
1700 "allocated. This is "
1701 "possible only is PC is set up twice");
1702 }
1703
1705 CHKERR MatSetBlockSize(S, SPACE_DIM);
1706
1707 // Set DM to use shell block matrix
1708 DM solver_dm;
1709 CHKERR TSGetDM(solver, &solver_dm);
1710 CHKERR DMSetMatType(solver_dm, MATSHELL);
1711
1712 auto ts_ctx_ptr = getDMTsCtx(solver_dm);
1713 auto A = createDMBlockMat(simple->getDM());
1714 auto P = createDMNestSchurMat(simple->getDM());
1715
1716 if (is_quasi_static == PETSC_TRUE) {
1717 auto swap_assemble = [](TS ts, PetscReal t, Vec u, Vec u_t, PetscReal a,
1718 Mat A, Mat B, void *ctx) {
1719 return TsSetIJacobian(ts, t, u, u_t, a, B, A, ctx);
1720 };
1721 CHKERR TSSetIJacobian(solver, A, P, swap_assemble, ts_ctx_ptr.get());
1722 } else {
1723 auto swap_assemble = [](TS ts, PetscReal t, Vec u, Vec u_t, Vec utt,
1724 PetscReal a, PetscReal aa, Mat A, Mat B,
1725 void *ctx) {
1726 return TsSetI2Jacobian(ts, t, u, u_t, utt, a, aa, B, A, ctx);
1727 };
1728 CHKERR TSSetI2Jacobian(solver, A, P, swap_assemble, ts_ctx_ptr.get());
1729 }
1730 CHKERR KSPSetOperators(ksp, A, P);
1731
1732 auto set_ops = [&]() {
1734 auto pip_mng = mField.getInterface<PipelineManager>();
1735
1736#ifndef ADD_CONTACT
1737 // Boundary
1738 pip_mng->getOpBoundaryLhsPipeline().push_front(
1740 pip_mng->getOpBoundaryLhsPipeline().push_back(createOpSchurAssembleEnd(
1741
1742 {"EP", "TAU"}, {nullptr, nullptr}, aoSchur, S, false, false
1743
1744 ));
1745 // Domain
1746 pip_mng->getOpDomainLhsPipeline().push_front(
1748 pip_mng->getOpDomainLhsPipeline().push_back(createOpSchurAssembleEnd(
1749
1750 {"EP", "TAU"}, {nullptr, nullptr}, aoSchur, S, false, false
1751
1752 ));
1753#else
1754
1755 double eps_stab = 1e-4;
1756 CHKERR PetscOptionsGetScalar(PETSC_NULL, "", "-eps_stab", &eps_stab,
1757 PETSC_NULL);
1758
1761 using OpMassStab = B::OpMass<3, SPACE_DIM * SPACE_DIM>;
1762
1763 // Boundary
1764 pip_mng->getOpBoundaryLhsPipeline().push_front(
1766 pip_mng->getOpBoundaryLhsPipeline().push_back(
1767 new OpMassStab("SIGMA", "SIGMA", [eps_stab](double, double, double) {
1768 return eps_stab;
1769 }));
1770 pip_mng->getOpBoundaryLhsPipeline().push_back(createOpSchurAssembleEnd(
1771
1772 {"SIGMA", "EP", "TAU"}, {nullptr, nullptr, nullptr}, aoSchur, S,
1773 false, false
1774
1775 ));
1776 // Domain
1777 pip_mng->getOpDomainLhsPipeline().push_front(
1779 pip_mng->getOpDomainLhsPipeline().push_back(createOpSchurAssembleEnd(
1780
1781 {"SIGMA", "EP", "TAU"}, {nullptr, nullptr, nullptr}, aoSchur, S,
1782 false, false
1783
1784 ));
1785#endif // ADD_CONTACT
1787 };
1788
1789 auto set_assemble_elems = [&]() {
1791 auto schur_asmb_pre_proc = boost::make_shared<FEMethod>();
1792 schur_asmb_pre_proc->preProcessHook = [this]() {
1794 CHKERR MatZeroEntries(S);
1795 MOFEM_LOG("TIMER", Sev::verbose) << "Lhs Assemble Begin";
1797 };
1798 auto schur_asmb_post_proc = boost::make_shared<FEMethod>();
1799
1800 schur_asmb_post_proc->postProcessHook = [this, schur_asmb_post_proc]() {
1802 MOFEM_LOG("TIMER", Sev::verbose) << "Lhs Assemble End";
1803
1804 // Apply essential constrains to Schur complement
1805 CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
1806 CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
1808 mField, schur_asmb_post_proc, 1, S, aoSchur)();
1809
1811 };
1812 auto ts_ctx_ptr = getDMTsCtx(simple->getDM());
1813 ts_ctx_ptr->getPreProcessIJacobian().push_front(schur_asmb_pre_proc);
1814 ts_ctx_ptr->getPostProcessIJacobian().push_front(schur_asmb_post_proc);
1816 };
1817
1818 auto set_pc = [&]() {
1820 CHKERR PCFieldSplitSetIS(pc, NULL, fieldSplitIS);
1821 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER, S);
1823 };
1824
1825 auto set_diagonal_pc = [&]() {
1827 KSP *subksp;
1828 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULL, &subksp);
1829 auto get_pc = [](auto ksp) {
1830 PC pc_raw;
1831 CHKERR KSPGetPC(ksp, &pc_raw);
1832 return SmartPetscObj<PC>(pc_raw,
1833 true); // bump reference
1834 };
1835 CHKERR setSchurA00MatSolvePC(get_pc(subksp[0]));
1836 CHKERR PetscFree(subksp);
1838 };
1839
1840 CHKERR set_ops();
1841 CHKERR set_pc();
1842 CHKERR set_assemble_elems();
1843
1844 CHKERR TSSetUp(solver);
1845 CHKERR KSPSetUp(ksp);
1846 CHKERR set_diagonal_pc();
1847
1848 } else {
1849 pip_mng->getOpBoundaryLhsPipeline().push_front(
1851 pip_mng->getOpBoundaryLhsPipeline().push_back(
1852 createOpSchurAssembleEnd({}, {}));
1853 pip_mng->getOpDomainLhsPipeline().push_front(createOpSchurAssembleBegin());
1854 pip_mng->getOpDomainLhsPipeline().push_back(
1855 createOpSchurAssembleEnd({}, {}));
1856 }
1857
1858 // fieldSplitIS.reset();
1859 // aoSchur.reset();
1861}
1862
1863boost::shared_ptr<SetUpSchur>
1865 SmartPetscObj<DM> sub_dm, SmartPetscObj<IS> is_sub,
boost::ptr_deque< UserDataOperator > & getOpBoundaryLhsPipeline()
Get the Op Boundary Lhs Pipeline object.

◆ 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
Examples
mofem/tutorials/vec-10/schur_elastic.cpp.

Definition at line 1026 of file contact.cpp.

◆ 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/plastic.cpp, plastic.cpp, and thermoplastic.cpp.

Definition at line 1681 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
Examples
mofem/tutorials/vec-10/schur_elastic.cpp.

Definition at line 1025 of file contact.cpp.

◆ subDM

SmartPetscObj< DM > SetUpSchurImpl::subDM
private

field split sub dm

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

Definition at line 1680 of file plastic.cpp.

◆ subEnts

Range SetUpSchurImpl::subEnts
private
Examples
mofem/tutorials/vec-10/schur_elastic.cpp.

Definition at line 204 of file schur_elastic.cpp.

◆ volEnts

Range SetUpSchurImpl::volEnts
private
Examples
mofem/tutorials/vec-10/schur_elastic.cpp.

Definition at line 203 of file schur_elastic.cpp.


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