13struct ProjectionEvents {
16 ierr = PetscLogEventRegister(
"ProjectionInit", 0, &projectionInit);
17 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
18 ierr = PetscLogEventRegister(
"ProjectionQ", 0, &projectionQ);
19 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
20 ierr = PetscLogEventRegister(
"ProjectionP", 0, &projectionP);
21 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
22 ierr = PetscLogEventRegister(
"ProjectionR", 0, &projectionR);
23 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
24 ierr = PetscLogEventRegister(
"ProjectionRT", 0, &projectionRT);
25 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
27 PetscLogEventRegister(
"ProjectionCTC_QTKQ", 0, &projectionCTCPlusQTKQ);
28 CHKERRABORT(PETSC_COMM_WORLD,
ierr);
39const ProjectionEvents &getProjectionEvents() {
40 static const ProjectionEvents events;
45 LogEventScope(PetscLogEvent event, MPI_Comm comm)
50 const auto ierr = PetscLogEventEnd(event, 0, 0, 0, 0);
51 CHKERRABORT(comm,
ierr);
58 CHKERR PetscLogEventEnd(event, 0, 0, 0, 0);
68using ContextOwner = boost::shared_ptr<ConstrainMatrixCtx>;
69constexpr char inverseCCTConstraintMatrixKey[] =
70 "_MoFEM_ConstrainMatrixCtx_inverse_CCT_constraint_matrix";
72struct CCTInverseKSPCtx {
73 CCTInverseKSPCtx(MPI_Comm
comm, Mat constrain_matrix, KSP external_ksp,
74 const std::string &options_prefix)
75 :
comm(
comm),
C(constrain_matrix,
true),
ksp(external_ksp,
true),
79 MoFEMErrorCode apply(Mat inverse_mat, Vec x, Vec f,
bool transpose);
83 SmartPetscObj<Mat>
CT;
84 SmartPetscObj<Mat>
CCT;
85 SmartPetscObj<KSP>
ksp;
93enum class ProjectionOperator { Q, P,
R, RT, CTCPlusQTKQ };
99MoFEMErrorCode projectionMatrixMultCTCPlusQTKQ(Mat mat, Vec x, Vec f);
103PetscErrorCode destroyProjectionMatrixContext(
void *void_ctx) {
104 delete static_cast<ContextOwner *
>(void_ctx);
108PetscErrorCode destroyCCTInverseKSPContext(
void *void_ctx) {
109 delete static_cast<CCTInverseKSPCtx *
>(void_ctx);
123 Mat inverse_cct)
override;
144 const char *object_name)
const;
146 PetscInt global_size,
147 const char *vector_name)
const;
149 Mat inverse_cct)
const;
181 :
comm(
comm), xDm(x_dm, true), yDm(y_dm, true) {
182 getProjectionEvents();
187 :
comm(
comm), scatter(scatter, true), buildScatterFromDms(false) {
188 getProjectionEvents();
193 const char *object_name)
const {
197 <<
"Null PETSc object supplied for " << object_name;
201 MPI_Comm object_comm;
202 CHKERR PetscObjectGetComm(
object, &object_comm);
204 CHKERR MPI_Comm_compare(
comm, object_comm, &relation);
205 if (relation > MPI_CONGRUENT) {
207 << object_name <<
" uses a communicator incompatible with the context";
209 "PETSc object uses an incompatible communicator");
216 PetscInt global_size,
217 const char *vector_name)
const {
220 PetscInt actual_local_size;
221 PetscInt actual_global_size;
222 CHKERR VecGetLocalSize(vec, &actual_local_size);
223 CHKERR VecGetSize(vec, &actual_global_size);
224 if (actual_local_size != local_size || actual_global_size != global_size) {
226 << vector_name <<
" layout is (" << actual_local_size <<
", "
227 << actual_global_size <<
"), expected (" << local_size <<
", "
228 << global_size <<
")";
230 "Vector layout is incompatible with the projection context");
237 Mat inverse_cct)
const {
240 "constraint matrix C");
242 "inverse C C^T action");
244 PetscInt c_local_rows;
245 PetscInt c_local_columns;
246 PetscInt c_global_rows;
247 PetscInt c_global_columns;
248 PetscInt inverse_local_rows;
249 PetscInt inverse_local_columns;
250 PetscInt inverse_global_rows;
251 PetscInt inverse_global_columns;
252 CHKERR MatGetLocalSize(constrain_matrix, &c_local_rows, &c_local_columns);
253 CHKERR MatGetSize(constrain_matrix, &c_global_rows, &c_global_columns);
254 CHKERR MatGetLocalSize(inverse_cct, &inverse_local_rows,
255 &inverse_local_columns);
256 CHKERR MatGetSize(inverse_cct, &inverse_global_rows, &inverse_global_columns);
257 if (inverse_local_rows != c_local_rows ||
258 inverse_local_columns != c_local_rows ||
259 inverse_global_rows != c_global_rows ||
260 inverse_global_columns != c_global_rows) {
262 <<
"Inverse C C^T layout, local (" << inverse_local_rows <<
", "
263 << inverse_local_columns <<
"), global (" << inverse_global_rows <<
", "
264 << inverse_global_columns
265 <<
"), does not match the row layout of C, local " << c_local_rows
266 <<
", global " << c_global_rows;
268 "Inverse C C^T action has an incompatible layout");
272 CHKERR MatHasOperation(inverse_cct, MATOP_MULT, &has_mult);
275 "Inverse C C^T action does not implement MatMult");
277 PetscObject associated_c =
nullptr;
279 inverseCCTConstraintMatrixKey, &associated_c);
280 if (associated_c && associated_c !=
getPetscObject(constrain_matrix)) {
282 <<
"KSP-backed inverse C C^T action was created for a different "
285 "Inverse C C^T action is associated with a different C");
294 PetscInt local_columns;
295 PetscInt global_rows;
296 PetscInt global_columns;
297 CHKERR MatGetLocalSize(
K.get(), &local_rows, &local_columns);
298 CHKERR MatGetSize(
K.get(), &global_rows, &global_columns);
299 if (local_rows != local_columns || global_rows != global_columns) {
301 <<
"System matrix K must be square, local size (" << local_rows <<
", "
302 << local_columns <<
"), global size (" << global_rows <<
", "
303 << global_columns <<
")";
305 "System matrix K must have matching row and column layouts");
310 <<
"System matrix K layout (" << local_rows <<
", " << global_rows
311 <<
") does not match the full vector layout (" <<
fullLocalSize <<
", "
314 "System matrix K is incompatible with the full vector layout");
381 "constraint scatter");
384 const auto &events = getProjectionEvents();
385 CHKERR PetscLogEventBegin(events.projectionInit, 0, 0, 0, 0);
386 LogEventScope event_scope(events.projectionInit,
comm);
389 CHKERR MatTranspose(
C, MAT_INITIAL_MATRIX, &raw_ct);
394 CHKERR MatCreateVecs(
C, &raw_x, &raw_cx);
399 CHKERR VecDuplicate(new_cx, &raw_cctm1_cx);
403 CHKERR VecDuplicate(new_x, &raw_ct_cctm1_cx);
412 if (x_m_field_ptr != y_m_field_ptr) {
414 <<
"The full problem DM and constraint DM belong to different MoFEM "
417 "DMs must belong to the same MoFEM interface");
429 PetscInt new_full_local_size;
430 PetscInt new_full_global_size;
431 CHKERR VecGetLocalSize(x, &new_full_local_size);
432 CHKERR VecGetSize(x, &new_full_global_size);
436 PetscInt inverse_cct_rows;
437 PetscInt inverse_cct_columns;
438 CHKERR MatGetSize(
C, &c_rows, &c_columns);
441 <<
"Constraint projection initialized: C size (" << c_rows <<
", "
442 << c_columns <<
"), inverse C C^T action size (" << inverse_cct_rows
443 <<
", " << inverse_cct_columns <<
"), full vector size "
444 << new_full_global_size;
466 Mat raw_mat =
CT.get();
467 CHKERR MatTranspose(
C, MAT_REUSE_MATRIX, &raw_mat);
468 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Recalculated C^T";
480 const auto &events = getProjectionEvents();
481 CHKERR PetscLogEventBegin(events.projectionInit, 0, 0, 0, 0);
482 LogEventScope event_scope(events.projectionInit,
comm);
485 CHKERR MatTransposeMatMult(
C,
C, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &raw_ctc);
490 CHKERR MatCreateVecs(
K, &raw_qx, &raw_kqx);
495 CHKERR MatCreateVecs(new_ctc,
nullptr, &raw_ctcx);
499 PetscInt ctc_columns;
500 CHKERR MatGetSize(new_ctc, &ctc_rows, &ctc_columns);
502 <<
"Initialized C^T C + Q^T K Q work data: C^T C size (" << ctc_rows
503 <<
", " << ctc_columns <<
")";
519 Mat raw_mat =
CTC.get();
520 CHKERR MatTransposeMatMult(
C,
C, MAT_REUSE_MATRIX, PETSC_DEFAULT, &raw_mat);
521 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Recalculated C^T C";
529 PetscBool has_mult_transpose;
531 &has_mult_transpose);
532 if (!has_mult_transpose) {
534 <<
"Inverse C C^T action does not implement MatMultTranspose";
536 "Inverse C C^T action does not implement MatMultTranspose");
546 bool transpose_inverse) {
552 CHKERR VecScatterBegin(
scatter, x,
X, INSERT_VALUES, SCATTER_FORWARD);
553 CHKERR VecScatterEnd(
scatter, x,
X, INSERT_VALUES, SCATTER_FORWARD);
565 const auto &events = getProjectionEvents();
566 CHKERR PetscLogEventBegin(events.projectionQ, 0, 0, 0, 0);
567 LogEventScope event_scope(events.projectionQ,
comm);
577 const auto &events = getProjectionEvents();
578 CHKERR PetscLogEventBegin(events.projectionP, 0, 0, 0, 0);
579 LogEventScope event_scope(events.projectionP,
comm);
584 CHKERR VecScatterBegin(
scatter, x,
X, INSERT_VALUES, SCATTER_FORWARD);
585 CHKERR VecScatterEnd(
scatter, x,
X, INSERT_VALUES, SCATTER_FORWARD);
590 CHKERR VecGhostUpdateBegin(f, INSERT_VALUES, SCATTER_FORWARD);
591 CHKERR VecGhostUpdateEnd(f, INSERT_VALUES, SCATTER_FORWARD);
601 const auto &events = getProjectionEvents();
602 CHKERR PetscLogEventBegin(events.projectionR, 0, 0, 0, 0);
603 LogEventScope event_scope(events.projectionR,
comm);
607 <<
"R requires initializeQorP() or a previously created Q/P matrix";
609 "Projection context is not initialized");
611 PetscInt constraint_local_size;
612 PetscInt constraint_global_size;
613 CHKERR VecGetLocalSize(
Cx, &constraint_local_size);
614 CHKERR VecGetSize(
Cx, &constraint_global_size);
621 CHKERR VecGhostUpdateBegin(f, INSERT_VALUES, SCATTER_FORWARD);
622 CHKERR VecGhostUpdateEnd(f, INSERT_VALUES, SCATTER_FORWARD);
632 const auto &events = getProjectionEvents();
633 CHKERR PetscLogEventBegin(events.projectionRT, 0, 0, 0, 0);
634 LogEventScope event_scope(events.projectionRT,
comm);
638 <<
"R^T requires initializeQorP() or a previously created Q/P matrix";
640 "Projection context is not initialized");
642 PetscInt constraint_local_size;
643 PetscInt constraint_global_size;
644 CHKERR VecGetLocalSize(
Cx, &constraint_local_size);
645 CHKERR VecGetSize(
Cx, &constraint_global_size);
649 CHKERR VecScatterBegin(
scatter, x,
X, INSERT_VALUES, SCATTER_FORWARD);
650 CHKERR VecScatterEnd(
scatter, x,
X, INSERT_VALUES, SCATTER_FORWARD);
660 const auto &events = getProjectionEvents();
661 CHKERR PetscLogEventBegin(events.projectionCTCPlusQTKQ, 0, 0, 0, 0);
662 LogEventScope event_scope(events.projectionCTCPlusQTKQ,
comm);
668 "C^T C + Q^T K Q input");
670 "C^T C + Q^T K Q output");
674 CHKERR VecScatterBegin(
scatter, x,
X, INSERT_VALUES, SCATTER_FORWARD);
675 CHKERR VecScatterEnd(
scatter, x,
X, INSERT_VALUES, SCATTER_FORWARD);
692 PetscObjectState current_matrix_state;
693 PetscObjectState current_nonzero_state;
695 CHKERR MatGetNonzeroState(
C, ¤t_nonzero_state);
697 PetscBool local_values_changed =
700 PetscBool local_structure_changed =
703 PetscBool values_changed;
704 PetscBool structure_changed;
705 CHKERR MPIU_Allreduce(&local_values_changed, &values_changed, 1, MPIU_BOOL,
707 CHKERR MPIU_Allreduce(&local_structure_changed, &structure_changed, 1,
708 MPIU_BOOL, MPI_LOR,
comm);
714 if (structure_changed) {
716 CHKERR MatTranspose(
C, MAT_INITIAL_MATRIX, &raw_ct);
720 CHKERR MatTransposeMatMult(updated_ct, updated_ct, MAT_INITIAL_MATRIX,
721 PETSC_DEFAULT, &raw_cct);
724 Mat raw_mat = updated_ct.get();
725 CHKERR MatTranspose(
C, MAT_REUSE_MATRIX, &raw_mat);
726 raw_mat = updated_cct.get();
727 CHKERR MatTransposeMatMult(updated_ct, updated_ct, MAT_REUSE_MATRIX,
728 PETSC_DEFAULT, &raw_mat);
731 SmartPetscObj<KSP> updated_ksp =
ksp;
732 const bool create_solver = !updated_ksp;
735 CHKERR KSPSetOperators(updated_ksp, updated_cct, updated_cct);
736 CHKERR KSPSetReusePreconditioner(updated_ksp, PETSC_FALSE);
739 CHKERR KSPSetFromOptions(updated_ksp);
741 CHKERR KSPSetUp(updated_ksp);
755 <<
"Updated KSP-backed inverse C C^T action, operator size (" <<
rows
756 <<
", " << columns <<
")";
760MoFEMErrorCode CCTInverseKSPCtx::apply(Mat inverse_mat, Vec x, Vec f,
763 PetscInt constraint_size;
764 CHKERR VecGetSize(x, &constraint_size);
765 if (!constraint_size) {
770 CHKERR update(inverse_mat);
771 CHKERR KSPSetInitialGuessNonzero(
ksp, PETSC_FALSE);
772 CHKERR KSPSetInitialGuessKnoll(
ksp, PETSC_FALSE);
778 KSPConvergedReason reason;
780 PetscReal residual_norm;
781 CHKERR KSPGetConvergedReason(
ksp, &reason);
782 CHKERR KSPGetIterationNumber(
ksp, &iterations);
783 CHKERR KSPGetResidualNorm(
ksp, &residual_norm);
785 <<
"KSP-backed inverse C C^T action: reason "
786 << KSPConvergedReasons[reason] <<
", iterations " << iterations
787 <<
", residual " << residual_norm;
789 MOFEM_LOG(
"SELF", Sev::error) <<
"KSP-backed inverse C C^T action failed: "
790 << KSPConvergedReasons[reason];
792 "KSP-backed inverse C C^T action did not converge");
797MoFEMErrorCode getCCTInverseKSPContext(Mat mat, CCTInverseKSPCtx **ctx_ptr) {
799 void *void_ctx =
nullptr;
800 CHKERR MatShellGetContext(mat, &void_ctx);
801 auto *inverse_ctx_ptr =
static_cast<CCTInverseKSPCtx *
>(void_ctx);
802 if (!inverse_ctx_ptr)
804 "KSP-backed inverse C C^T shell has no context");
805 *ctx_ptr = inverse_ctx_ptr;
811 CCTInverseKSPCtx *ctx_ptr;
812 CHKERR getCCTInverseKSPContext(mat, &ctx_ptr);
813 CHKERR ctx_ptr->apply(mat, x, f,
false);
819 CCTInverseKSPCtx *ctx_ptr;
820 CHKERR getCCTInverseKSPContext(mat, &ctx_ptr);
821 CHKERR ctx_ptr->apply(mat, x, f,
true);
825MoFEMErrorCode getProjectionContext(Mat mat, ConstrainMatrixCtx **ctx_ptr) {
827 void *void_ctx =
nullptr;
828 CHKERR MatShellGetContext(mat, &void_ctx);
829 auto *owner_ptr =
static_cast<ContextOwner *
>(void_ctx);
830 if (!owner_ptr || !*owner_ptr)
832 "Projection shell matrix has no context");
833 *ctx_ptr = owner_ptr->get();
839 ConstrainMatrixCtx *ctx_ptr;
840 CHKERR getProjectionContext(mat, &ctx_ptr);
841 CHKERR ctx_ptr->applyQ(x, f);
847 ConstrainMatrixCtx *ctx_ptr;
848 CHKERR getProjectionContext(mat, &ctx_ptr);
849 CHKERR ctx_ptr->applyP(x, f);
855 ConstrainMatrixCtx *ctx_ptr;
856 CHKERR getProjectionContext(mat, &ctx_ptr);
857 CHKERR ctx_ptr->applyR(x, f);
863 ConstrainMatrixCtx *ctx_ptr;
864 CHKERR getProjectionContext(mat, &ctx_ptr);
865 CHKERR ctx_ptr->applyRT(x, f);
869MoFEMErrorCode projectionMatrixMultCTCPlusQTKQ(Mat mat, Vec x, Vec f) {
871 ConstrainMatrixCtx *ctx_ptr;
872 CHKERR getProjectionContext(mat, &ctx_ptr);
873 CHKERR ctx_ptr->applyCTC_QTKQ(x, f);
878createProjectionShellMatrix(
const boost::shared_ptr<ConstrainMatrixCtx> &ctx,
879 Vec x, ProjectionOperator projection_operator,
880 SmartPetscObj<Mat> &shell_matrix) {
884 "Cannot create a projection matrix from a null context");
887 "Cannot create a projection matrix from a null vector");
889 CHKERR ctx->initializeQorP(x);
890 if (projection_operator == ProjectionOperator::CTCPlusQTKQ)
891 CHKERR ctx->initializeQTKQ();
893 PetscInt full_local_size;
894 PetscInt full_global_size;
895 CHKERR VecGetLocalSize(x, &full_local_size);
896 CHKERR VecGetSize(x, &full_global_size);
898 Mat
C = ctx->getConstrainMatrix();
899 PetscInt constraint_local_rows;
900 PetscInt constraint_local_columns;
901 PetscInt constraint_global_rows;
902 PetscInt constraint_global_columns;
903 CHKERR MatGetLocalSize(
C, &constraint_local_rows, &constraint_local_columns);
904 CHKERR MatGetSize(
C, &constraint_global_rows, &constraint_global_columns);
906 PetscInt local_rows = full_local_size;
907 PetscInt local_columns = full_local_size;
908 PetscInt global_rows = full_global_size;
909 PetscInt global_columns = full_global_size;
910 void (*multiply_operation)(void) =
nullptr;
911 const char *matrix_name =
nullptr;
913 switch (projection_operator) {
914 case ProjectionOperator::Q:
916 reinterpret_cast<void (*)(
void)
>(projectionMatrixMultQ);
917 matrix_name =
"ProjectionQ";
919 case ProjectionOperator::P:
921 reinterpret_cast<void (*)(
void)
>(projectionMatrixMultP);
922 matrix_name =
"ProjectionP";
924 case ProjectionOperator::R:
925 local_columns = constraint_local_rows;
926 global_columns = constraint_global_rows;
928 reinterpret_cast<void (*)(
void)
>(projectionMatrixMultR);
929 matrix_name =
"ProjectionR";
931 case ProjectionOperator::RT:
932 local_rows = constraint_local_rows;
933 global_rows = constraint_global_rows;
935 reinterpret_cast<void (*)(
void)
>(projectionMatrixMultRT);
936 matrix_name =
"ProjectionRT";
938 case ProjectionOperator::CTCPlusQTKQ:
940 reinterpret_cast<void (*)(
void)
>(projectionMatrixMultCTCPlusQTKQ);
941 matrix_name =
"ProjectionCTCPlusQTKQ";
945 auto context_owner = std::make_unique<ContextOwner>(ctx);
946 Mat raw_shell_matrix;
948 CHKERR MatCreateShell(matrix_comm, local_rows, local_columns, global_rows,
949 global_columns, context_owner.get(), &raw_shell_matrix);
950 shell_matrix = SmartPetscObj<Mat>(raw_shell_matrix);
951 CHKERR MatShellSetContextDestroy(shell_matrix,
952 destroyProjectionMatrixContext);
953 context_owner.release();
954 CHKERR MatShellSetOperation(shell_matrix, MATOP_MULT, multiply_operation);
958 <<
"Created " << matrix_name <<
" shell matrix, global size ("
959 << global_rows <<
", " << global_columns <<
")";
963void validateFactoryCommunicators(MPI_Comm context_comm, PetscObject
object,
964 const char *object_name) {
968 "Failed to compare PETSc communicators");
969 if (relation > MPI_CONGRUENT)
971 " uses a communicator incompatible with the context");
976boost::shared_ptr<ConstrainMatrixCtx>
979 if (!x_dm || !y_dm || !constrain_matrix || !inverse_cct)
981 "Both DMs, C, and its inverse C C^T action are required to create a "
982 "constraint-matrix context");
987 "constraint matrix C");
989 "inverse C C^T action");
994 "Failed to get the MoFEM interface from the full DM");
996 "Failed to get the MoFEM interface from the constraint DM");
997 if (x_m_field_ptr != y_m_field_ptr)
998 THROW_MESSAGE(
"DMs must belong to the same MoFEM interface");
1000 auto ctx = boost::make_shared<ConstrainMatrixCtxImpl>(
comm, x_dm, y_dm);
1002 "Set C and its inverse C C^T action");
1006boost::shared_ptr<ConstrainMatrixCtx>
1009 if (!scatter || !constrain_matrix || !inverse_cct)
1010 THROW_MESSAGE(
"A scatter, C, and its inverse C C^T action are required to "
1011 "create a constraint-matrix context");
1014 "constraint matrix C");
1016 "inverse C C^T action");
1017 auto ctx = boost::make_shared<ConstrainMatrixCtxImpl>(
comm, scatter);
1019 "Set C and its inverse C C^T action");
1024 const std::string &options_prefix) {
1025 if (!constrain_matrix)
1027 "Constraint matrix C is required to create its inverse action");
1028 if (!external_ksp && !options_prefix.empty() && options_prefix.front() ==
'-')
1029 THROW_MESSAGE(
"A PETSc options prefix must not start with '-'");
1034 "inverse C C^T KSP");
1036 PetscInt local_rows;
1037 PetscInt local_columns;
1038 PetscInt global_rows;
1039 PetscInt global_columns;
1041 MatGetLocalSize(constrain_matrix, &local_rows, &local_columns),
1042 "Get local size of C");
1044 "Get global size of C");
1046 auto inverse_ctx = std::make_unique<CCTInverseKSPCtx>(
1047 comm, constrain_matrix, external_ksp, options_prefix);
1050 global_rows, inverse_ctx.get(),
1052 "Create KSP-backed inverse C C^T shell");
1055 inverseCCTConstraintMatrixKey,
1057 "Associate KSP-backed inverse C C^T shell with C");
1059 MatShellSetContextDestroy(
inverse, destroyCCTInverseKSPContext),
1060 "Set KSP-backed inverse C C^T context destroy operation");
1061 inverse_ctx.release();
1063 MatShellSetOperation(
inverse, MATOP_MULT,
1064 reinterpret_cast<void (*)(
void)
>(cctInverseKSPMult)),
1065 "Set KSP-backed inverse C C^T multiply operation");
1067 MatShellSetOperation(
1068 inverse, MATOP_MULT_TRANSPOSE,
1069 reinterpret_cast<void (*)(
void)
>(cctInverseKSPMultTranspose)),
1070 "Set KSP-backed inverse C C^T transpose-multiply operation");
1073 "Name KSP-backed inverse C C^T shell");
1076 <<
"Created KSP-backed inverse C C^T shell, global size (" << global_rows
1077 <<
", " << global_rows <<
")";
1086 createProjectionShellMatrix(ctx, x, ProjectionOperator::Q, matrix),
1087 "Failed to create Q projection matrix");
1096 createProjectionShellMatrix(ctx, x, ProjectionOperator::P, matrix),
1097 "Failed to create P projection matrix");
1106 createProjectionShellMatrix(ctx, x, ProjectionOperator::R, matrix),
1107 "Failed to create R projection matrix");
1116 createProjectionShellMatrix(ctx, x, ProjectionOperator::RT, matrix),
1117 "Failed to create R^T projection matrix");
1122 const boost::shared_ptr<ConstrainMatrixCtx> &ctx, Vec x) {
1125 ctx, x, ProjectionOperator::CTCPlusQTKQ, matrix),
1126 "Failed to create C^T C + Q^T K Q projection matrix");
PetscLogEvent projectionRT
PetscLogEvent projectionQ
std::string optionsPrefix
PetscLogEvent projectionInit
PetscObjectState nonzeroState
PetscLogEvent projectionP
PetscLogEvent projectionR
PetscLogEvent projectionCTCPlusQTKQ
bool configureFromOptions
PetscObjectState matrixState
SmartPetscObj< Mat > inverse
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_OPERATION_UNSUCCESSFUL
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define THROW_MESSAGE(msg)
Throw MoFEM exception.
PetscErrorCode DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
PetscErrorCode DMoFEMGetInterfacePtr(DM dm, MoFEM::Interface **m_field_ptr)
Get pointer to MoFEM::Interface.
#define MOFEM_LOG(channel, severity)
Log.
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
MPI_Comm getCommFromPetscObject(PetscObject obj)
Get the Comm From Petsc Object object.
auto createKSP(MPI_Comm comm)
SmartPetscObj< Mat > createCCTInverseKSP(Mat constrain_matrix, KSP ksp=nullptr, const std::string &options_prefix="constraint_matrix_")
SmartPetscObj< Mat > createProjectionMatrixP(const boost::shared_ptr< ConstrainMatrixCtx > &ctx, Vec x)
boost::shared_ptr< ConstrainMatrixCtx > createConstrainMatrixCtx(DM x_dm, DM y_dm, Mat constrain_matrix, Mat inverse_cct)
SmartPetscObj< Mat > createProjectionMatrixR(const boost::shared_ptr< ConstrainMatrixCtx > &ctx, Vec x)
SmartPetscObj< Mat > createProjectionMatrixCTCPlusQTKQ(const boost::shared_ptr< ConstrainMatrixCtx > &ctx, Vec x)
SmartPetscObj< Mat > createProjectionMatrixQ(const boost::shared_ptr< ConstrainMatrixCtx > &ctx, Vec x)
PetscObject getPetscObject(T obj)
SmartPetscObj< Mat > createProjectionMatrixRT(const boost::shared_ptr< ConstrainMatrixCtx > &ctx, Vec x)
MoFEMErrorCode validateInverseCCTLayout(Mat constrain_matrix, Mat inverse_cct) const
Mat getInverseCCT() const override
SmartPetscObj< Vec > CCTm1Cx
MoFEMErrorCode applyQImpl(Vec x, Vec f, bool transpose_inverse)
MoFEMErrorCode initializeQTKQ() override
ConstrainMatrixCtxImpl(MPI_Comm comm, DM x_dm, DM y_dm)
MoFEMErrorCode invalidateSystemData()
Mat getConstrainMatrix() const override
MoFEMErrorCode invalidateProjectionData()
MoFEMErrorCode applyR(Vec x, Vec f) override
MoFEMErrorCode applyCTC_QTKQ(Vec x, Vec f) override
MoFEMErrorCode validateVectorLayout(Vec vec, PetscInt local_size, PetscInt global_size, const char *vector_name) const
Mat getSystemMatrix() const override
MoFEMErrorCode validateSystemMatrixLayout() const
MoFEMErrorCode setSystemMatrix(Mat system_matrix) override
MoFEMErrorCode applyRT(Vec x, Vec f) override
SmartPetscObj< Vec > CTCx
bool projectionInitialized
MoFEMErrorCode applyQ(Vec x, Vec f) override
MoFEMErrorCode applyP(Vec x, Vec f) override
SmartPetscObj< Mat > inverseCCT
SmartPetscObj< Vec > CTCCTm1Cx
MoFEMErrorCode applyInverseCCT(Vec x, Vec f, bool transpose)
MoFEMErrorCode setConstrainMatrix(Mat constrain_matrix, Mat inverse_cct) override
MoFEMErrorCode recalculateCT() override
MoFEMErrorCode validatePetscObject(PetscObject object, const char *object_name) const
MoFEMErrorCode initializeQorP(Vec x) override
~ConstrainMatrixCtxImpl() override=default
MoFEMErrorCode recalculateCTC() override
SmartPetscObj< VecScatter > scatter
API for matrices that project onto, or lift from, a constraint space.
Deprecated interface functions.
keeps basic data about problem
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Vector manager is used to create vectors \mofem_vectors.