Actual source code: qr.c
2: /*
3: Defines a direct QR factorization preconditioner for any Mat implementation
4: Note: this need not be considered a preconditioner since it supplies
5: a direct solver.
6: */
7: #include <../src/ksp/pc/impls/factor/qr/qr.h>
9: static PetscErrorCode PCSetUp_QR(PC pc)
10: {
11: PetscErrorCode ierr;
12: PC_QR *dir = (PC_QR*)pc->data;
13: MatSolverType stype;
14: MatFactorError err;
17: pc->failedreason = PC_NOERROR;
18: if (dir->hdr.reusefill && pc->setupcalled) ((PC_Factor*)dir)->info.fill = dir->hdr.actualfill;
20: MatSetErrorIfFailure(pc->pmat,pc->erroriffailure);
21: if (dir->hdr.inplace) {
22: MatFactorType ftype;
24: MatGetFactorType(pc->pmat, &ftype);
25: if (ftype == MAT_FACTOR_NONE) {
26: MatQRFactor(pc->pmat,dir->col,&((PC_Factor*)dir)->info);
27: MatFactorGetError(pc->pmat,&err);
28: if (err) { /* Factor() fails */
29: pc->failedreason = (PCFailedReason)err;
30: return(0);
31: }
32: }
33: ((PC_Factor*)dir)->fact = pc->pmat;
34: } else {
35: MatInfo info;
37: if (!pc->setupcalled) {
38: if (!((PC_Factor*)dir)->fact) {
39: MatGetFactor(pc->pmat,((PC_Factor*)dir)->solvertype,MAT_FACTOR_QR,&((PC_Factor*)dir)->fact);
40: PetscLogObjectParent((PetscObject)pc,(PetscObject)((PC_Factor*)dir)->fact);
41: }
42: MatQRFactorSymbolic(((PC_Factor*)dir)->fact,pc->pmat,dir->col,&((PC_Factor*)dir)->info);
43: MatGetInfo(((PC_Factor*)dir)->fact,MAT_LOCAL,&info);
44: dir->hdr.actualfill = info.fill_ratio_needed;
45: } else if (pc->flag != SAME_NONZERO_PATTERN) {
46: MatQRFactorSymbolic(((PC_Factor*)dir)->fact,pc->pmat,dir->col,&((PC_Factor*)dir)->info);
47: MatGetInfo(((PC_Factor*)dir)->fact,MAT_LOCAL,&info);
48: dir->hdr.actualfill = info.fill_ratio_needed;
49: } else {
50: MatFactorGetError(((PC_Factor*)dir)->fact,&err);
51: }
52: MatFactorGetError(((PC_Factor*)dir)->fact,&err);
53: if (err) { /* FactorSymbolic() fails */
54: pc->failedreason = (PCFailedReason)err;
55: return(0);
56: }
58: MatQRFactorNumeric(((PC_Factor*)dir)->fact,pc->pmat,&((PC_Factor*)dir)->info);
59: MatFactorGetError(((PC_Factor*)dir)->fact,&err);
60: if (err) { /* FactorNumeric() fails */
61: pc->failedreason = (PCFailedReason)err;
62: }
63: }
65: PCFactorGetMatSolverType(pc,&stype);
66: if (!stype) {
67: MatSolverType solverpackage;
68: MatFactorGetSolverType(((PC_Factor*)dir)->fact,&solverpackage);
69: PCFactorSetMatSolverType(pc,solverpackage);
70: }
71: return(0);
72: }
74: static PetscErrorCode PCReset_QR(PC pc)
75: {
76: PC_QR *dir = (PC_QR*)pc->data;
80: if (!dir->hdr.inplace && ((PC_Factor*)dir)->fact) {MatDestroy(&((PC_Factor*)dir)->fact);}
81: ISDestroy(&dir->col);
82: return(0);
83: }
85: static PetscErrorCode PCDestroy_QR(PC pc)
86: {
87: PC_QR *dir = (PC_QR*)pc->data;
91: PCReset_QR(pc);
92: PetscFree(((PC_Factor*)dir)->ordering);
93: PetscFree(((PC_Factor*)dir)->solvertype);
94: PetscFree(pc->data);
95: return(0);
96: }
98: static PetscErrorCode PCApply_QR(PC pc,Vec x,Vec y)
99: {
100: PC_QR *dir = (PC_QR*)pc->data;
101: Mat fact;
105: fact = dir->hdr.inplace ? pc->pmat : ((PC_Factor*)dir)->fact;
106: MatSolve(fact,x,y);
107: return(0);
108: }
110: static PetscErrorCode PCMatApply_QR(PC pc,Mat X,Mat Y)
111: {
112: PC_QR *dir = (PC_QR*)pc->data;
113: Mat fact;
117: fact = dir->hdr.inplace ? pc->pmat : ((PC_Factor*)dir)->fact;
118: MatMatSolve(fact,X,Y);
119: return(0);
120: }
122: static PetscErrorCode PCApplyTranspose_QR(PC pc,Vec x,Vec y)
123: {
124: PC_QR *dir = (PC_QR*)pc->data;
125: Mat fact;
129: fact = dir->hdr.inplace ? pc->pmat : ((PC_Factor*)dir)->fact;
130: MatSolveTranspose(fact,x,y);
131: return(0);
132: }
134: /* -----------------------------------------------------------------------------------*/
136: /*MC
137: PCQR - Uses a direct solver, based on QR factorization, as a preconditioner
139: Level: beginner
141: Notes:
142: Usually this will compute an "exact" solution in one iteration and does
143: not need a Krylov method (i.e. you can use -ksp_type preonly, or
144: KSPSetType(ksp,KSPPREONLY) for the Krylov method
146: .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC,
147: PCILU, PCLU, PCCHOLESKY, PCICC, PCFactorSetReuseOrdering(), PCFactorSetReuseFill(), PCFactorGetMatrix(),
148: PCFactorSetFill(), PCFactorSetUseInPlace(), PCFactorSetMatOrderingType(), PCFactorSetColumnPivot(),
149: PCFactorSetPivotingInBlocks(),PCFactorSetShiftType(),PCFactorSetShiftAmount()
150: PCFactorReorderForNonzeroDiagonal()
151: M*/
153: PETSC_EXTERN PetscErrorCode PCCreate_QR(PC pc)
154: {
156: PC_QR *dir;
159: PetscNewLog(pc,&dir);
160: pc->data = (void*)dir;
161: PCFactorInitialize(pc, MAT_FACTOR_QR);
163: dir->col = NULL;
164: pc->ops->reset = PCReset_QR;
165: pc->ops->destroy = PCDestroy_QR;
166: pc->ops->apply = PCApply_QR;
167: pc->ops->matapply = PCMatApply_QR;
168: pc->ops->applytranspose = PCApplyTranspose_QR;
169: pc->ops->setup = PCSetUp_QR;
170: pc->ops->setfromoptions = PCSetFromOptions_Factor;
171: pc->ops->view = PCView_Factor;
172: pc->ops->applyrichardson = NULL;
173: return(0);
174: }