xref: /petsc/src/ksp/pc/impls/tfs/tfs.c (revision ce0a2cd1da0658c2b28aad1be2e2c8e41567bece)
1 #define PETSCKSP_DLL
2 /*
3         Provides an interface to the Tufo-Fischer parallel direct solver
4 */
5 
6 #include "private/pcimpl.h"   /*I "petscpc.h" I*/
7 #include "src/mat/impls/aij/mpi/mpiaij.h"
8 #include "src/ksp/pc/impls/tfs/tfs.h"
9 
10 typedef struct {
11   xxt_ADT  xxt;
12   xyt_ADT  xyt;
13   Vec      b,xd,xo;
14   PetscInt nd;
15 } PC_TFS;
16 
17 #undef __FUNCT__
18 #define __FUNCT__ "PCDestroy_TFS"
19 PetscErrorCode PCDestroy_TFS(PC pc)
20 {
21   PC_TFS *tfs = (PC_TFS*)pc->data;
22   PetscErrorCode ierr;
23 
24   PetscFunctionBegin;
25   /* free the XXT datastructures */
26   if (tfs->xxt) {
27     ierr = XXT_free(tfs->xxt);CHKERRQ(ierr);
28   }
29   if (tfs->xyt) {
30     ierr = XYT_free(tfs->xyt);CHKERRQ(ierr);
31   }
32   if (tfs->b) {
33   ierr = VecDestroy(tfs->b);CHKERRQ(ierr);
34   }
35   if (tfs->xd) {
36   ierr = VecDestroy(tfs->xd);CHKERRQ(ierr);
37   }
38   if (tfs->xo) {
39   ierr = VecDestroy(tfs->xo);CHKERRQ(ierr);
40   }
41   ierr = PetscFree(tfs);CHKERRQ(ierr);
42   PetscFunctionReturn(0);
43 }
44 
45 #undef __FUNCT__
46 #define __FUNCT__ "PCApply_TFS_XXT"
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;
51   PetscErrorCode ierr;
52 
53   PetscFunctionBegin;
54   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
55   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
56   ierr = XXT_solve(tfs->xxt,yy,xx);CHKERRQ(ierr);
57   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
58   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
59   PetscFunctionReturn(0);
60 }
61 
62 #undef __FUNCT__
63 #define __FUNCT__ "PCApply_TFS_XYT"
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;
68   PetscErrorCode ierr;
69 
70   PetscFunctionBegin;
71   ierr = VecGetArray(x,&xx);CHKERRQ(ierr);
72   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
73   ierr = XYT_solve(tfs->xyt,yy,xx);CHKERRQ(ierr);
74   ierr = VecRestoreArray(x,&xx);CHKERRQ(ierr);
75   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
76   PetscFunctionReturn(0);
77 }
78 
79 #undef __FUNCT__
80 #define __FUNCT__ "LocalMult_TFS"
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;
86   PetscErrorCode ierr;
87 
88   PetscFunctionBegin;
89   ierr = VecPlaceArray(tfs->b,xout);CHKERRQ(ierr);
90   ierr = VecPlaceArray(tfs->xd,xin);CHKERRQ(ierr);
91   ierr = VecPlaceArray(tfs->xo,xin+tfs->nd);CHKERRQ(ierr);
92   ierr = MatMult(a->A,tfs->xd,tfs->b);CHKERRQ(ierr);
93   ierr = MatMultAdd(a->B,tfs->xo,tfs->b,tfs->b);CHKERRQ(ierr);
94   ierr = VecResetArray(tfs->b);CHKERRQ(ierr);
95   ierr = VecResetArray(tfs->xd);CHKERRQ(ierr);
96   ierr = VecResetArray(tfs->xo);CHKERRQ(ierr);
97   PetscFunctionReturn(0);
98 }
99 
100 #undef __FUNCT__
101 #define __FUNCT__ "PCSetUp_TFS"
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;
107   PetscErrorCode ierr;
108   PetscInt      *localtoglobal,ncol,i;
109   PetscTruth     ismpiaij;
110 
111   /*
112   PetscTruth     issymmetric;
113   Petsc Real tol = 0.0;
114   */
115 
116   PetscFunctionBegin;
117   if (A->cmap.N != A->rmap.N) SETERRQ(PETSC_ERR_ARG_SIZ,"matrix must be square");
118   ierr = PetscTypeCompare((PetscObject)pc->pmat,MATMPIAIJ,&ismpiaij);CHKERRQ(ierr);
119   if (!ismpiaij) {
120     SETERRQ(PETSC_ERR_SUP,"Currently only supports MPIAIJ matrices");
121   }
122 
123   /* generate the local to global mapping */
124   ncol = a->A->cmap.n + a->B->cmap.n;
125   ierr = PetscMalloc((ncol)*sizeof(PetscInt),&localtoglobal);CHKERRQ(ierr);
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   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->rmap.n,PETSC_NULL,&tfs->b);CHKERRQ(ierr);
134   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->A->cmap.n,PETSC_NULL,&tfs->xd);CHKERRQ(ierr);
135   ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,a->B->cmap.n,PETSC_NULL,&tfs->xo);CHKERRQ(ierr);
136   tfs->nd = a->A->cmap.n;
137 
138 
139   /*  ierr =  MatIsSymmetric(A,tol,&issymmetric); */
140   /*  if (issymmetric) { */
141   ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr);
142   if (A->symmetric) {
143     tfs->xxt       = XXT_new();
144     ierr           = XXT_factor(tfs->xxt,localtoglobal,A->rmap.n,ncol,(void*)LocalMult_TFS,pc);CHKERRQ(ierr);
145     pc->ops->apply = PCApply_TFS_XXT;
146   } else {
147     tfs->xyt       = XYT_new();
148     ierr           = XYT_factor(tfs->xyt,localtoglobal,A->rmap.n,ncol,(void*)LocalMult_TFS,pc);CHKERRQ(ierr);
149     pc->ops->apply = PCApply_TFS_XYT;
150   }
151 
152   ierr = PetscFree(localtoglobal);CHKERRQ(ierr);
153   PetscFunctionReturn(0);
154 }
155 
156 #undef __FUNCT__
157 #define __FUNCT__ "PCSetFromOptions_TFS"
158 static PetscErrorCode PCSetFromOptions_TFS(PC pc)
159 {
160   PetscFunctionBegin;
161   PetscFunctionReturn(0);
162 }
163 #undef __FUNCT__
164 #define __FUNCT__ "PCView_TFS"
165 static PetscErrorCode PCView_TFS(PC pc,PetscViewer viewer)
166 {
167   PetscFunctionBegin;
168   PetscFunctionReturn(0);
169 }
170 
171 EXTERN_C_BEGIN
172 #undef __FUNCT__
173 #define __FUNCT__ "PCCreate_TFS"
174 /*MC
175      PCTFS - A parallel direct solver intended for problems with very few unknowns (like the
176          coarse grid in multigrid).
177 
178    Implemented by  Henry M. Tufo III and Paul Fischer
179 
180    Level: beginner
181 
182    Notes: Only implemented for the MPIAIJ matrices
183 
184 .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC
185 M*/
186 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_TFS(PC pc)
187 {
188   PetscErrorCode ierr;
189   PC_TFS         *tfs;
190 
191   PetscFunctionBegin;
192   ierr = PetscNewLog(pc,PC_TFS,&tfs);CHKERRQ(ierr);
193 
194   tfs->xxt = 0;
195   tfs->xyt = 0;
196   tfs->b   = 0;
197   tfs->xd  = 0;
198   tfs->xo  = 0;
199   tfs->nd  = 0;
200 
201   pc->ops->apply               = 0;
202   pc->ops->applytranspose      = 0;
203   pc->ops->setup               = PCSetUp_TFS;
204   pc->ops->destroy             = PCDestroy_TFS;
205   pc->ops->setfromoptions      = PCSetFromOptions_TFS;
206   pc->ops->view                = PCView_TFS;
207   pc->ops->applyrichardson     = 0;
208   pc->ops->applysymmetricleft  = 0;
209   pc->ops->applysymmetricright = 0;
210   pc->data                     = (void*)tfs;
211   PetscFunctionReturn(0);
212 }
213 EXTERN_C_END
214 
215