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