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