xref: /petsc/src/mat/impls/aij/mpi/mpiaijpc.c (revision 9da4b97980014f264c154f4ded6e07585648142b)
16699817fSBarry Smith #ifndef lint
2*9da4b979SBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.7 1995/12/03 02:42:38 bsmith Exp bsmith $";
36699817fSBarry Smith #endif
46699817fSBarry Smith /*
56699817fSBarry Smith    Defines a block Jacobi preconditioner for the MPIAIJ format.
6*9da4b979SBarry Smith    Handles special case of  single block per processor.
76699817fSBarry Smith    This file knows about storage formats for MPIAIJ matrices.
8*9da4b979SBarry 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 {
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;
24*9da4b979SBarry Smith   int              ierr;
256699817fSBarry Smith 
26*9da4b979SBarry Smith   ierr = SLESDestroy(jac->sles[0]); CHKERRQ(ierr);
270452661fSBarry Smith   PetscFree(jac->sles);
286699817fSBarry Smith   ierr = VecDestroy(bjac->x); CHKERRQ(ierr);
290452661fSBarry Smith   PetscFree(bjac); PetscFree(jac);
306699817fSBarry Smith   return 0;
316699817fSBarry Smith }
326699817fSBarry Smith 
336699817fSBarry Smith int PCApply_BJacobiMPIAIJ(PC pc,Vec x, Vec y)
346699817fSBarry Smith {
356699817fSBarry Smith   int              ierr,its;
366699817fSBarry Smith   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
376699817fSBarry Smith   PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data;
38*9da4b979SBarry Smith   Scalar           *array,*true_array;
396699817fSBarry Smith 
40*9da4b979SBarry Smith   /*
41*9da4b979SBarry Smith       The VecPlaceArray() is to avoid having to copy the
42*9da4b979SBarry Smith     y vector into the bjac->x vector. The reason for
43*9da4b979SBarry Smith     the bjac->x vector is that we need a sequential vector
44*9da4b979SBarry Smith     for the sequential solve.
45*9da4b979SBarry Smith   */
46*9da4b979SBarry Smith   ierr = VecGetArray(y,&array); CHKERRQ(ierr);
47*9da4b979SBarry Smith   ierr = VecGetArray(bjac->x,&true_array); CHKERRQ(ierr);
48*9da4b979SBarry Smith   ierr = VecPlaceArray(bjac->x,array); CHKERRQ(ierr);
496699817fSBarry Smith   ierr = SLESSolve(jac->sles[0],x,bjac->x,&its); CHKERRQ(ierr);
50*9da4b979SBarry Smith   ierr = VecPlaceArray(bjac->x,true_array); CHKERRQ(ierr);
51*9da4b979SBarry Smith 
526699817fSBarry Smith   return 0;
536699817fSBarry Smith }
546699817fSBarry Smith 
556699817fSBarry Smith int PCSetUp_BJacobiMPIAIJ(PC pc)
566699817fSBarry Smith {
576699817fSBarry Smith   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
586699817fSBarry Smith   Mat              mat = pc->mat, pmat = pc->pmat;
596699817fSBarry Smith   Mat_MPIAIJ       *pmatin = (Mat_MPIAIJ *) pmat->data;
606699817fSBarry Smith   Mat_MPIAIJ       *matin = 0;
6163b91edcSBarry Smith   int              ierr, m;
626699817fSBarry Smith   SLES             sles;
636699817fSBarry Smith   Vec              x;
646699817fSBarry Smith   PC_BJacobiMPIAIJ *bjac;
656699817fSBarry Smith   KSP              subksp;
666699817fSBarry Smith   PC               subpc;
676699817fSBarry Smith   MatType          type;
686699817fSBarry Smith 
696699817fSBarry Smith   if (jac->use_true_local) {
706699817fSBarry Smith     MatGetType(pc->mat,&type);
716699817fSBarry Smith     if (type != MATMPIAIJ) SETERRQ(1,"PCSetUp_BJacobiMPIAIJ:Incompatible matrix type.");
726699817fSBarry Smith     matin = (Mat_MPIAIJ *) mat->data;
736699817fSBarry Smith   }
746699817fSBarry Smith 
756699817fSBarry Smith   /* set default direct solver with no Krylov method */
766699817fSBarry Smith   if (!pc->setupcalled) {
776699817fSBarry Smith     ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr);
786699817fSBarry Smith     PLogObjectParent(pc,sles);
796699817fSBarry Smith     ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr);
806699817fSBarry Smith     ierr = KSPSetMethod(subksp,KSPPREONLY); CHKERRQ(ierr);
816699817fSBarry Smith     ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr);
826699817fSBarry Smith     ierr = PCSetMethod(subpc,PCLU); CHKERRQ(ierr);
836699817fSBarry Smith     ierr = SLESSetOptionsPrefix(sles,"-sub_"); CHKERRQ(ierr);
846699817fSBarry Smith     ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
856699817fSBarry Smith /*
866699817fSBarry Smith    This is not so good. The only reason we need to generate this vector
876699817fSBarry Smith   is so KSP may generate seq vectors for the local solves
886699817fSBarry Smith */
896699817fSBarry Smith     ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr);
906699817fSBarry Smith     ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr);
916699817fSBarry Smith     PLogObjectParent(pmat,x);
926699817fSBarry Smith 
936699817fSBarry Smith     pc->destroy  = PCDestroy_BJacobiMPIAIJ;
946699817fSBarry Smith     pc->apply    = PCApply_BJacobiMPIAIJ;
956699817fSBarry Smith 
9649c46530SBarry Smith     bjac         = (PC_BJacobiMPIAIJ *) PetscMalloc(sizeof(PC_BJacobiMPIAIJ));CHKPTRQ(bjac);
976699817fSBarry Smith     PLogObjectMemory(pc,sizeof(PC_BJacobiMPIAIJ));
986699817fSBarry Smith     bjac->x      = x;
996699817fSBarry Smith 
1000452661fSBarry Smith     jac->sles    = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles);
1016699817fSBarry Smith     jac->sles[0] = sles;
1026699817fSBarry Smith     jac->data    = (void *) bjac;
1036699817fSBarry Smith   }
1046699817fSBarry Smith   else {
1056699817fSBarry Smith     sles = jac->sles[0];
1066699817fSBarry Smith   }
10749c46530SBarry Smith   if (jac->l_true[0] == USE_TRUE_MATRIX) {
10849c46530SBarry Smith     ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag);
10949c46530SBarry Smith   }
11049c46530SBarry Smith   else if (jac->use_true_local)
1116699817fSBarry Smith     ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag);
1126699817fSBarry Smith   else
1136699817fSBarry Smith     ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag);
1146699817fSBarry Smith   CHKERRQ(ierr);
1156699817fSBarry Smith 
1166699817fSBarry Smith   return 0;
1176699817fSBarry Smith }
1186699817fSBarry Smith 
11902834360SBarry Smith 
120