v0.16.3
Loading...
Searching...
No Matches
SetUpSchurImpl.cpp
Go to the documentation of this file.
1/** @file SetUpSchurImpl
2 * @brief
3 * @date 2023-05-13
4 *
5 * @license{This project is released under the MIT License.}
6 *
7 */
8
10
12 : SetUpSchur(), mField(m_field), epCorePtr(ep_core_ptr) {}
13 virtual ~SetUpSchurImpl() {}
14
18
19private:
22
25
26 boost::shared_ptr<std::vector<boost::weak_ptr<NumeredDofEntity>>>
27 piolaZeroDofsVec; //< Dofs on crack surface
28 boost::shared_ptr<std::vector<unsigned char>>
29 piolaZeroDofsMarker; //< marker for crack dofs on surface
30
50
51 boost::shared_ptr<P_MultiGridData> pMGPtr;
52
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 };
59
60 auto getA00Fields() {
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 }
71};
72
75
76 auto create_schur_dm = [&](SmartPetscObj<DM> &dm_sub) {
78
79 dm_sub = createDM(mField.get_comm(), "DMMOFEM_MG");
80 CHKERR DMMoFEMCreateSubDM(dm_sub, epCorePtr->dmElastic, "SUB_SCHUR");
81 CHKERR DMMoFEMSetSquareProblem(dm_sub, PETSC_TRUE);
82 CHKERR DMMoFEMSetIsPartitioned(dm_sub, PETSC_TRUE);
85
86 int r_idx = 0;
87 auto [schur_field_list, schur_range_list] = getSchurFields();
88 for (auto f : schur_field_list) {
89 MOFEM_LOG("EP", Sev::inform) << "Add schur field: " << f;
90 CHKERR DMMoFEMAddSubFieldRow(dm_sub, f, schur_range_list[r_idx]);
91 CHKERR DMMoFEMAddSubFieldCol(dm_sub, f, schur_range_list[r_idx]);
92 ++r_idx;
93 }
94 CHKERR DMSetUp(dm_sub);
96 };
97
98 auto create_a00_dm = [&](SmartPetscObj<DM> &dm_sub) {
100 dm_sub = createDM(mField.get_comm(), "DMMOFEM");
101 CHKERR DMMoFEMCreateSubDM(dm_sub, epCorePtr->dmElastic, "SUB_A00");
102 CHKERR DMMoFEMSetSquareProblem(dm_sub, PETSC_TRUE);
103 CHKERR DMMoFEMSetIsPartitioned(dm_sub, PETSC_TRUE);
107
108 int r_idx = 0;
109 auto [a00_field_list, a00_range_list] = getA00Fields();
110 for (auto f : a00_field_list) {
111 MOFEM_LOG("EP", Sev::inform) << "Add a00 field: " << f;
112 CHKERR DMMoFEMAddSubFieldRow(dm_sub, f, a00_range_list[r_idx]);
113 CHKERR DMMoFEMAddSubFieldCol(dm_sub, f, a00_range_list[r_idx]);
114 ++r_idx;
115 }
116 CHKERR DMSetUp(dm_sub);
118 };
119
120 auto get_snes = [&](TS ts) {
121 SNES snes;
122 CHKERR TSGetSNES(ts, &snes);
123 return snes;
124 };
125
126 auto get_ksp = [&](SNES snes) {
127 KSP ksp;
128 CHKERR SNESGetKSP(snes, &ksp);
129 CHKERR KSPSetFromOptions(ksp);
130 return ksp;
131 };
132
133 auto get_pc = [&](KSP ksp) {
134 PC pc;
135 CHKERR KSPGetPC(ksp, &pc);
136 return pc;
137 };
138
139 auto ksp = get_ksp(get_snes(ts));
140 auto pc = get_pc(ksp);
141
142 PetscBool is_pcfs = PETSC_FALSE;
143 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
144 if (epCorePtr->alphaOmegaPrec > 0. && !is_pcfs)
146 "-alpha_omega_prec requires the elastic PCFIELDSPLIT Schur solver");
147
148 if (is_pcfs) {
149 const bool use_rotation_prec = epCorePtr->alphaOmegaPrec > 0.;
150 if (use_rotation_prec) {
151 PCCompositeType split_type;
152 CHKERR PCFieldSplitGetType(pc, &split_type);
153 if (split_type != PC_COMPOSITE_SCHUR)
155 "-alpha_omega_prec requires -elastic_pc_fieldsplit_type schur");
156 }
157
158 MOFEM_LOG("EP", Sev::inform) << "SetUpSchurImpl::setUp: PCFIELDSPLIT";
159
160 SmartPetscObj<DM> schur_dm, a00_dm;
161 CHKERR create_schur_dm(schur_dm);
162 CHKERR create_a00_dm(a00_dm);
163
164 auto dm_elastic = epCorePtr->dmElastic;
165 auto vol_elem_name = epCorePtr->elementVolumeName;
166 auto skel_elem_name = epCorePtr->skeletonElement;
167 auto contact_elem_name = epCorePtr->contactElement;
168 auto natural_bc_element_name = epCorePtr->naturalBcElement;
169
170 std::vector<std::pair<std::string, std::string>> mat_block_list = {
171
180
181 };
182
183 mat_block_list.push_back({epCorePtr->rotAxis, epCorePtr->rotAxis});
184 auto add_pair = [&](const std::string &row, const std::string &col) {
185 if (mField.check_field(row) && mField.check_field(col)) {
186 mat_block_list.emplace_back(row, col);
187 if (row != col)
188 mat_block_list.emplace_back(col, row);
189 }
190 };
191 for (const auto &[row, col] :
192 epCorePtr->physicalEquations->getMaterialCouplings(*epCorePtr))
193 add_pair(row, col);
194
195 auto get_nested_mat_data = [&](auto schur_dm, auto block_dm) {
196 auto block_mat_data = createBlockMatStructure(
197 dm_elastic,
198
199 {
200
201 {vol_elem_name, mat_block_list},
202
203 {skel_elem_name,
204
205 {
206
212
213 }},
214
215 {contact_elem_name,
216
217 {
218
224
225 }},
226
227 {natural_bc_element_name,
228
229 {
230
234
235 }}
236
237 }
238
239 );
240
241 auto [a00_field_list, a00_range_list] = getA00Fields();
242
244
245 {schur_dm, a00_dm}, block_mat_data,
246
247 a00_field_list,
248
249 a00_range_list,
250
251 use_rotation_prec
252
253 );
254 };
255
256 auto nested_mat_data = get_nested_mat_data(schur_dm, a00_dm);
258 const auto block_mat_data = std::get<2>(*nested_mat_data);
259 if (use_rotation_prec)
260 epCorePtr->elasticFeLhs->getOpPtrVector().push_back(
263 CHKERR DMSetMatType(epCorePtr->dmElastic, MATSHELL);
264
267
268 if (std::abs(epCorePtr->alphaRho) >
269 std::numeric_limits<double>::epsilon()) {
270 auto swap_assemble = [](TS ts, PetscReal t, Vec u, Vec u_t, Vec utt,
271 PetscReal a, PetscReal aa, Mat A, Mat B,
272 void *ctx) {
273 return TsSetI2Jacobian(ts, t, u, u_t, utt, a, aa, B, A, ctx);
274 };
275 auto ts_ctx_ptr = getDMTsCtx(epCorePtr->dmElastic);
276 CHKERR TSSetI2Jacobian(ts, m, p, swap_assemble, ts_ctx_ptr.get());
277 } else {
278 auto swap_assemble = [](TS ts, PetscReal t, Vec u, Vec u_t, PetscReal a,
279 Mat A, Mat B, void *ctx) {
280 return TsSetIJacobian(ts, t, u, u_t, a, B, A, ctx);
281 };
282 auto ts_ctx_ptr = getDMTsCtx(epCorePtr->dmElastic);
283 CHKERR TSSetIJacobian(ts, m, p, swap_assemble, ts_ctx_ptr.get());
284 }
285 CHKERR KSPSetOperators(ksp, m, p);
286
287 auto set_assembly = [&]() {
289
290 aoS = getDMSubData(schur_dm)->getSmartRowMap();
291 S = createDMHybridisedL2Matrix(schur_dm);
292 auto set_block_size = [&]<FieldApproximationBase Base>() {
295 CHKERR MatSetBlockSize(
296 S, SPACE_DIM * NBFACETRI_L2(Orders::hybrid(epCorePtr->spaceOrder)));
298 };
299 CHKERR epCorePtr->withFieldOrders(set_block_size);
300 epCorePtr->S = S;
301 epCorePtr->aoS = aoS;
302
303 auto set_assemble = [&]() {
305 auto schur_asmb_pre_proc_lhs = boost::make_shared<FEMethod>();
306 auto schur_asmb_pre_proc_rhs = boost::make_shared<FEMethod>();
307
308 schur_asmb_pre_proc_lhs->preProcessHook = [this]() {
310 CHKERR MatZeroEntries(S);
312 };
313
314 auto *schur_asmb_pre_proc_rhs_ptr = schur_asmb_pre_proc_rhs.get();
315 schur_asmb_pre_proc_rhs->preProcessHook =
316 [this, schur_asmb_pre_proc_rhs_ptr]() {
318 auto prb_ptr = schur_asmb_pre_proc_rhs_ptr->problemPtr;
319 auto dofs_prb = prb_ptr->getNumeredRowDofsPtr();
320
321 auto crack_faces = epCorePtr->crackFaces;
322 piolaZeroDofsVec->clear();
323 CHKERR mField.getInterface<ProblemsManager>()
324 ->getSideDofsOnBrokenSpaceEntities(
325 *piolaZeroDofsVec, prb_ptr->getName(), ROW,
326 epCorePtr->piolaStress, *crack_faces, SPACE_DIM, 0,
327 SPACE_DIM);
328
329 piolaZeroDofsMarker->resize(dofs_prb->size(), 0);
330 piolaZeroDofsMarker->clear();
331 for (auto &dof : *piolaZeroDofsVec) {
332 if (auto dof_ptr = dof.lock()) {
333 auto idx = dof_ptr->getPetscLocalDofIdx();
334 (*piolaZeroDofsMarker)[idx] = 1;
335 }
336 }
337 // FIXME: This needs investigation, true is required for fracture
338 constexpr bool hard_coded_set_bc_debug = true;
339 if constexpr (hard_coded_set_bc_debug) {
340
341 auto problem_name =
342 schur_asmb_pre_proc_rhs_ptr->problemPtr->getName();
343 auto crack_faces = epCorePtr->crackFaces;
344
345 SmartPetscObj<IS> crack_hybrid_is;
346 CHKERR epCorePtr->mField.getInterface<ISManager>()
347 ->isCreateProblemFieldAndRankLocal(
348 problem_name, ROW, epCorePtr->hybridSpatialDisp, 0,
349 SPACE_DIM, crack_hybrid_is, &*crack_faces);
350
351 SmartPetscObj<IS> crack_piola_is;
352 CHKERR epCorePtr->mField.getInterface<ISManager>()
353 ->isCreateProblemBrokenFieldAndRankLocal(*piolaZeroDofsVec,
354 crack_piola_is);
355
356 const double *a_x;
357 CHKERR VecGetArrayRead(schur_asmb_pre_proc_rhs_ptr->x, &a_x);
358 auto zero_by_is = [&](auto is) {
360 const PetscInt *is_array;
361 PetscInt is_size;
362 CHKERR ISGetLocalSize(is, &is_size);
363 CHKERR ISGetIndices(is, &is_array);
364 for (int i = 0; i != is_size; ++i) {
365 // FIXME: That is irregular, need investigate if needed
366 const_cast<double *>(a_x)[is_array[i]] = 0;
367 }
368 CHKERR ISRestoreIndices(is, &is_array);
370 };
371
372 CHKERR zero_by_is(crack_hybrid_is);
373 CHKERR zero_by_is(crack_piola_is);
374
375 CHKERR VecRestoreArrayRead(schur_asmb_pre_proc_rhs_ptr->x,
376 &a_x);
377
378 CHKERR epCorePtr->mField.getInterface<VecManager>()
379 ->setLocalGhostVector(problem_name, COL,
380 schur_asmb_pre_proc_rhs_ptr->x,
381 INSERT_VALUES, SCATTER_REVERSE);
382 }
383
385 };
386
387 auto schur_asmb_post_proc_lhs = boost::make_shared<FEMethod>();
388 auto schur_asmb_post_proc_rhs = boost::make_shared<FEMethod>();
389
390 auto schur_asmb_post_proc_rhs_weak_ptr =
391 boost::weak_ptr<FEMethod>(schur_asmb_post_proc_rhs);
392 schur_asmb_post_proc_rhs->postProcessHook =
393 [this, schur_asmb_post_proc_rhs_weak_ptr]() {
395
396 if (auto schur_asmb_post_proc_rhs_ptr =
397 schur_asmb_post_proc_rhs_weak_ptr.lock()) {
398
399 CHKERR VecGhostUpdateBegin(schur_asmb_post_proc_rhs_ptr->f,
400 ADD_VALUES, SCATTER_REVERSE);
401 CHKERR VecGhostUpdateEnd(schur_asmb_post_proc_rhs_ptr->f,
402 ADD_VALUES, SCATTER_REVERSE);
403 CHKERR VecAssemblyBegin(schur_asmb_post_proc_rhs_ptr->f);
404 CHKERR VecAssemblyEnd(schur_asmb_post_proc_rhs_ptr->f);
405 *(schur_asmb_post_proc_rhs_ptr->vecAssembleSwitch) = false;
406
407 {
408
409 auto problem_name =
410 schur_asmb_post_proc_rhs_ptr->problemPtr->getName();
411
412 auto crack_faces = epCorePtr->crackFaces;
413
414 SmartPetscObj<IS> crack_hybrid_is;
415 CHKERR epCorePtr->mField.getInterface<ISManager>()
416 ->isCreateProblemFieldAndRankLocal(
417 problem_name, ROW, epCorePtr->hybridSpatialDisp, 0,
418 SPACE_DIM, crack_hybrid_is, &*crack_faces);
419
420 SmartPetscObj<IS> crack_piola_is;
421 CHKERR epCorePtr->mField.getInterface<ISManager>()
422 ->isCreateProblemBrokenFieldAndRankLocal(
423 *piolaZeroDofsVec, crack_piola_is);
424
425 double *a_f;
426 CHKERR VecGetArray(schur_asmb_post_proc_rhs_ptr->f, &a_f);
427 const double *a_x;
428 CHKERR VecGetArrayRead(schur_asmb_post_proc_rhs_ptr->x, &a_x);
429 auto zero_by_is = [&](auto is) {
431 const PetscInt *is_array;
432 PetscInt is_size;
433 CHKERR ISGetLocalSize(is, &is_size);
434 CHKERR ISGetIndices(is, &is_array);
435 for (int i = 0; i != is_size; ++i) {
436 a_f[is_array[i]] = -a_x[is_array[i]];
437 }
438 CHKERR ISRestoreIndices(is, &is_array);
440 };
441
442 CHKERR zero_by_is(crack_hybrid_is);
443 CHKERR zero_by_is(crack_piola_is);
444
445 CHKERR VecRestoreArray(schur_asmb_post_proc_rhs_ptr->f, &a_f);
446 CHKERR VecRestoreArrayRead(schur_asmb_post_proc_rhs_ptr->x,
447 &a_x);
448 }
449
450 } else {
451 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
452 "schur_asmb_post_proc_rhs is expired");
453 }
454
456 };
457
458 auto schur_asmb_post_proc_lhs_weak_ptr =
459 boost::weak_ptr<FEMethod>(schur_asmb_post_proc_lhs);
460 schur_asmb_post_proc_lhs->postProcessHook =
461 [this, schur_asmb_post_proc_lhs_weak_ptr, block_mat_data,
462 use_rotation_prec]() {
464
465 if (auto schur_asmb_post_proc_lhs_ptr =
466 schur_asmb_post_proc_lhs_weak_ptr.lock()) {
467
468 if (pMGPtr) {
469 CHKERR pMGPtr->setUP();
470 pMGPtr.reset();
471 }
472
473 auto crack_faces = epCorePtr->crackFaces;
474
475 // Assemble matrix
476 CHKERR MatAssemblyBegin(schur_asmb_post_proc_lhs_ptr->B,
477 MAT_FINAL_ASSEMBLY);
478 CHKERR MatAssemblyEnd(schur_asmb_post_proc_lhs_ptr->B,
479 MAT_FINAL_ASSEMBLY);
480 *(schur_asmb_post_proc_lhs_ptr->matAssembleSwitch) = false;
481 {
482 SmartPetscObj<IS> crack_hybrid_is;
483 CHKERR epCorePtr->mField.getInterface<ISManager>()
484 ->isCreateProblemFieldAndRank(
485 "ELASTIC_PROBLEM", ROW, epCorePtr->hybridSpatialDisp,
486 0, SPACE_DIM, crack_hybrid_is, &*crack_faces);
487 CHKERR MatZeroRowsColumnsIS(schur_asmb_post_proc_lhs_ptr->B,
488 crack_hybrid_is, 1, PETSC_NULLPTR,
489 PETSC_NULLPTR);
490 }
491 {
492 SmartPetscObj<IS> crack_piola_is;
493 CHKERR epCorePtr->mField.getInterface<ISManager>()
494 ->isCreateProblemBrokenFieldAndRank(*piolaZeroDofsVec,
495 crack_piola_is);
496 CHKERR MatZeroRowsColumnsIS(schur_asmb_post_proc_lhs_ptr->B,
497 crack_piola_is, 1, PETSC_NULLPTR,
498 PETSC_NULLPTR);
499 }
500
501 auto [a00_field_list, a00_range_list] = getA00Fields();
502 // Use the same shifted A00 for its solve and the Schur PC.
503 // Restore the exact parent operator even if assembly fails.
504 if (use_rotation_prec)
505 CHKERR schurSwitchPreconditioner(block_mat_data);
506 const auto schur_error = assembleBlockMatSchur(
507 epCorePtr->mField, schur_asmb_post_proc_lhs_ptr->B, S,
508 a00_field_list, a00_range_list, aoS);
509 if (use_rotation_prec)
510 CHKERR schurSwitchPreconditioner(block_mat_data);
511 CHKERR schur_error;
512 epCorePtr->a00FieldList = a00_field_list;
513 epCorePtr->a00RangeList = a00_range_list;
514
515 // Apply essential constrains to Schur complement
516 CHKERR MatAssemblyBegin(S, MAT_FINAL_ASSEMBLY);
517 CHKERR MatAssemblyEnd(S, MAT_FINAL_ASSEMBLY);
518
519 SmartPetscObj<IS> crack_hybrid_is;
520 CHKERR epCorePtr->mField.getInterface<ISManager>()
521 ->isCreateProblemFieldAndRank(
522 "SUB_SCHUR", ROW, epCorePtr->hybridSpatialDisp, 0,
523 SPACE_DIM, crack_hybrid_is, &*crack_faces);
524 epCorePtr->crackHybridIs = crack_hybrid_is;
525 CHKERR MatZeroRowsColumnsIS(S, crack_hybrid_is, 1,
526 PETSC_NULLPTR, PETSC_NULLPTR);
527
528 } else {
529 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB,
530 "schur_asmb_post_proc_lhs is expired");
531 }
532
534 };
535
536 auto ts_ctx_ptr = getDMTsCtx(epCorePtr->dmElastic);
537 ts_ctx_ptr->getPreProcessIFunction().push_front(
538 schur_asmb_pre_proc_rhs);
539 ts_ctx_ptr->getPostProcessIFunction().push_back(
540 schur_asmb_post_proc_rhs);
541 ts_ctx_ptr->getPreProcessIJacobian().push_front(
542 schur_asmb_pre_proc_lhs);
543 ts_ctx_ptr->getPostProcessIJacobian().push_back(
544 schur_asmb_post_proc_lhs);
546 };
547
549 boost::make_shared<std::vector<boost::weak_ptr<NumeredDofEntity>>>();
550 piolaZeroDofsMarker = boost::make_shared<std::vector<unsigned char>>();
551 CHKERR set_assemble();
552
554 };
555
556 auto set_pc = [&]() {
558 auto a00_is = getDMSubData(a00_dm)->getSmartRowIs();
559 auto schur_is = getDMSubData(schur_dm)->getSmartRowIs();
560 CHKERR PCFieldSplitSetIS(pc, NULL, a00_is);
561 CHKERR PCFieldSplitSetIS(pc, NULL, schur_is);
562 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER, S);
564 };
565
566 auto set_diagonal_pc = [&]() {
568 KSP *subksp;
569 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
570 auto get_pc = [](auto ksp) {
571 PC pc_raw;
572 CHKERR KSPGetPC(ksp, &pc_raw);
573 return SmartPetscObj<PC>(pc_raw, true); // bump reference
574 };
575 CHKERR setSchurA00MatSolvePC(get_pc(subksp[0]));
576
577 auto set_pc_p_mg = [&](auto dm, auto pc, auto S) {
579 CHKERR PCSetDM(pc, dm);
580 PetscBool same = PETSC_FALSE;
581 PetscObjectTypeCompare((PetscObject)pc, PCMG, &same);
582 if (same) {
583 auto smart_pc = SmartPetscObj<PC>(pc, true);
584 pMGPtr = boost::make_shared<P_MultiGridData>(dm, smart_pc, S);
585 }
586 PetscObjectTypeCompare((PetscObject)pc, PCKSP, &same);
587 if (same) {
588 MOFEM_LOG("EP", Sev::inform)
589 << "SetUpSchurImpl::setUp: fieldsplit 1 PCKSP";
590 CHKERR PCSetFromOptions(pc);
591 KSP ksp;
592 CHKERR PCKSPGetKSP(pc, &ksp);
593 CHKERR KSPSetFromOptions(ksp);
594 PC ksp_pc;
595 CHKERR KSPGetPC(ksp, &ksp_pc);
596 CHKERR PCSetFromOptions(ksp_pc);
597 PetscObjectTypeCompare((PetscObject)ksp_pc, PCMG, &same);
598 if (same) {
599 auto smart_pc = SmartPetscObj<PC>(ksp_pc, true);
600 pMGPtr = boost::make_shared<P_MultiGridData>(dm, smart_pc, S);
601 }
602 }
604 };
605
606 CHKERR set_pc_p_mg(schur_dm, get_pc(subksp[1]), S);
607
608 CHKERR PetscFree(subksp);
610 };
611
612 CHKERR set_assembly();
613 CHKERR set_pc();
614 CHKERR TSSetUp(ts);
615 CHKERR KSPSetUp(ksp);
616 CHKERR set_diagonal_pc();
617
618 } else {
619 MOFEM_LOG("EP", Sev::inform) << "SetUpSchurImpl::setUp: PCLU or other";
620
622 // Plastic coupling may extend the elastic matrix graph on first assembly.
624 CHKERR MatSetOption(m, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE);
625 auto ts_ctx_ptr = getDMTsCtx(epCorePtr->dmElastic);
626 CHKERR TSSetIJacobian(ts, m, m, TsSetIJacobian, ts_ctx_ptr.get());
627
628 epCorePtr->elasticFeLhs->getOpPtrVector().push_front(
630 epCorePtr->elasticFeLhs->getOpPtrVector().push_back(
632 epCorePtr->elasticBcLhs->getOpPtrVector().push_front(
634 epCorePtr->elasticBcLhs->getOpPtrVector().push_back(
636 }
637
639}
640
641boost::shared_ptr<EshelbianCore::SetUpSchur>
643 EshelbianCore *ep_core_ptr) {
644 return boost::shared_ptr<SetUpSchur>(
645 new SetUpSchurImpl(m_field, ep_core_ptr));
646}
SmartPetscObj< KSP > ksp
constexpr double a
@ COL
@ ROW
FieldApproximationBase
approximation base
Definition definitions.h:58
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_INVALID_DATA
Definition definitions.h:36
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
Definition DMMoFEM.cpp:1142
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:244
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition DMMoFEM.cpp:517
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
Definition DMMoFEM.cpp:479
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
Definition DMMoFEM.cpp:267
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
Definition DMMoFEM.cpp:309
auto createDMMatrix(DM dm)
Get smart matrix from DM.
Definition DMMoFEM.hpp:1207
virtual bool check_field(const std::string &name) const =0
check if field is in database
#define MOFEM_LOG(channel, severity)
Log.
#define NBFACETRI_L2(P)
Number of base functions on triangle for L2 space.
FTensor::Index< 'i', SPACE_DIM > i
const FTensor::Tensor2< T, Dim, Dim > Vec
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
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:1292
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:4196
MoFEMErrorCode schurSwitchPreconditioner(boost::shared_ptr< BlockStructure > block_mat_data)
Switch preconditioner.
Definition Schur.cpp:4385
MoFEMErrorCode setSchurA00MatSolvePC(SmartPetscObj< PC > pc)
Set PC for A00 block.
Definition Schur.cpp:4238
boost::shared_ptr< PCMGSetUpViaApproxOrdersCtx > createPCMGSetUpViaApproxOrdersCtx(DM dm, Mat A, bool use_shell_mat)
createPCMGSetUpViaApproxOrdersCtx
auto createDMHybridisedL2Matrix(DM dm)
Get smart hybridised L2 matrix from DM.
Definition DMMoFEM.hpp:1220
auto getDMSubData(DM dm)
Get sub problem data structure.
Definition DMMoFEM.hpp:1308
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
MoFEMErrorCode PCMGSetUpViaApproxOrders(PC pc, boost::shared_ptr< PCMGSetUpViaApproxOrdersCtx > ctx, int verb)
Function build MG structure.
boost::shared_ptr< BlockStructure > createBlockMatStructure(DM dm, SchurFEOpsFEandFields schur_fe_op_vec)
Create block matrix structure.
Definition Schur.cpp:2415
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)
Create structure of nested matrix [A11 A10; A01 A00].
Definition Schur.cpp:3667
MoFEMErrorCode DMMoFEMSetNestSchurData(DM dm, boost::shared_ptr< NestSchurData >)
Definition DMMoFEM.cpp:1584
auto createDMNestSchurMat(DM dm)
Definition DMMoFEM.hpp:1234
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
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 complement S = A11 - A10 A00^{-1} A01 from block matrix.
Definition Schur.cpp:3107
OpSchurAssembleBase * createOpSchurAssembleBegin()
Definition Schur.cpp:4191
auto createDMBlockMat(DM dm)
Definition DMMoFEM.hpp:1227
constexpr double t
plate stiffness
Definition plate.cpp:58
FTensor::Index< 'm', 3 > m
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field, EshelbianCore *ep_core_ptr)
std::vector< boost::shared_ptr< Range > > a00RangeList
const std::string skeletonElement
MoFEM::Interface & mField
const std::string spatialL2Disp
SmartPetscObj< IS > crackHybridIs
boost::shared_ptr< FaceElementForcesAndSourcesCore > elasticBcLhs
const std::string elementVolumeName
const std::string piolaStress
std::vector< std::string > a00FieldList
const std::string bubbleField
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeLhs
boost::shared_ptr< PhysicalEquations > physicalEquations
const std::string rotAxis
const std::string contactDisp
double alphaOmegaPrec
Rotation-gradient shift of the Schur preconditioner.
static PetscBool plasticVolume
const std::string naturalBcElement
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< Range > crackFaces
const std::string hybridSpatialDisp
SmartPetscObj< DM > dmElastic
Elastic problem.
MoFEMErrorCode withFieldOrders(Op &&op) const
const std::string contactElement
virtual MPI_Comm & get_comm() const =0
Deprecated interface functions.
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
P_MultiGridData(SmartPetscObj< DM > dm, SmartPetscObj< PC > pc, SmartPetscObj< Mat > S)
EshelbianCore * epCorePtr
boost::shared_ptr< std::vector< unsigned char > > piolaZeroDofsMarker
SmartPetscObj< Mat > S
boost::shared_ptr< std::vector< boost::weak_ptr< NumeredDofEntity > > > piolaZeroDofsVec
boost::shared_ptr< P_MultiGridData > pMGPtr
MoFEMErrorCode setUp(TS ts)
MoFEMErrorCode setUp(SmartPetscObj< KSP >)
virtual ~SetUpSchurImpl()
MoFEMErrorCode postProc()
SmartPetscObj< AO > aoS
MoFEMErrorCode preProc()
MoFEM::Interface & mField
SetUpSchurImpl(MoFEM::Interface &m_field, EshelbianCore *ep_core_ptr)
[Push operators to pipeline]
constexpr int SPACE_DIM
[Define dimension]
Definition elastic.cpp:18
constexpr AssemblyType A
[Define dimension]
Definition elastic.cpp:21