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