Actual source code: jacobic.c
1: #ifdef PETSC_RCS_HEADER
2: static char vcid[] = "$Id: jacobic.c,v 1.1 1999/05/20 21:56:24 knepley Exp $";
3: #endif
4: /*
5: Defines a Jacobi preconditioner for any constrained Mat implementation
6: */
7: #include src/sles/pc/pcimpl.h
8: #include gvec.h
10: /* We are cheating here since the interface is deficient */
11: typedef struct {
12: Vec diag;
13: Vec diagsqrt;
14: PetscTruth userowmax;
15: } PC_Jacobi;
17: typedef struct {
18: PC jacobi;
19: } PC_Jacobi_Constrained;
21: static int PCSetUp_Jacobi_Constrained(PC pc) {
22: PC_Jacobi_Constrained *jacConst = (PC_Jacobi_Constrained *) pc->data;
23: PC_Jacobi *jac = (PC_Jacobi *) jacConst->jacobi->data;
24: PetscTruth zeroDetected = PETSC_FALSE;
25: Grid grid;
26: Vec diag, diagsqrt;
27: PetscScalar *x;
28: int i, n;
29: int ierr;
32: PCSetVector(jacConst->jacobi, pc->vec);
33: PCSetOperators(jacConst->jacobi, pc->mat, pc->pmat, pc->flag);
34: GMatGetGrid(pc->pmat, &grid);
35: if (grid == PETSC_NULL) SETERRQ(PETSC_ERR_SUP, "Constrained Jacobi is only for Grid matrices");
37: jacConst->jacobi->setupcalled = 2;
38: diag = jac->diag;
39: diagsqrt = jac->diagsqrt;
40: if (jac->userowmax) SETERRQ(PETSC_ERR_SUP, "Not currently supported for constrained matrices");
41: if (diag) {
42: GMatGetDiagonalConstrained(pc->pmat, diag);
43: VecReciprocal(diag);
44: VecGetLocalSize(diag, &n);
45: VecGetArray(diag, &x);
46: for(i = 0; i < n; i++) {
47: if (x[i] == 0.0) {
48: x[i] = 1.0;
49: zeroDetected = PETSC_TRUE;
50: }
51: }
52: VecRestoreArray(diag, &x);
53: }
54: if (diagsqrt) {
55: GMatGetDiagonalConstrained(pc->pmat, diagsqrt);
56: VecGetLocalSize(diagsqrt, &n);
57: VecGetArray(diagsqrt, &x);
58: for(i = 0; i < n; i++) {
59: if (x[i] != 0.0) {
60: x[i] = 1.0/sqrt(PetscAbsScalar(x[i]));
61: } else {
62: x[i] = 1.0;
63: zeroDetected = PETSC_TRUE;
64: }
65: }
66: VecRestoreArray(diagsqrt, &x);
67: }
69: if (zeroDetected == PETSC_TRUE) {
70: PetscLogInfo(pc, "PCSetUp_Jacobi_Constrained:WARNING: Zero detected in diagonal while building Jacobi preconditionern");
71: }
72: return(0);
73: }
75: static int PCDestroy_Jacobi_Constrained(PC pc) {
76: PC_Jacobi_Constrained *jac = (PC_Jacobi_Constrained *) pc->data;
77: int ierr;
80: PCDestroy(jac->jacobi);
81: PetscFree(jac);
82: return(0);
83: }
85: static int PCApply_Jacobi_Constrained(PC pc, Vec x, Vec y) {
86: PC_Jacobi_Constrained *jac = (PC_Jacobi_Constrained *) pc->data;
87: PC_Jacobi *j = (PC_Jacobi *) jac->jacobi->data;
88: int ierr;
90: if (j->diag == PETSC_NULL) {
91: VecDuplicate(pc->vec, &j->diag);
92: PetscLogObjectParent(pc, j->diag);
93: PCSetUp_Jacobi_Constrained(pc);
94: }
95: return PCApply(jac->jacobi, x, y);
96: }
98: static int PCSetFromOptions_Jacobi_Constrained(PC pc) {
99: PC_Jacobi_Constrained *jac = (PC_Jacobi_Constrained *) pc->data;
100: return PCSetFromOptions(jac->jacobi);
101: }
103: static int PCApplySymmetricLeftOrRight_Jacobi_Constrained(PC pc, Vec x, Vec y) {
104: PC_Jacobi_Constrained *jac = (PC_Jacobi_Constrained *) pc->data;
105: PC_Jacobi *j = (PC_Jacobi *) jac->jacobi->data;
106: int ierr;
108: if (j->diagsqrt == PETSC_NULL) {
109: VecDuplicate(pc->vec, &j->diagsqrt);
110: PetscLogObjectParent(pc, j->diagsqrt);
111: PCSetUp_Jacobi_Constrained(pc);
112: }
113: return PCApplySymmetricLeft(jac->jacobi, x, y);
114: }
116: EXTERN_C_BEGIN
117: int PCCreate_Jacobi_Constrained(PC pc) {
118: PC_Jacobi_Constrained *jac;
119: int ierr;
122: PetscNew(PC_Jacobi_Constrained, &jac);
123: PetscLogObjectMemory(pc,sizeof(PC_Jacobi_Constrained));
124: pc->data = (void*) jac;
126: PCCreate(pc->comm, &jac->jacobi);
127: PCSetOptionsPrefix(jac->jacobi, "jacobic");
128: PCSetType(jac->jacobi, PCJACOBI);
129: pc->ops->apply = PCApply_Jacobi_Constrained;
130: pc->ops->applytranspose = PCApply_Jacobi_Constrained;
131: pc->ops->setup = PCSetUp_Jacobi_Constrained;
132: pc->ops->destroy = PCDestroy_Jacobi_Constrained;
133: pc->ops->setfromoptions = PCSetFromOptions_Jacobi_Constrained;
134: pc->ops->view = PETSC_NULL;
135: pc->ops->applyrichardson = PETSC_NULL;
136: pc->ops->applysymmetricleft = PCApplySymmetricLeftOrRight_Jacobi_Constrained;
137: pc->ops->applysymmetricright = PCApplySymmetricLeftOrRight_Jacobi_Constrained;
138: return(0);
139: }
140: EXTERN_C_END