xref: /petsc/src/mat/impls/aij/mpi/mpiaijpc.c (revision 6d84be18fbb99ba69be7b8bdde5411a66955b7ea)
1 #ifndef lint
2 static char vcid[] = "$Id: mpiaijpc.c,v 1.14 1996/02/25 02:42:31 curfman Exp bsmith $";
3 #endif
4 /*
5    Defines a block Jacobi preconditioner for the MPIAIJ format.
6    Handles special case of  single block per processor.
7    This file knows about storage formats for MPIAIJ matrices.
8    The general case is handled in aijpc.c
9 */
10 #include "mpiaij.h"
11 #include "src/pc/pcimpl.h"
12 #include "src/pc/impls/bjacobi/bjacobi.h"
13 #include "sles.h"
14 
15 typedef struct {
16   Vec  x, y;
17 } PC_BJacobiMPIAIJ;
18 
19 int PCDestroy_BJacobiMPIAIJ(PetscObject obj)
20 {
21   PC               pc = (PC) obj;
22   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
23   PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data;
24   int              ierr;
25 
26   ierr = SLESDestroy(jac->sles[0]); CHKERRQ(ierr);
27   PetscFree(jac->sles);
28   ierr = VecDestroy(bjac->x); CHKERRQ(ierr);
29   ierr = VecDestroy(bjac->y); CHKERRQ(ierr);
30   if (jac->l_lens) PetscFree(jac->l_lens);
31   if (jac->g_lens) PetscFree(jac->g_lens);
32   if (jac->l_true) PetscFree(jac->l_true);
33   if (jac->g_true) PetscFree(jac->g_true);
34   PetscFree(bjac); PetscFree(jac);
35   return 0;
36 }
37 
38 
39 int PCSetUpOnBlocks_BJacobiMPIAIJ(PC pc)
40 {
41   int              ierr;
42   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
43   PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data;
44 
45   ierr = SLESSetUp(jac->sles[0],bjac->x,bjac->y); CHKERRQ(ierr);
46   return 0;
47 }
48 
49 int PCApply_BJacobiMPIAIJ(PC pc,Vec x, Vec y)
50 {
51   int              ierr,its;
52   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
53   PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data;
54   Scalar           *x_array,*x_true_array, *y_array,*y_true_array;
55 
56   /*
57       The VecPlaceArray() is to avoid having to copy the
58     y vector into the bjac->x vector. The reason for
59     the bjac->x vector is that we need a sequential vector
60     for the sequential solve.
61   */
62   ierr = VecGetArray(x,&x_array); CHKERRQ(ierr);
63   ierr = VecGetArray(y,&y_array); CHKERRQ(ierr);
64   ierr = VecGetArray(bjac->x,&x_true_array); CHKERRQ(ierr);
65   ierr = VecGetArray(bjac->y,&y_true_array); CHKERRQ(ierr);
66   ierr = VecPlaceArray(bjac->x,x_array); CHKERRQ(ierr);
67   ierr = VecPlaceArray(bjac->y,y_array); CHKERRQ(ierr);
68   ierr = SLESSolve(jac->sles[0],bjac->x,bjac->y,&its); CHKERRQ(ierr);
69   ierr = VecPlaceArray(bjac->x,x_true_array); CHKERRQ(ierr);
70   ierr = VecPlaceArray(bjac->y,y_true_array); CHKERRQ(ierr);
71   return 0;
72 }
73 
74 int PCSetUp_BJacobiMPIAIJ(PC pc)
75 {
76   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
77   Mat              mat = pc->mat, pmat = pc->pmat;
78   Mat_MPIAIJ       *pmatin = (Mat_MPIAIJ *) pmat->data;
79   Mat_MPIAIJ       *matin = 0;
80   int              ierr, m;
81   SLES             sles;
82   Vec              x,y;
83   PC_BJacobiMPIAIJ *bjac;
84   KSP              subksp;
85   PC               subpc;
86   MatType          type;
87 
88   if (jac->use_true_local) {
89     MatGetType(pc->mat,&type,PETSC_NULL);
90     if (type != MATMPIAIJ) SETERRQ(1,"PCSetUp_BJacobiMPIAIJ:Incompatible matrix type.");
91     matin = (Mat_MPIAIJ *) mat->data;
92   }
93 
94   /* set default direct solver with no Krylov method */
95   if (!pc->setupcalled) {
96     ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr);
97     PLogObjectParent(pc,sles);
98     ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr);
99     ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr);
100     ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr);
101     ierr = PCSetType(subpc,PCLU); CHKERRQ(ierr);
102     ierr = SLESSetOptionsPrefix(sles,"sub_"); CHKERRQ(ierr);
103     ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
104 /*
105    This is not so good. The only reason we need to generate this vector
106   is so KSP may generate seq vectors for the local solves
107 */
108     ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr);
109     ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr);
110     ierr = VecCreateSeq(MPI_COMM_SELF,m,&y); CHKERRQ(ierr);
111     PLogObjectParent(pmat,x);
112     PLogObjectParent(pmat,y);
113 
114     pc->destroy       = PCDestroy_BJacobiMPIAIJ;
115     pc->apply         = PCApply_BJacobiMPIAIJ;
116     pc->setuponblocks = PCSetUpOnBlocks_BJacobiMPIAIJ;
117 
118     bjac         = (PC_BJacobiMPIAIJ *) PetscMalloc(sizeof(PC_BJacobiMPIAIJ));CHKPTRQ(bjac);
119     PLogObjectMemory(pc,sizeof(PC_BJacobiMPIAIJ));
120     bjac->x      = x;
121     bjac->y      = y;
122 
123     jac->sles    = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles);
124     jac->sles[0] = sles;
125     jac->data    = (void *) bjac;
126   }
127   else {
128     sles = jac->sles[0];
129     bjac = (PC_BJacobiMPIAIJ *)jac->data;
130   }
131   if (jac->l_true[0] == USE_TRUE_MATRIX) {
132     ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag);
133   }
134   else if (jac->use_true_local)
135     ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag);
136   else
137     ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag);
138   CHKERRQ(ierr);
139   return 0;
140 }
141 
142 
143