xref: /petsc/src/ksp/pc/impls/tfs/tfs.c (revision 6218e5750b7cdb8fc46d97822198c34b3166d531)
1*6218e575SSatish Balay /*
2*6218e575SSatish Balay         Provides an interface to the Tufo-Fischer parallel direct solver
3*6218e575SSatish Balay */
4*6218e575SSatish Balay 
5*6218e575SSatish Balay #include "src/ksp/pc/pcimpl.h"   /*I "petscpc.h" I*/
6*6218e575SSatish Balay #include "src/mat/impls/aij/mpi/mpiaij.h"
7*6218e575SSatish Balay 
8*6218e575SSatish Balay #include "src/ksp/pc/impls/tfs/xxt.h"
9*6218e575SSatish Balay #include "src/ksp/pc/impls/tfs/xyt.h"
10*6218e575SSatish Balay 
11*6218e575SSatish Balay typedef struct {
12*6218e575SSatish Balay   xxt_ADT  xxt;
13*6218e575SSatish Balay   xyt_ADT  xyt;
14*6218e575SSatish Balay   Vec      b,xd,xo;
15*6218e575SSatish Balay   PetscInt nd;
16*6218e575SSatish Balay } PC_TFS;
17*6218e575SSatish Balay 
18*6218e575SSatish Balay #undef __FUNCT__
19*6218e575SSatish Balay #define __FUNCT__ "PCDestroy_TFS"
20*6218e575SSatish Balay PetscErrorCode PCDestroy_TFS(PC pc)
21*6218e575SSatish Balay {
22*6218e575SSatish Balay   PC_TFS *tfs = (PC_TFS*)pc->data;
23*6218e575SSatish Balay   PetscErrorCode ierr;
24*6218e575SSatish Balay 
25*6218e575SSatish Balay   PetscFunctionBegin;
26*6218e575SSatish Balay   /* free the XXT datastructures */
27*6218e575SSatish Balay   if (tfs->xxt) {
28*6218e575SSatish Balay     ierr = XXT_free(tfs->xxt);CHKERRQ(ierr);
29*6218e575SSatish Balay   }
30*6218e575SSatish Balay   if (tfs->xyt) {
31*6218e575SSatish Balay     ierr = XYT_free(tfs->xyt);CHKERRQ(ierr);
32*6218e575SSatish Balay   }
33*6218e575SSatish Balay   if (tfs->b) {
34*6218e575SSatish Balay   ierr = VecDestroy(tfs->b);CHKERRQ(ierr);
35*6218e575SSatish Balay   }
36*6218e575SSatish Balay   if (tfs->xd) {
37*6218e575SSatish Balay   ierr = VecDestroy(tfs->xd);CHKERRQ(ierr);
38*6218e575SSatish Balay   }
39*6218e575SSatish Balay   if (tfs->xo) {
40*6218e575SSatish Balay   ierr = VecDestroy(tfs->xo);CHKERRQ(ierr);
41*6218e575SSatish Balay   }
42*6218e575SSatish Balay   ierr = PetscFree(tfs);CHKERRQ(ierr);
43*6218e575SSatish Balay   PetscFunctionReturn(0);
44*6218e575SSatish Balay }
45*6218e575SSatish Balay 
46*6218e575SSatish Balay #undef __FUNCT__
47*6218e575SSatish Balay #define __FUNCT__ "PCApply_TFS_XXT"
48*6218e575SSatish Balay static PetscErrorCode PCApply_TFS_XXT(PC pc,Vec x,Vec y)
49*6218e575SSatish Balay {
50*6218e575SSatish Balay   PC_TFS *tfs = (PC_TFS*)pc->data;
51*6218e575SSatish Balay   PetscScalar    *xx,*yy;
52*6218e575SSatish Balay   PetscErrorCode ierr;
53*6218e575SSatish Balay 
54*6218e575SSatish Balay   PetscFunctionBegin;
55*6218e575SSatish Balay   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
56*6218e575SSatish Balay   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
57*6218e575SSatish Balay   ierr = XXT_solve(tfs->xxt,yy,xx);CHKERRQ(ierr);
58*6218e575SSatish Balay   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
59*6218e575SSatish Balay   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
60*6218e575SSatish Balay   PetscFunctionReturn(0);
61*6218e575SSatish Balay }
62*6218e575SSatish Balay 
63*6218e575SSatish Balay #undef __FUNCT__
64*6218e575SSatish Balay #define __FUNCT__ "PCApply_TFS_XYT"
65*6218e575SSatish Balay static PetscErrorCode PCApply_TFS_XYT(PC pc,Vec x,Vec y)
66*6218e575SSatish Balay {
67*6218e575SSatish Balay   PC_TFS *tfs = (PC_TFS*)pc->data;
68*6218e575SSatish Balay   PetscScalar    *xx,*yy;
69*6218e575SSatish Balay   PetscErrorCode ierr;
70*6218e575SSatish Balay 
71*6218e575SSatish Balay   PetscFunctionBegin;
72*6218e575SSatish Balay   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
73*6218e575SSatish Balay   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
74*6218e575SSatish Balay   ierr = XYT_solve(tfs->xyt,yy,xx);CHKERRQ(ierr);
75*6218e575SSatish Balay   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
76*6218e575SSatish Balay   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
77*6218e575SSatish Balay   PetscFunctionReturn(0);
78*6218e575SSatish Balay }
79*6218e575SSatish Balay 
80*6218e575SSatish Balay #undef __FUNCT__
81*6218e575SSatish Balay #define __FUNCT__ "LocalMult_TFS"
82*6218e575SSatish Balay static PetscErrorCode LocalMult_TFS(PC pc,PetscScalar *xin,PetscScalar *xout)
83*6218e575SSatish Balay {
84*6218e575SSatish Balay   PC_TFS        *tfs = (PC_TFS*)pc->data;
85*6218e575SSatish Balay   Mat           A = pc->pmat;
86*6218e575SSatish Balay   Mat_MPIAIJ    *a = (Mat_MPIAIJ*)A->data;
87*6218e575SSatish Balay   PetscErrorCode ierr;
88*6218e575SSatish Balay 
89*6218e575SSatish Balay   PetscFunctionBegin;
90*6218e575SSatish Balay   ierr = VecPlaceArray(tfs->b,xout);CHKERRQ(ierr);
91*6218e575SSatish Balay   ierr = VecPlaceArray(tfs->xd,xin);CHKERRQ(ierr);
92*6218e575SSatish Balay   ierr = VecPlaceArray(tfs->xo,xin+tfs->nd);CHKERRQ(ierr);
93*6218e575SSatish Balay   ierr = MatMult(a->A,tfs->xd,tfs->b);CHKERRQ(ierr);
94*6218e575SSatish Balay   ierr = MatMultAdd(a->B,tfs->xo,tfs->b,tfs->b);CHKERRQ(ierr);
95*6218e575SSatish Balay   PetscFunctionReturn(0);
96*6218e575SSatish Balay }
97*6218e575SSatish Balay 
98*6218e575SSatish Balay #undef __FUNCT__
99*6218e575SSatish Balay #define __FUNCT__ "PCSetUp_TFS"
100*6218e575SSatish Balay static PetscErrorCode PCSetUp_TFS(PC pc)
101*6218e575SSatish Balay {
102*6218e575SSatish Balay   PC_TFS        *tfs = (PC_TFS*)pc->data;
103*6218e575SSatish Balay   Mat            A = pc->pmat;
104*6218e575SSatish Balay   Mat_MPIAIJ     *a = (Mat_MPIAIJ*)A->data;
105*6218e575SSatish Balay   PetscErrorCode ierr;
106*6218e575SSatish Balay   PetscInt      *localtoglobal,ncol,i;
107*6218e575SSatish Balay   PetscTruth     ismpiaij;
108*6218e575SSatish Balay 
109*6218e575SSatish Balay   /*
110*6218e575SSatish Balay   PetscTruth     issymmetric;
111*6218e575SSatish Balay   PetscReal tol = 0.0;
112*6218e575SSatish Balay   */
113*6218e575SSatish Balay 
114*6218e575SSatish Balay   PetscFunctionBegin;
115*6218e575SSatish Balay   if (A->N != A->M) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
116*6218e575SSatish Balay   ierr = PetscTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr);
117*6218e575SSatish Balay   if (!ismpiaij) {
118*6218e575SSatish Balay     SETERRQ(PETSC_ERR_SUP,"Currently only supports MPIAIJ matrices");
119*6218e575SSatish Balay   }
120*6218e575SSatish Balay 
121*6218e575SSatish Balay   /* generate the local to global mapping */
122*6218e575SSatish Balay   ncol = a->A->n + a->B->n;
123*6218e575SSatish Balay   ierr = PetscMalloc((ncol)*sizeof(int),&localtoglobal);CHKERRQ(ierr);
124*6218e575SSatish Balay   for (i=0; i<a->A->n; i++) {
125*6218e575SSatish Balay     localtoglobal[i] = a->cstart + i + 1;
126*6218e575SSatish Balay   }
127*6218e575SSatish Balay   for (i=0; i<a->B->n; i++) {
128*6218e575SSatish Balay     localtoglobal[i+a->A->n] = a->garray[i] + 1;
129*6218e575SSatish Balay   }
130*6218e575SSatish Balay   /* generate the vectors needed for the local solves */
131*6218e575SSatish Balay   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->m,PETSC_NULL,&tfs->b);CHKERRQ(ierr);
132*6218e575SSatish Balay   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->n,PETSC_NULL,&tfs->xd);CHKERRQ(ierr);
133*6218e575SSatish Balay   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->B->n,PETSC_NULL,&tfs->xo);CHKERRQ(ierr);
134*6218e575SSatish Balay   tfs->nd = a->A->n;
135*6218e575SSatish Balay 
136*6218e575SSatish Balay 
137*6218e575SSatish Balay   /*  ierr =  MatIsSymmetric(A,tol,&issymmetric); */
138*6218e575SSatish Balay   /*  if (issymmetric) { */
139*6218e575SSatish Balay   PetscBarrier(pc);
140*6218e575SSatish Balay   if (A->symmetric) {
141*6218e575SSatish Balay     tfs->xxt       = XXT_new();
142*6218e575SSatish Balay     ierr           = XXT_factor(tfs->xxt,localtoglobal,A->m,ncol,(void*)LocalMult_TFS,pc);CHKERRQ(ierr);
143*6218e575SSatish Balay     pc->ops->apply = PCApply_TFS_XXT;
144*6218e575SSatish Balay   } else {
145*6218e575SSatish Balay     tfs->xyt       = XYT_new();
146*6218e575SSatish Balay     ierr           = XYT_factor(tfs->xyt,localtoglobal,A->m,ncol,(void*)LocalMult_TFS,pc);CHKERRQ(ierr);
147*6218e575SSatish Balay     pc->ops->apply = PCApply_TFS_XYT;
148*6218e575SSatish Balay   }
149*6218e575SSatish Balay 
150*6218e575SSatish Balay   ierr = PetscFree(localtoglobal);CHKERRQ(ierr);
151*6218e575SSatish Balay   PetscFunctionReturn(0);
152*6218e575SSatish Balay }
153*6218e575SSatish Balay 
154*6218e575SSatish Balay #undef __FUNCT__
155*6218e575SSatish Balay #define __FUNCT__ "PCSetFromOptions_TFS"
156*6218e575SSatish Balay static PetscErrorCode PCSetFromOptions_TFS(PC pc)
157*6218e575SSatish Balay {
158*6218e575SSatish Balay   PetscFunctionBegin;
159*6218e575SSatish Balay   PetscFunctionReturn(0);
160*6218e575SSatish Balay }
161*6218e575SSatish Balay #undef __FUNCT__
162*6218e575SSatish Balay #define __FUNCT__ "PCView_TFS"
163*6218e575SSatish Balay static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer)
164*6218e575SSatish Balay {
165*6218e575SSatish Balay   PetscFunctionBegin;
166*6218e575SSatish Balay   PetscFunctionReturn(0);
167*6218e575SSatish Balay }
168*6218e575SSatish Balay 
169*6218e575SSatish Balay EXTERN_C_BEGIN
170*6218e575SSatish Balay #undef __FUNCT__
171*6218e575SSatish Balay #define __FUNCT__ "PCCreate_TFS"
172*6218e575SSatish Balay PetscErrorCode PCCreate_TFS(PC pc)
173*6218e575SSatish Balay {
174*6218e575SSatish Balay   PetscErrorCode ierr;
175*6218e575SSatish Balay   PC_TFS         *tfs;
176*6218e575SSatish Balay 
177*6218e575SSatish Balay   PetscFunctionBegin;
178*6218e575SSatish Balay   ierr = PetscNew(PC_TFS,&tfs);CHKERRQ(ierr);
179*6218e575SSatish Balay   PetscLogObjectMemory(pc,sizeof(PC_TFS));
180*6218e575SSatish Balay 
181*6218e575SSatish Balay   tfs->xxt = 0;
182*6218e575SSatish Balay   tfs->xyt = 0;
183*6218e575SSatish Balay   tfs->b   = 0;
184*6218e575SSatish Balay   tfs->xd  = 0;
185*6218e575SSatish Balay   tfs->xo  = 0;
186*6218e575SSatish Balay   tfs->nd  = 0;
187*6218e575SSatish Balay 
188*6218e575SSatish Balay   pc->ops->apply               = 0;
189*6218e575SSatish Balay   pc->ops->applytranspose      = 0;
190*6218e575SSatish Balay   pc->ops->setup               = PCSetUp_TFS;
191*6218e575SSatish Balay   pc->ops->destroy             = PCDestroy_TFS;
192*6218e575SSatish Balay   pc->ops->setfromoptions      = PCSetFromOptions_TFS;
193*6218e575SSatish Balay   pc->ops->view                = PCView_TFS;
194*6218e575SSatish Balay   pc->ops->applyrichardson     = 0;
195*6218e575SSatish Balay   pc->ops->applysymmetricleft  = 0;
196*6218e575SSatish Balay   pc->ops->applysymmetricright = 0;
197*6218e575SSatish Balay   pc->data                     = (void*)tfs;
198*6218e575SSatish Balay   PetscFunctionReturn(0);
199*6218e575SSatish Balay }
200*6218e575SSatish Balay EXTERN_C_END
201*6218e575SSatish Balay 
202