xref: /petsc/src/mat/impls/aij/mpi/mpiaijpc.c (revision 49c465302fbc3d2f8bd3a12a002e9ced08d7a437)
16699817fSBarry Smith #ifndef lint
2*49c46530SBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.6 1995/11/01 23:18:18 bsmith Exp bsmith $";
36699817fSBarry Smith #endif
46699817fSBarry Smith /*
56699817fSBarry Smith    Defines a block Jacobi preconditioner for the MPIAIJ format.
66699817fSBarry Smith    At the moment only supports a single block per processor.
76699817fSBarry Smith    This file knows about storage formats for MPIAIJ matrices.
86699817fSBarry Smith    This code is nearly identical to that for the MPIROW format;
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 {
166699817fSBarry Smith   Vec  x;
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;
246699817fSBarry Smith   int              i,ierr;
256699817fSBarry Smith 
266699817fSBarry Smith   for ( i=0; i<jac->n_local; i++ ) {
276699817fSBarry Smith     ierr = SLESDestroy(jac->sles[i]); CHKERRQ(ierr);
286699817fSBarry Smith   }
290452661fSBarry Smith   PetscFree(jac->sles);
306699817fSBarry Smith   ierr = VecDestroy(bjac->x); CHKERRQ(ierr);
310452661fSBarry Smith   PetscFree(bjac); PetscFree(jac);
326699817fSBarry Smith   return 0;
336699817fSBarry Smith }
346699817fSBarry Smith 
356699817fSBarry Smith int PCApply_BJacobiMPIAIJ(PC pc,Vec x, Vec y)
366699817fSBarry Smith {
376699817fSBarry Smith   int              ierr,its;
386699817fSBarry Smith   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
396699817fSBarry Smith   PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data;
406699817fSBarry Smith 
416699817fSBarry Smith   ierr = SLESSolve(jac->sles[0],x,bjac->x,&its); CHKERRQ(ierr);
426699817fSBarry Smith   ierr = VecCopy(bjac->x,y); CHKERRQ(ierr);
436699817fSBarry Smith   return 0;
446699817fSBarry Smith }
456699817fSBarry Smith 
466699817fSBarry Smith int PCSetUp_BJacobiMPIAIJ(PC pc)
476699817fSBarry Smith {
486699817fSBarry Smith   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
496699817fSBarry Smith   Mat              mat = pc->mat, pmat = pc->pmat;
506699817fSBarry Smith   Mat_MPIAIJ       *pmatin = (Mat_MPIAIJ *) pmat->data;
516699817fSBarry Smith   Mat_MPIAIJ       *matin = 0;
5263b91edcSBarry Smith   int              ierr, m;
536699817fSBarry Smith   SLES             sles;
546699817fSBarry Smith   Vec              x;
556699817fSBarry Smith   PC_BJacobiMPIAIJ *bjac;
566699817fSBarry Smith   KSP              subksp;
576699817fSBarry Smith   PC               subpc;
586699817fSBarry Smith   MatType          type;
596699817fSBarry Smith 
606699817fSBarry Smith   if (jac->use_true_local) {
616699817fSBarry Smith     MatGetType(pc->mat,&type);
626699817fSBarry Smith     if (type != MATMPIAIJ) SETERRQ(1,"PCSetUp_BJacobiMPIAIJ:Incompatible matrix type.");
636699817fSBarry Smith     matin = (Mat_MPIAIJ *) mat->data;
646699817fSBarry Smith   }
656699817fSBarry Smith 
666699817fSBarry Smith   /* set default direct solver with no Krylov method */
676699817fSBarry Smith   if (!pc->setupcalled) {
686699817fSBarry Smith     ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr);
696699817fSBarry Smith     PLogObjectParent(pc,sles);
706699817fSBarry Smith     ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr);
716699817fSBarry Smith     ierr = KSPSetMethod(subksp,KSPPREONLY); CHKERRQ(ierr);
726699817fSBarry Smith     ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr);
736699817fSBarry Smith     ierr = PCSetMethod(subpc,PCLU); CHKERRQ(ierr);
746699817fSBarry Smith     ierr = SLESSetOptionsPrefix(sles,"-sub_"); CHKERRQ(ierr);
756699817fSBarry Smith     ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
766699817fSBarry Smith /*
776699817fSBarry Smith    This is not so good. The only reason we need to generate this vector
786699817fSBarry Smith   is so KSP may generate seq vectors for the local solves
796699817fSBarry Smith */
806699817fSBarry Smith     ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr);
816699817fSBarry Smith     ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr);
826699817fSBarry Smith     PLogObjectParent(pmat,x);
836699817fSBarry Smith 
846699817fSBarry Smith     pc->destroy  = PCDestroy_BJacobiMPIAIJ;
856699817fSBarry Smith     pc->apply    = PCApply_BJacobiMPIAIJ;
866699817fSBarry Smith 
87*49c46530SBarry Smith     bjac         = (PC_BJacobiMPIAIJ *) PetscMalloc(sizeof(PC_BJacobiMPIAIJ));CHKPTRQ(bjac);
886699817fSBarry Smith     PLogObjectMemory(pc,sizeof(PC_BJacobiMPIAIJ));
896699817fSBarry Smith     bjac->x      = x;
906699817fSBarry Smith 
910452661fSBarry Smith     jac->sles    = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles);
926699817fSBarry Smith     jac->sles[0] = sles;
936699817fSBarry Smith     jac->data    = (void *) bjac;
946699817fSBarry Smith   }
956699817fSBarry Smith   else {
966699817fSBarry Smith     sles = jac->sles[0];
976699817fSBarry Smith   }
98*49c46530SBarry Smith   if (jac->l_true[0] == USE_TRUE_MATRIX) {
99*49c46530SBarry Smith     ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag);
100*49c46530SBarry Smith   }
101*49c46530SBarry Smith   else if (jac->use_true_local)
1026699817fSBarry Smith     ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag);
1036699817fSBarry Smith   else
1046699817fSBarry Smith     ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag);
1056699817fSBarry Smith   CHKERRQ(ierr);
1066699817fSBarry Smith 
1076699817fSBarry Smith   return 0;
1086699817fSBarry Smith }
1096699817fSBarry Smith 
11002834360SBarry Smith 
111