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: }