Actual source code: tfs.c

  1: /* 
  2:         Provides an interface to the Tufo-Fischer parallel direct solver
  3: */

 5:  #include src/ksp/pc/pcimpl.h
 6:  #include src/mat/impls/aij/mpi/mpiaij.h

 8:  #include src/ksp/pc/impls/tfs/xxt.h
 9:  #include src/ksp/pc/impls/tfs/xyt.h

 11: typedef struct {
 12:   xxt_ADT  xxt;
 13:   xyt_ADT  xyt;
 14:   Vec      b,xd,xo;
 15:   PetscInt nd;
 16: } PC_TFS;

 20: PetscErrorCode PCDestroy_TFS(PC pc)
 21: {
 22:   PC_TFS *tfs = (PC_TFS*)pc->data;

 26:   /* free the XXT datastructures */
 27:   if (tfs->xxt) {
 28:     XXT_free(tfs->xxt);
 29:   }
 30:   if (tfs->xyt) {
 31:     XYT_free(tfs->xyt);
 32:   }
 33:   if (tfs->b) {
 34:   VecDestroy(tfs->b);
 35:   }
 36:   if (tfs->xd) {
 37:   VecDestroy(tfs->xd);
 38:   }
 39:   if (tfs->xo) {
 40:   VecDestroy(tfs->xo);
 41:   }
 42:   PetscFree(tfs);
 43:   return(0);
 44: }

 48: static PetscErrorCode PCApply_TFS_XXT(PC pc,Vec x,Vec y)
 49: {
 50:   PC_TFS *tfs = (PC_TFS*)pc->data;
 51:   PetscScalar    *xx,*yy;

 55:   VecGetArray(x,&xx);
 56:   VecGetArray(y,&yy);
 57:   XXT_solve(tfs->xxt,yy,xx);
 58:   VecRestoreArray(x,&xx);
 59:   VecRestoreArray(y,&yy);
 60:   return(0);
 61: }

 65: static PetscErrorCode PCApply_TFS_XYT(PC pc,Vec x,Vec y)
 66: {
 67:   PC_TFS *tfs = (PC_TFS*)pc->data;
 68:   PetscScalar    *xx,*yy;

 72:   VecGetArray(x,&xx);
 73:   VecGetArray(y,&yy);
 74:   XYT_solve(tfs->xyt,yy,xx);
 75:   VecRestoreArray(x,&xx);
 76:   VecRestoreArray(y,&yy);
 77:   return(0);
 78: }

 82: static PetscErrorCode LocalMult_TFS(PC pc,PetscScalar *xin,PetscScalar *xout)
 83: {
 84:   PC_TFS        *tfs = (PC_TFS*)pc->data;
 85:   Mat           A = pc->pmat;
 86:   Mat_MPIAIJ    *a = (Mat_MPIAIJ*)A->data;
 88: 
 90:   VecPlaceArray(tfs->b,xout);
 91:   VecPlaceArray(tfs->xd,xin);
 92:   VecPlaceArray(tfs->xo,xin+tfs->nd);
 93:   MatMult(a->A,tfs->xd,tfs->b);
 94:   MatMultAdd(a->B,tfs->xo,tfs->b,tfs->b);
 95:   return(0);
 96: }

100: static PetscErrorCode PCSetUp_TFS(PC pc)
101: {
102:   PC_TFS        *tfs = (PC_TFS*)pc->data;
103:   Mat            A = pc->pmat;
104:   Mat_MPIAIJ     *a = (Mat_MPIAIJ*)A->data;
106:   PetscInt      *localtoglobal,ncol,i;
107:   PetscTruth     ismpiaij;

109:   /*
110:   PetscTruth     issymmetric;
111:   PetscReal tol = 0.0;
112:   */

115:   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
116:   PetscTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij);
117:   if (!ismpiaij) {
118:     SETERRQ(PETSC_ERR_SUP,"Currently only supports MPIAIJ matrices");
119:   }

121:   /* generate the local to global mapping */
122:   ncol = a->A->n + a->B->n;
123:   PetscMalloc((ncol)*sizeof(int),&localtoglobal);
124:   for (i=0; i<a->A->n; i++) {
125:     localtoglobal[i] = a->cstart + i + 1;
126:   }
127:   for (i=0; i<a->B->n; i++) {
128:     localtoglobal[i+a->A->n] = a->garray[i] + 1;
129:   }
130:   /* generate the vectors needed for the local solves */
131:   VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->m,PETSC_NULL,&tfs->b);
132:   VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->n,PETSC_NULL,&tfs->xd);
133:   VecCreateSeqWithArray(PETSC_COMM_SELF,a->B->n,PETSC_NULL,&tfs->xo);
134:   tfs->nd = a->A->n;


137:   /*   MatIsSymmetric(A,tol,&issymmetric); */
138:   /*  if (issymmetric) { */
139:   PetscBarrier((PetscObject)pc);
140:   if (A->symmetric) {
141:     tfs->xxt       = XXT_new();
142:     XXT_factor(tfs->xxt,localtoglobal,A->m,ncol,(void*)LocalMult_TFS,pc);
143:     pc->ops->apply = PCApply_TFS_XXT;
144:   } else {
145:     tfs->xyt       = XYT_new();
146:     XYT_factor(tfs->xyt,localtoglobal,A->m,ncol,(void*)LocalMult_TFS,pc);
147:     pc->ops->apply = PCApply_TFS_XYT;
148:   }

150:   PetscFree(localtoglobal);
151:   return(0);
152: }

156: static PetscErrorCode PCSetFromOptions_TFS(PC pc)
157: {
159:   return(0);
160: }
163: static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer)
164: {
166:   return(0);
167: }

172: PetscErrorCode PCCreate_TFS(PC pc)
173: {
175:   PC_TFS         *tfs;

178:   PetscNew(PC_TFS,&tfs);
179:   PetscLogObjectMemory(pc,sizeof(PC_TFS));

181:   tfs->xxt = 0;
182:   tfs->xyt = 0;
183:   tfs->b   = 0;
184:   tfs->xd  = 0;
185:   tfs->xo  = 0;
186:   tfs->nd  = 0;

188:   pc->ops->apply               = 0;
189:   pc->ops->applytranspose      = 0;
190:   pc->ops->setup               = PCSetUp_TFS;
191:   pc->ops->destroy             = PCDestroy_TFS;
192:   pc->ops->setfromoptions      = PCSetFromOptions_TFS;
193:   pc->ops->view                = PCView_TFS;
194:   pc->ops->applyrichardson     = 0;
195:   pc->ops->applysymmetricleft  = 0;
196:   pc->ops->applysymmetricright = 0;
197:   pc->data                     = (void*)tfs;
198:   return(0);
199: }