xref: /petsc/src/mat/impls/aij/mpi/mpiaijpc.c (revision e21470574e62e05c57ae15175f5c7b39d108f5f2)
16699817fSBarry Smith #ifndef lint
2*e2147057SSatish Balay static char vcid[] = "$Id: mpiaijpc.c,v 1.11 1996/01/12 03:53:14 bsmith Exp balay $";
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 {
16*e2147057SSatish 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);
29*e2147057SSatish 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 
386699817fSBarry Smith int PCApply_BJacobiMPIAIJ(PC pc,Vec x, Vec y)
396699817fSBarry Smith {
406699817fSBarry Smith   int              ierr,its;
416699817fSBarry Smith   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
426699817fSBarry Smith   PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data;
43*e2147057SSatish Balay   Scalar           *x_array,*x_true_array, *y_array,*y_true_array;
446699817fSBarry Smith 
459da4b979SBarry Smith   /*
469da4b979SBarry Smith       The VecPlaceArray() is to avoid having to copy the
479da4b979SBarry Smith     y vector into the bjac->x vector. The reason for
489da4b979SBarry Smith     the bjac->x vector is that we need a sequential vector
499da4b979SBarry Smith     for the sequential solve.
509da4b979SBarry Smith   */
51*e2147057SSatish Balay   ierr = VecGetArray(x,&x_array); CHKERRQ(ierr);
52*e2147057SSatish Balay   ierr = VecGetArray(y,&y_array); CHKERRQ(ierr);
53*e2147057SSatish Balay   ierr = VecGetArray(bjac->x,&x_true_array); CHKERRQ(ierr);
54*e2147057SSatish Balay   ierr = VecGetArray(bjac->y,&y_true_array); CHKERRQ(ierr);
55*e2147057SSatish Balay   ierr = VecPlaceArray(bjac->x,x_array); CHKERRQ(ierr);
56*e2147057SSatish Balay   ierr = VecPlaceArray(bjac->y,y_array); CHKERRQ(ierr);
57*e2147057SSatish Balay   ierr = SLESSolve(jac->sles[0],bjac->x,bjac->y,&its); CHKERRQ(ierr);
58*e2147057SSatish Balay   ierr = VecPlaceArray(bjac->x,x_true_array); CHKERRQ(ierr);
59*e2147057SSatish Balay   ierr = VecPlaceArray(bjac->y,y_true_array); CHKERRQ(ierr);
609da4b979SBarry Smith 
616699817fSBarry Smith   return 0;
626699817fSBarry Smith }
636699817fSBarry Smith 
646699817fSBarry Smith int PCSetUp_BJacobiMPIAIJ(PC pc)
656699817fSBarry Smith {
666699817fSBarry Smith   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
676699817fSBarry Smith   Mat              mat = pc->mat, pmat = pc->pmat;
686699817fSBarry Smith   Mat_MPIAIJ       *pmatin = (Mat_MPIAIJ *) pmat->data;
696699817fSBarry Smith   Mat_MPIAIJ       *matin = 0;
7063b91edcSBarry Smith   int              ierr, m;
716699817fSBarry Smith   SLES             sles;
72*e2147057SSatish Balay   Vec              x,y;
736699817fSBarry Smith   PC_BJacobiMPIAIJ *bjac;
746699817fSBarry Smith   KSP              subksp;
756699817fSBarry Smith   PC               subpc;
766699817fSBarry Smith   MatType          type;
776699817fSBarry Smith 
786699817fSBarry Smith   if (jac->use_true_local) {
794b0e389bSBarry Smith     MatGetType(pc->mat,&type,PETSC_NULL);
806699817fSBarry Smith     if (type != MATMPIAIJ) SETERRQ(1,"PCSetUp_BJacobiMPIAIJ:Incompatible matrix type.");
816699817fSBarry Smith     matin = (Mat_MPIAIJ *) mat->data;
826699817fSBarry Smith   }
836699817fSBarry Smith 
846699817fSBarry Smith   /* set default direct solver with no Krylov method */
856699817fSBarry Smith   if (!pc->setupcalled) {
866699817fSBarry Smith     ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr);
876699817fSBarry Smith     PLogObjectParent(pc,sles);
886699817fSBarry Smith     ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr);
894b0e389bSBarry Smith     ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr);
906699817fSBarry Smith     ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr);
914b0e389bSBarry Smith     ierr = PCSetType(subpc,PCLU); CHKERRQ(ierr);
926daaf66cSBarry Smith     ierr = SLESSetOptionsPrefix(sles,"sub_"); CHKERRQ(ierr);
936699817fSBarry Smith     ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
946699817fSBarry Smith /*
956699817fSBarry Smith    This is not so good. The only reason we need to generate this vector
966699817fSBarry Smith   is so KSP may generate seq vectors for the local solves
976699817fSBarry Smith */
986699817fSBarry Smith     ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr);
996699817fSBarry Smith     ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr);
100*e2147057SSatish Balay     ierr = VecCreateSeq(MPI_COMM_SELF,m,&y); CHKERRQ(ierr);
1016699817fSBarry Smith     PLogObjectParent(pmat,x);
102*e2147057SSatish Balay     PLogObjectParent(pmat,y);
1036699817fSBarry Smith 
1046699817fSBarry Smith     pc->destroy  = PCDestroy_BJacobiMPIAIJ;
1056699817fSBarry Smith     pc->apply    = PCApply_BJacobiMPIAIJ;
1066699817fSBarry Smith 
10749c46530SBarry Smith     bjac         = (PC_BJacobiMPIAIJ *) PetscMalloc(sizeof(PC_BJacobiMPIAIJ));CHKPTRQ(bjac);
1086699817fSBarry Smith     PLogObjectMemory(pc,sizeof(PC_BJacobiMPIAIJ));
1096699817fSBarry Smith     bjac->x      = x;
110*e2147057SSatish Balay     bjac->y      = y;
1116699817fSBarry Smith 
1120452661fSBarry Smith     jac->sles    = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles);
1136699817fSBarry Smith     jac->sles[0] = sles;
1146699817fSBarry Smith     jac->data    = (void *) bjac;
1156699817fSBarry Smith   }
1166699817fSBarry Smith   else {
1176699817fSBarry Smith     sles = jac->sles[0];
1186699817fSBarry Smith   }
11949c46530SBarry Smith   if (jac->l_true[0] == USE_TRUE_MATRIX) {
12049c46530SBarry Smith     ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag);
12149c46530SBarry Smith   }
12249c46530SBarry Smith   else if (jac->use_true_local)
1236699817fSBarry Smith     ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag);
1246699817fSBarry Smith   else
1256699817fSBarry Smith     ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag);
1266699817fSBarry Smith   CHKERRQ(ierr);
127*e2147057SSatish Balay   ierr = SLESSetUp(sles,bjac->x,bjac->y); CHKERRQ(ierr);
1286699817fSBarry Smith   return 0;
1296699817fSBarry Smith }
1306699817fSBarry Smith 
13102834360SBarry Smith 
132