xref: /petsc/src/mat/impls/aij/mpi/mpiaijpc.c (revision 028343607802a628ec4a043823d08aee29655c7e)
16699817fSBarry Smith #ifndef lint
2*02834360SBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.1 1995/10/04 03:24:11 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 */
10*02834360SBarry Smith #include "mpiaij.h"
11*02834360SBarry Smith #include "src/pc/pcimpl.h"
12*02834360SBarry 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   }
296699817fSBarry Smith   PETSCFREE(jac->sles);
306699817fSBarry Smith   ierr = VecDestroy(bjac->x); CHKERRQ(ierr);
316699817fSBarry 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;
526699817fSBarry Smith   int              ierr, numtids = pmatin->numtids,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   if (numtids != jac->n) {
676699817fSBarry Smith     SETERRQ(1,"PCSetUp_BJacobiMPIAIJ:Can do only 1 block per processor\n");
686699817fSBarry Smith   }
696699817fSBarry Smith 
706699817fSBarry Smith   /* set default direct solver with no Krylov method */
716699817fSBarry Smith   if (!pc->setupcalled) {
726699817fSBarry Smith     ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr);
736699817fSBarry Smith     PLogObjectParent(pc,sles);
746699817fSBarry Smith     ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr);
756699817fSBarry Smith     ierr = KSPSetMethod(subksp,KSPPREONLY); CHKERRQ(ierr);
766699817fSBarry Smith     ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr);
776699817fSBarry Smith     ierr = PCSetMethod(subpc,PCLU); CHKERRQ(ierr);
786699817fSBarry Smith     ierr = SLESSetOptionsPrefix(sles,"-sub_"); CHKERRQ(ierr);
796699817fSBarry Smith     ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
806699817fSBarry Smith /*
816699817fSBarry Smith    This is not so good. The only reason we need to generate this vector
826699817fSBarry Smith   is so KSP may generate seq vectors for the local solves
836699817fSBarry Smith */
846699817fSBarry Smith     ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr);
856699817fSBarry Smith     ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr);
866699817fSBarry Smith     PLogObjectParent(pmat,x);
876699817fSBarry Smith 
886699817fSBarry Smith     pc->destroy  = PCDestroy_BJacobiMPIAIJ;
896699817fSBarry Smith     pc->apply    = PCApply_BJacobiMPIAIJ;
906699817fSBarry Smith 
916699817fSBarry Smith     bjac         = (PC_BJacobiMPIAIJ *) PETSCMALLOC(sizeof(PC_BJacobiMPIAIJ));
926699817fSBarry Smith     CHKPTRQ(bjac);
936699817fSBarry Smith     PLogObjectMemory(pc,sizeof(PC_BJacobiMPIAIJ));
946699817fSBarry Smith     bjac->x      = x;
956699817fSBarry Smith 
966699817fSBarry Smith     jac->sles    = (SLES*) PETSCMALLOC( sizeof(SLES) ); CHKPTRQ(jac->sles);
976699817fSBarry Smith     jac->sles[0] = sles;
986699817fSBarry Smith     jac->data    = (void *) bjac;
996699817fSBarry Smith   }
1006699817fSBarry Smith   else {
1016699817fSBarry Smith     sles = jac->sles[0];
1026699817fSBarry Smith   }
1036699817fSBarry Smith   if (jac->use_true_local)
1046699817fSBarry Smith     ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag);
1056699817fSBarry Smith   else
1066699817fSBarry Smith     ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag);
1076699817fSBarry Smith   CHKERRQ(ierr);
1086699817fSBarry Smith 
1096699817fSBarry Smith   return 0;
1106699817fSBarry Smith }
1116699817fSBarry Smith 
112*02834360SBarry Smith 
113