v0.16.3
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::Interface & mField
 
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
 
EshelbianCore * epCorePtr
 
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_MultiGridData > pMGPtr
 

Additional Inherited Members

- Static Public Member Functions inherited from SetUpSchur
static boost::shared_ptr< SetUpSchur > createSetUpSchur (MoFEM::Interface &m_field)
 
static boost::shared_ptr< SetUpSchur > createSetUpSchur (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< SetUpSchur > createSetUpSchur (MoFEM::Interface &m_field)
 
static boost::shared_ptr< SetUpSchur > createSetUpSchur (MoFEM::Interface &m_field)
 
static boost::shared_ptr< SetUpSchur > createSetUpSchur (MoFEM::Interface &m_field)
 
static boost::shared_ptr< SetUpSchur > createSetUpSchur (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< SetUpSchur > createSetUpSchur (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< SetUpSchur > createSetUpSchur (MoFEM::Interface &m_field)
 
static boost::shared_ptr< SetUpSchur > createSetUpSchur (MoFEM::Interface &m_field)
 
- Static Public Member Functions inherited from EshelbianCore::SetUpSchur
static boost::shared_ptr< SetUpSchur > createSetUpSchur (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 543 of file test_broken_space.cpp.

Constructor & Destructor Documentation

◆ SetUpSchurImpl() [1/10]

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

Definition at line 545 of file test_broken_space.cpp.

545: 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 1666 of file plastic.cpp.

1668 : SetUpSchur(), mField(m_field), subDM(sub_dm),
1669 fieldSplitIS(field_split_is), aoSchur(ao_up) {
1670 if (S) {
1672 "Is expected that schur matrix is not "
1673 "allocated. This is "
1674 "possible only is if PC is set up twice");
1675 }
1676 }
#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:1687
SmartPetscObj< Mat > S
SmartPetscObj< AO > aoSchur
Definition plastic.cpp:1689
SmartPetscObj< IS > fieldSplitIS
IS for split Schur block.
Definition plastic.cpp:1688

◆ ~SetUpSchurImpl() [2/10]

virtual SetUpSchurImpl::~SetUpSchurImpl ( )
inlinevirtual

Definition at line 1677 of file plastic.cpp.

1677{ 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:2421
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 auto a00_field_list =
62 epCorePtr->physicalEquations->getMaterialFields(*epCorePtr);
63 for (const auto &field : {epCorePtr->bubbleField, epCorePtr->piolaStress,
65 if (mField.check_field(field))
66 a00_field_list.push_back(field);
67 std::vector<boost::shared_ptr<Range>> range_list_ptr(a00_field_list.size(),
68 nullptr);
69 return std::make_pair(a00_field_list, range_list_ptr);
70 }
virtual bool check_field(const std::string &name) const =0
check if field is in database
const std::string spatialL2Disp
const std::string piolaStress
const std::string bubbleField
boost::shared_ptr< PhysicalEquations > physicalEquations
const std::string rotAxis

◆ 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:2705
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 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:2663
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:2658
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 556 of file test_broken_space.cpp.

556 {
559 auto pip_mng = mField.getInterface<PipelineManager>();
560
561 CHKERR KSPSetFromOptions(ksp);
562 PC pc;
563 CHKERR KSPGetPC(ksp, &pc);
564
565 PetscBool is_pcfs = PETSC_FALSE;
566 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
567 if (is_pcfs) {
568
569 MOFEM_LOG("AT", Sev::inform) << "Setup Schur pc";
570
571 auto create_sub_dm = [&]() {
573
574 auto create_dm = [&](
575
576 std::string problem_name,
577 std::vector<std::string> fe_names,
578 std::vector<std::string> fields,
579
580 auto dm_type
581
582 ) {
583 auto dm = createDM(mField.get_comm(), dm_type);
584 auto create_dm_imp = [&]() {
586 CHKERR DMMoFEMCreateSubDM(dm, simple->getDM(), problem_name.c_str());
587 CHKERR DMMoFEMSetSquareProblem(dm, PETSC_TRUE);
588 for (auto fe : fe_names) {
590 }
591 CHKERR DMMoFEMAddElement(dm, simple->getSkeletonFEName());
592 for (auto field : fields) {
593 CHKERR DMMoFEMAddSubFieldRow(dm, field);
594 CHKERR DMMoFEMAddSubFieldCol(dm, field);
595 }
596 CHKERR DMSetUp(dm);
598 };
600 create_dm_imp(),
601 "Error in creating schurDM. It is possible that schurDM is "
602 "already created");
603 return dm;
604 };
605
606 auto schur_dm = create_dm(
607
608 "SCHUR",
609
610 {simple->getDomainFEName(), simple->getSkeletonFEName()},
611
612 {"HYBRID"},
613
614 "DMMOFEM_MG");
615
616 auto block_dm = create_dm(
617
618 "BLOCK",
619
620 {simple->getDomainFEName(), simple->getSkeletonFEName()},
621
622 {"BROKEN", "U"},
623
624 "DMMOFEM");
625
626 return std::make_tuple(schur_dm, block_dm);
627 };
628
629 auto get_nested_mat_data = [&](auto schur_dm, auto block_dm) {
630 auto block_mat_data = createBlockMatStructure(
631 simple->getDM(),
632
633 {
634
635 {
636
637 simple->getDomainFEName(),
638
639 {
640
641 {"BROKEN", "BROKEN"},
642 {"U", "U"},
643 {"BROKEN", "U"},
644 {"U", "BROKEN"}
645
646 }
647
648 },
649
650 {
651
652 simple->getSkeletonFEName(),
653
654 {
655
656 {"BROKEN", "HYBRID"}, {"HYBRID", "BROKEN"}
657
658 }
659
660 }
661
662 }
663
664 );
665
667
668 {schur_dm, block_dm}, block_mat_data,
669
670 {"BROKEN", "U"}, {nullptr, nullptr}, true
671
672 );
673 };
674
675 auto set_ops = [&](auto schur_dm) {
677 auto dm_is = getDMSubData(schur_dm)->getSmartRowIs();
678 auto ao_up = createAOMappingIS(dm_is, PETSC_NULLPTR);
679
680 boost::shared_ptr<BlockStructure> block_data;
681 CHKERR DMMoFEMGetBlocMatData(simple->getDM(), block_data);
682
683 if (AT == BLOCK_SCHUR) {
684 pip_mng->getOpDomainLhsPipeline().push_front(
686 pip_mng->getOpDomainLhsPipeline().push_back(
687
688 createOpSchurAssembleEnd({"BROKEN", "U"}, {nullptr, nullptr}, ao_up,
689 S, true, true)
690
691 );
692 }
693
694 auto pre_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
695 auto post_proc_schur_lhs_ptr = boost::make_shared<FEMethod>();
696
697 pre_proc_schur_lhs_ptr->preProcessHook = [this]() {
699 CHKERR MatZeroEntries(S);
700 MOFEM_LOG("AT", Sev::verbose) << "Lhs Assemble Begin";
702 };
703
704 post_proc_schur_lhs_ptr->postProcessHook = [this, ao_up,
705 post_proc_schur_lhs_ptr]() {
707 MOFEM_LOG("AT", Sev::verbose) << "Lhs Assemble End";
708
709 if (AT == BLOCK_SCHUR) {
710 CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
711 CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
712 if (1) {
713 auto S_from_block = matDuplicate(S, MAT_SHARE_NONZERO_PATTERN);
714 // Create matrix from block mat
715 CHKERR assembleBlockMatSchur(mField, post_proc_schur_lhs_ptr->B,
716 S_from_block, {"BROKEN", "U"},
717 {nullptr, nullptr}, ao_up);
718 CHKERR MatAssemblyBegin(S_from_block, MAT_FINAL_ASSEMBLY);
719 CHKERR MatAssemblyEnd(S_from_block, MAT_FINAL_ASSEMBLY);
720 CHKERR MatAYPX(S_from_block, -1, S, DIFFERENT_NONZERO_PATTERN);
721 double norm;
722 CHKERR MatNorm(S_from_block, NORM_FROBENIUS, &norm);
723 MOFEM_LOG("AT", Sev::inform) << "Norm of difference: " << norm;
724 if (norm > 1e-6)
725 SETERRQ(
726 PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
727 "Norm of difference between Schur and block matrix is larger "
728 "than accepted");
729 }
730 } else {
731 CHKERR assembleBlockMatSchur(mField, post_proc_schur_lhs_ptr->B, S,
732 {"BROKEN", "U"}, {nullptr, nullptr}, ao_up);
733 CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
734 CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
735 }
736
737 MOFEM_LOG("AT", Sev::verbose) << "Lhs Assemble Finish";
739 };
740
741 auto ksp_ctx_ptr = getDMKspCtx(simple->getDM());
742 ksp_ctx_ptr->getPreProcSetOperators().push_front(pre_proc_schur_lhs_ptr);
743 ksp_ctx_ptr->getPostProcSetOperators().push_back(post_proc_schur_lhs_ptr);
744
746 };
747
748 auto set_pc = [&](auto pc, auto block_dm) {
750 auto block_is = getDMSubData(block_dm)->getSmartRowIs();
751 CHKERR PCFieldSplitSetIS(pc, NULL, block_is);
752 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER, S);
754 };
755
756
757
758 auto [schur_dm, block_dm] = create_sub_dm();
759 if (AT == BLOCK_SCHUR || AT == BLOCK_MAT) {
760 auto nested_mat_data = get_nested_mat_data(schur_dm, block_dm);
761 CHKERR DMMoFEMSetNestSchurData(simple->getDM(), nested_mat_data);
762 }
763 S = createDMHybridisedL2Matrix(schur_dm);
764 CHKERR MatSetDM(S, PETSC_NULLPTR);
765
766 int bs = (SPACE_DIM == 2) ? NBEDGE_L2(approx_order - 1)
768 CHKERR MatSetBlockSize(S, bs);
769
770 CHKERR set_ops(schur_dm);
771 CHKERR set_pc(pc, block_dm);
772 DM solver_dm;
773 CHKERR KSPGetDM(ksp, &solver_dm);
774 if (AT == BLOCK_SCHUR || AT == BLOCK_MAT)
775 CHKERR DMSetMatType(solver_dm, MATSHELL);
776
777 auto get_pc = [](auto ksp) {
778 PC pc_raw;
779 CHKERR KSPGetPC(ksp, &pc_raw);
780 return pc_raw;
781 };
782
783 auto set_diagonal_pc = [&](auto pc) {
785
786 if (AT == BLOCK_SCHUR || AT == BLOCK_MAT) {
787 auto A = createDMBlockMat(simple->getDM());
788 auto P = createDMNestSchurMat(simple->getDM());
789 CHKERR PCSetOperators(pc, A, P);
790 }
791
792 KSP *subksp;
793 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
794 CHKERR setSchurA00MatSolvePC(SmartPetscObj<PC>(get_pc(subksp[0]), true));
795
796 CHKERR PetscFree(subksp);
798 };
799
800 auto set_mg_for_schur_complement = [&](auto pc, auto schur_dm, auto S) {
802
803 KSP *subksp;
804 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
805 auto subpc = get_pc(subksp[1]);
806
807 auto set_pc_p_mg = [](auto dm, auto pc, auto S) {
809 CHKERR PCSetDM(pc, dm);
810 PetscBool same = PETSC_FALSE;
811 PetscObjectTypeCompare((PetscObject)pc, PCMG, &same);
812 if (same) {
813 MOFEM_LOG("TIMER", Sev::inform) << "Set up MG";
815 pc, createPCMGSetUpViaApproxOrdersCtx(dm, S, true));
816 CHKERR PCSetFromOptions(pc);
817 }
819 };
820
821 PetscBool same = PETSC_FALSE;
822 PetscObjectTypeCompare((PetscObject)subpc, PCKSP, &same);
823 if (same) {
824 CHKERR PCSetFromOptions(subpc);
825 KSP inner_ksp;
826 CHKERR PCKSPGetKSP(subpc, &inner_ksp);
827 CHKERR KSPSetFromOptions(inner_ksp);
828 PC inner_pc;
829 CHKERR KSPGetPC(inner_ksp, &inner_pc);
830 CHKERR PCSetFromOptions(inner_pc);
831 CHKERR set_pc_p_mg(schur_dm, inner_pc, S);
832 }
833
834 CHKERR PetscFree(subksp);
836 };
837
838 CHKERR KSPSetUp(ksp);
839 if (AT == BLOCK_SCHUR || AT == BLOCK_MAT) {
840 CHKERR set_diagonal_pc(pc);
841 CHKERR set_mg_for_schur_complement(pc, schur_dm, S);
842 }
843
844 } else {
845 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
846 "PC is not set to PCFIELDSPLIT");
847 }
849}
@ 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:1895
auto createDMBlockMat(DM dm)
Definition DMMoFEM.hpp:1214
static constexpr int 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: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 1692 of file plastic.cpp.

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

◆ 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 1688 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 1687 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: