xref: /petsc/src/mat/impls/aij/mpi/mpiaijpc.c (revision 6dea57dee99dbba0a52868d0109c726908a98f00)
16699817fSBarry Smith #ifndef lint
2*6dea57deSBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.14 1996/02/25 02:42:31 curfman Exp bsmith $";
36699817fSBarry Smith #endif
46699817fSBarry Smith /*
56699817fSBarry Smith    Defines a block Jacobi preconditioner for the MPIAIJ format.
69da4b979SBarry Smith    Handles special case of  single block per processor.
76699817fSBarry Smith    This file knows about storage formats for MPIAIJ matrices.
89da4b979SBarry Smith    The general case is handled in aijpc.c
96699817fSBarry Smith */
1002834360SBarry Smith #include "mpiaij.h"
1102834360SBarry Smith #include "src/pc/pcimpl.h"
1202834360SBarry Smith #include "src/pc/impls/bjacobi/bjacobi.h"
136699817fSBarry Smith #include "sles.h"
146699817fSBarry Smith 
156699817fSBarry Smith typedef struct {
16e2147057SSatish Balay   Vec  x, y;
176699817fSBarry Smith } PC_BJacobiMPIAIJ;
186699817fSBarry Smith 
196699817fSBarry Smith int PCDestroy_BJacobiMPIAIJ(PetscObject obj)
206699817fSBarry Smith {
216699817fSBarry Smith   PC               pc = (PC) obj;
226699817fSBarry Smith   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
236699817fSBarry Smith   PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data;
249da4b979SBarry Smith   int              ierr;
256699817fSBarry Smith 
269da4b979SBarry Smith   ierr = SLESDestroy(jac->sles[0]); CHKERRQ(ierr);
270452661fSBarry Smith   PetscFree(jac->sles);
286699817fSBarry Smith   ierr = VecDestroy(bjac->x); CHKERRQ(ierr);
29e2147057SSatish Balay   ierr = VecDestroy(bjac->y); CHKERRQ(ierr);
30b4fd4287SBarry Smith   if (jac->l_lens) PetscFree(jac->l_lens);
31b4fd4287SBarry Smith   if (jac->g_lens) PetscFree(jac->g_lens);
32b4fd4287SBarry Smith   if (jac->l_true) PetscFree(jac->l_true);
33b4fd4287SBarry Smith   if (jac->g_true) PetscFree(jac->g_true);
340452661fSBarry Smith   PetscFree(bjac); PetscFree(jac);
356699817fSBarry Smith   return 0;
366699817fSBarry Smith }
376699817fSBarry Smith 
38*6dea57deSBarry Smith 
39*6dea57deSBarry Smith int PCSetUpOnBlocks_BJacobiMPIAIJ(PC pc)
40*6dea57deSBarry Smith {
41*6dea57deSBarry Smith   int              ierr;
42*6dea57deSBarry Smith   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
43*6dea57deSBarry Smith   PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data;
44*6dea57deSBarry Smith 
45*6dea57deSBarry Smith   ierr = SLESSetUp(jac->sles[0],bjac->x,bjac->y); CHKERRQ(ierr);
46*6dea57deSBarry Smith   return 0;
47*6dea57deSBarry Smith }
48*6dea57deSBarry Smith 
496699817fSBarry Smith int PCApply_BJacobiMPIAIJ(PC pc,Vec x, Vec y)
506699817fSBarry Smith {
516699817fSBarry Smith   int              ierr,its;
526699817fSBarry Smith   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
536699817fSBarry Smith   PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data;
54e2147057SSatish Balay   Scalar           *x_array,*x_true_array, *y_array,*y_true_array;
556699817fSBarry Smith 
569da4b979SBarry Smith   /*
579da4b979SBarry Smith       The VecPlaceArray() is to avoid having to copy the
589da4b979SBarry Smith     y vector into the bjac->x vector. The reason for
599da4b979SBarry Smith     the bjac->x vector is that we need a sequential vector
609da4b979SBarry Smith     for the sequential solve.
619da4b979SBarry Smith   */
62e2147057SSatish Balay   ierr = VecGetArray(x,&x_array); CHKERRQ(ierr);
63e2147057SSatish Balay   ierr = VecGetArray(y,&y_array); CHKERRQ(ierr);
64e2147057SSatish Balay   ierr = VecGetArray(bjac->x,&x_true_array); CHKERRQ(ierr);
65e2147057SSatish Balay   ierr = VecGetArray(bjac->y,&y_true_array); CHKERRQ(ierr);
66e2147057SSatish Balay   ierr = VecPlaceArray(bjac->x,x_array); CHKERRQ(ierr);
67e2147057SSatish Balay   ierr = VecPlaceArray(bjac->y,y_array); CHKERRQ(ierr);
68e2147057SSatish Balay   ierr = SLESSolve(jac->sles[0],bjac->x,bjac->y,&its); CHKERRQ(ierr);
69e2147057SSatish Balay   ierr = VecPlaceArray(bjac->x,x_true_array); CHKERRQ(ierr);
70e2147057SSatish Balay   ierr = VecPlaceArray(bjac->y,y_true_array); CHKERRQ(ierr);
716699817fSBarry Smith   return 0;
726699817fSBarry Smith }
736699817fSBarry Smith 
746699817fSBarry Smith int PCSetUp_BJacobiMPIAIJ(PC pc)
756699817fSBarry Smith {
766699817fSBarry Smith   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
776699817fSBarry Smith   Mat              mat = pc->mat, pmat = pc->pmat;
786699817fSBarry Smith   Mat_MPIAIJ       *pmatin = (Mat_MPIAIJ *) pmat->data;
796699817fSBarry Smith   Mat_MPIAIJ       *matin = 0;
8063b91edcSBarry Smith   int              ierr, m;
816699817fSBarry Smith   SLES             sles;
82e2147057SSatish Balay   Vec              x,y;
836699817fSBarry Smith   PC_BJacobiMPIAIJ *bjac;
846699817fSBarry Smith   KSP              subksp;
856699817fSBarry Smith   PC               subpc;
866699817fSBarry Smith   MatType          type;
876699817fSBarry Smith 
886699817fSBarry Smith   if (jac->use_true_local) {
894b0e389bSBarry Smith     MatGetType(pc->mat,&type,PETSC_NULL);
906699817fSBarry Smith     if (type != MATMPIAIJ) SETERRQ(1,"PCSetUp_BJacobiMPIAIJ:Incompatible matrix type.");
916699817fSBarry Smith     matin = (Mat_MPIAIJ *) mat->data;
926699817fSBarry Smith   }
936699817fSBarry Smith 
946699817fSBarry Smith   /* set default direct solver with no Krylov method */
956699817fSBarry Smith   if (!pc->setupcalled) {
966699817fSBarry Smith     ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr);
976699817fSBarry Smith     PLogObjectParent(pc,sles);
986699817fSBarry Smith     ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr);
994b0e389bSBarry Smith     ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr);
1006699817fSBarry Smith     ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr);
1014b0e389bSBarry Smith     ierr = PCSetType(subpc,PCLU); CHKERRQ(ierr);
1026daaf66cSBarry Smith     ierr = SLESSetOptionsPrefix(sles,"sub_"); CHKERRQ(ierr);
1036699817fSBarry Smith     ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
1046699817fSBarry Smith /*
1056699817fSBarry Smith    This is not so good. The only reason we need to generate this vector
1066699817fSBarry Smith   is so KSP may generate seq vectors for the local solves
1076699817fSBarry Smith */
1086699817fSBarry Smith     ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr);
1096699817fSBarry Smith     ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr);
110e2147057SSatish Balay     ierr = VecCreateSeq(MPI_COMM_SELF,m,&y); CHKERRQ(ierr);
1116699817fSBarry Smith     PLogObjectParent(pmat,x);
112e2147057SSatish Balay     PLogObjectParent(pmat,y);
1136699817fSBarry Smith 
1146699817fSBarry Smith     pc->destroy       = PCDestroy_BJacobiMPIAIJ;
1156699817fSBarry Smith     pc->apply         = PCApply_BJacobiMPIAIJ;
116*6dea57deSBarry Smith     pc->setuponblocks = PCSetUpOnBlocks_BJacobiMPIAIJ;
1176699817fSBarry Smith 
11849c46530SBarry Smith     bjac         = (PC_BJacobiMPIAIJ *) PetscMalloc(sizeof(PC_BJacobiMPIAIJ));CHKPTRQ(bjac);
1196699817fSBarry Smith     PLogObjectMemory(pc,sizeof(PC_BJacobiMPIAIJ));
1206699817fSBarry Smith     bjac->x      = x;
121e2147057SSatish Balay     bjac->y      = y;
1226699817fSBarry Smith 
1230452661fSBarry Smith     jac->sles    = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles);
1246699817fSBarry Smith     jac->sles[0] = sles;
1256699817fSBarry Smith     jac->data    = (void *) bjac;
1266699817fSBarry Smith   }
1276699817fSBarry Smith   else {
1286699817fSBarry Smith     sles = jac->sles[0];
129e5c453d8SLois Curfman McInnes     bjac = (PC_BJacobiMPIAIJ *)jac->data;
1306699817fSBarry Smith   }
13149c46530SBarry Smith   if (jac->l_true[0] == USE_TRUE_MATRIX) {
13249c46530SBarry Smith     ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag);
13349c46530SBarry Smith   }
13449c46530SBarry Smith   else if (jac->use_true_local)
1356699817fSBarry Smith     ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag);
1366699817fSBarry Smith   else
1376699817fSBarry Smith     ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag);
1386699817fSBarry Smith   CHKERRQ(ierr);
1396699817fSBarry Smith   return 0;
1406699817fSBarry Smith }
1416699817fSBarry Smith 
14202834360SBarry Smith 
143