17 "Is expected that schur matrix is not allocated. This is "
18 "possible only is PC is set up twice");
42 auto get_ents_by_dim = [&](
int dim) {
48 std::vector<std::string> schur_field_list{
61 std::vector<std::string> field_list{
epCorePtr->piolaStress,
64 auto create_schur_dm = [&](SmartPetscObj<DM> &dm_sub) {
75 auto faces_ptr = boost::make_shared<Range>(get_ents_by_dim(
SPACE_DIM - 1));
76 std::vector<boost::shared_ptr<Range>> dm_range_list{faces_ptr,
nullptr};
78 if (field_list.size() != dm_range_list.size()) {
80 "Both ranges should have the same size");
84 for (
auto f : field_list) {
85 MOFEM_LOG(
"EP", Sev::inform) <<
"Add schur field: " <<
f;
94 auto create_a00_is = [&](SmartPetscObj<IS> &is_a00) {
97 std::vector<SmartPetscObj<IS>> is_vec;
98 std::vector<Range *> range_list_ptr(schur_field_list.size(),
nullptr);
99 range_list_ptr.back() = &vols;
102 for (
auto f : schur_field_list) {
103 SmartPetscObj<IS> is;
106 range_list_ptr[r_idx]);
107 is_vec.push_back(is);
112 for (
auto i = 1;
i < is_vec.size(); ++
i) {
114 CHKERR ISExpand(is_a00, is_vec[
i], &is_union_raw);
115 is_a00 = SmartPetscObj<IS>(is_union_raw);
123 CHKERR KSPSetFromOptions(solver);
124 CHKERR KSPGetPC(solver, &pc);
125 PetscBool is_pcfs = PETSC_FALSE;
126 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
129 SmartPetscObj<DM> schur_dm, a00_dm;
130 CHKERR create_schur_dm(schur_dm);
136 "Is expected that schur matrix is not allocated. This is "
137 "possible only is PC is set up twice");
142 auto set_ops = [&]() {
144 auto range_ptr = boost::make_shared<Range>(get_ents_by_dim(
SPACE_DIM));
145 std::vector<boost::shared_ptr<Range>> ranges_list(schur_field_list.size(),
147 ranges_list.back() = range_ptr;
148 std::vector<SmartPetscObj<AO>> ao_list(schur_field_list.size(),
149 SmartPetscObj<AO>());
150 std::vector<SmartPetscObj<Mat>> mat_list(schur_field_list.size(),
151 SmartPetscObj<Mat>());
152 std::vector<bool> symm_list(schur_field_list.size(),
false);
156 ao_list.back() =
aoUp;
159 const bool symmetric_system =
162 epCorePtr->elasticFeLhs->getOpPtrVector().push_front(
163 new OpSchurAssembleBegin());
164 epCorePtr->elasticFeLhs->getOpPtrVector().push_back(
165 new OpSchurAssembleEnd<SCHUR_DGESV>(schur_field_list, ranges_list,
166 ao_list, mat_list, symm_list,
168 epCorePtr->elasticBcLhs->getOpPtrVector().push_front(
169 new OpSchurAssembleBegin());
170 epCorePtr->elasticBcLhs->getOpPtrVector().push_back(
171 new OpSchurAssembleEnd<SCHUR_DGESV>(schur_field_list, ranges_list,
172 ao_list, mat_list, symm_list,
178 auto set_pc = [&]() {
181 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER,
S);
189 epCorePtr->elasticFeLhs->getOpPtrVector().push_front(
190 new OpSchurAssembleBegin());
191 epCorePtr->elasticFeLhs->getOpPtrVector().push_back(
192 new OpSchurAssembleEnd<SCHUR_DGESV>({}, {}, {}, {}, {}));
193 epCorePtr->elasticBcLhs->getOpPtrVector().push_front(
194 new OpSchurAssembleBegin());
195 epCorePtr->elasticBcLhs->getOpPtrVector().push_back(
196 new OpSchurAssembleEnd<SCHUR_DGESV>({}, {}, {}, {}, {}));
204 MOFEM_LOG(
"EP", Sev::verbose) <<
"Zero Schur";
216 MOFEM_LOG(
"EP", Sev::verbose) <<
"Assemble Schur";
217 CHKERR MatAssemblyBegin(
S, MAT_FINAL_ASSEMBLY);
218 CHKERR MatAssemblyEnd(
S, MAT_FINAL_ASSEMBLY);
220 CHKERR MatAssemblyBegin(
M, MAT_FINAL_ASSEMBLY);
221 CHKERR MatAssemblyEnd(
M, MAT_FINAL_ASSEMBLY);
222 CHKERR MatAssemblyBegin(
P, MAT_FINAL_ASSEMBLY);
223 CHKERR MatAssemblyEnd(
P, MAT_FINAL_ASSEMBLY);
224 CHKERR MatAXPY(
P, 1,
M, SAME_NONZERO_PATTERN);
229 boost::shared_ptr<EshelbianCore::SetUpSchur>
231 SmartPetscObj<Mat>
m,
232 SmartPetscObj<Mat> p,
234 return boost::shared_ptr<SetUpSchur>(