xref: /petsc/src/ksp/pc/impls/tfs/tfs.c (revision 7773e740a59dc995f6fb3ee2f4d2bd5cd7cda562)
1 /*
2         Provides an interface to the Tufo-Fischer parallel direct solver
3 */
4 
5 #include <petsc-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           Only works on a solver object that lives on all of PETSC_COMM_WORLD!
176 
177 .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC
178 M*/
179 PetscErrorCode  PCCreate_TFS(PC pc)
180 {
181   PetscErrorCode ierr;
182   PC_TFS         *tfs;
183 
184   PetscFunctionBegin;
185   ierr = PetscNewLog(pc,PC_TFS,&tfs);CHKERRQ(ierr);
186 
187   tfs->xxt = 0;
188   tfs->xyt = 0;
189   tfs->b   = 0;
190   tfs->xd  = 0;
191   tfs->xo  = 0;
192   tfs->nd  = 0;
193 
194   pc->ops->apply               = 0;
195   pc->ops->applytranspose      = 0;
196   pc->ops->setup               = PCSetUp_TFS;
197   pc->ops->destroy             = PCDestroy_TFS;
198   pc->ops->setfromoptions      = PCSetFromOptions_TFS;
199   pc->ops->view                = PCView_TFS;
200   pc->ops->applyrichardson     = 0;
201   pc->ops->applysymmetricleft  = 0;
202   pc->ops->applysymmetricright = 0;
203   pc->data                     = (void*)tfs;
204   PetscFunctionReturn(0);
205 }
206 EXTERN_C_END
207 
208