Actual source code: tfs.c

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

 6:  #include private/pcimpl.h
 7:  #include src/mat/impls/aij/mpi/mpiaij.h
 8:  #include src/ksp/pc/impls/tfs/tfs.h

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

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

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

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

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

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

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

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

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

111:   /*
112:   PetscTruth     issymmetric;
113:   Petsc Real tol = 0.0;
114:   */

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

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


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

152:   PetscFree(localtoglobal);
153:   return(0);
154: }

158: static PetscErrorCode PCSetFromOptions_TFS(PC pc)
159: {
161:   return(0);
162: }
165: static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer)
166: {
168:   return(0);
169: }

174: PetscErrorCode  PCCreate_TFS(PC pc)
175: {
177:   PC_TFS         *tfs;

180:   PetscNew(PC_TFS,&tfs);
181:   PetscLogObjectMemory(pc,sizeof(PC_TFS));

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

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