xref: /petsc/src/mat/impls/aij/mpi/mpiaijpc.c (revision 4b0e389b2accb070e9f94a7c5aef9e462c8b7c96)
16699817fSBarry Smith #ifndef lint
2*4b0e389bSBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.9 1995/12/21 18:31:45 bsmith 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 {
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;
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);
29b4fd4287SBarry Smith   if (jac->l_lens) PetscFree(jac->l_lens);
30b4fd4287SBarry Smith   if (jac->g_lens) PetscFree(jac->g_lens);
31b4fd4287SBarry Smith   if (jac->l_true) PetscFree(jac->l_true);
32b4fd4287SBarry Smith   if (jac->g_true) PetscFree(jac->g_true);
330452661fSBarry Smith   PetscFree(bjac); PetscFree(jac);
346699817fSBarry Smith   return 0;
356699817fSBarry Smith }
366699817fSBarry Smith 
376699817fSBarry Smith int PCApply_BJacobiMPIAIJ(PC pc,Vec x, Vec y)
386699817fSBarry Smith {
396699817fSBarry Smith   int              ierr,its;
406699817fSBarry Smith   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
416699817fSBarry Smith   PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data;
429da4b979SBarry Smith   Scalar           *array,*true_array;
436699817fSBarry Smith 
449da4b979SBarry Smith   /*
459da4b979SBarry Smith       The VecPlaceArray() is to avoid having to copy the
469da4b979SBarry Smith     y vector into the bjac->x vector. The reason for
479da4b979SBarry Smith     the bjac->x vector is that we need a sequential vector
489da4b979SBarry Smith     for the sequential solve.
499da4b979SBarry Smith   */
509da4b979SBarry Smith   ierr = VecGetArray(y,&array); CHKERRQ(ierr);
519da4b979SBarry Smith   ierr = VecGetArray(bjac->x,&true_array); CHKERRQ(ierr);
529da4b979SBarry Smith   ierr = VecPlaceArray(bjac->x,array); CHKERRQ(ierr);
536699817fSBarry Smith   ierr = SLESSolve(jac->sles[0],x,bjac->x,&its); CHKERRQ(ierr);
549da4b979SBarry Smith   ierr = VecPlaceArray(bjac->x,true_array); CHKERRQ(ierr);
559da4b979SBarry Smith 
566699817fSBarry Smith   return 0;
576699817fSBarry Smith }
586699817fSBarry Smith 
596699817fSBarry Smith int PCSetUp_BJacobiMPIAIJ(PC pc)
606699817fSBarry Smith {
616699817fSBarry Smith   PC_BJacobi       *jac = (PC_BJacobi *) pc->data;
626699817fSBarry Smith   Mat              mat = pc->mat, pmat = pc->pmat;
636699817fSBarry Smith   Mat_MPIAIJ       *pmatin = (Mat_MPIAIJ *) pmat->data;
646699817fSBarry Smith   Mat_MPIAIJ       *matin = 0;
6563b91edcSBarry Smith   int              ierr, m;
666699817fSBarry Smith   SLES             sles;
676699817fSBarry Smith   Vec              x;
686699817fSBarry Smith   PC_BJacobiMPIAIJ *bjac;
696699817fSBarry Smith   KSP              subksp;
706699817fSBarry Smith   PC               subpc;
716699817fSBarry Smith   MatType          type;
726699817fSBarry Smith 
736699817fSBarry Smith   if (jac->use_true_local) {
74*4b0e389bSBarry Smith     MatGetType(pc->mat,&type,PETSC_NULL);
756699817fSBarry Smith     if (type != MATMPIAIJ) SETERRQ(1,"PCSetUp_BJacobiMPIAIJ:Incompatible matrix type.");
766699817fSBarry Smith     matin = (Mat_MPIAIJ *) mat->data;
776699817fSBarry Smith   }
786699817fSBarry Smith 
796699817fSBarry Smith   /* set default direct solver with no Krylov method */
806699817fSBarry Smith   if (!pc->setupcalled) {
816699817fSBarry Smith     ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr);
826699817fSBarry Smith     PLogObjectParent(pc,sles);
836699817fSBarry Smith     ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr);
84*4b0e389bSBarry Smith     ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr);
856699817fSBarry Smith     ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr);
86*4b0e389bSBarry Smith     ierr = PCSetType(subpc,PCLU); CHKERRQ(ierr);
876699817fSBarry Smith     ierr = SLESSetOptionsPrefix(sles,"-sub_"); CHKERRQ(ierr);
886699817fSBarry Smith     ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
896699817fSBarry Smith /*
906699817fSBarry Smith    This is not so good. The only reason we need to generate this vector
916699817fSBarry Smith   is so KSP may generate seq vectors for the local solves
926699817fSBarry Smith */
936699817fSBarry Smith     ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr);
946699817fSBarry Smith     ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr);
956699817fSBarry Smith     PLogObjectParent(pmat,x);
966699817fSBarry Smith 
976699817fSBarry Smith     pc->destroy  = PCDestroy_BJacobiMPIAIJ;
986699817fSBarry Smith     pc->apply    = PCApply_BJacobiMPIAIJ;
996699817fSBarry Smith 
10049c46530SBarry Smith     bjac         = (PC_BJacobiMPIAIJ *) PetscMalloc(sizeof(PC_BJacobiMPIAIJ));CHKPTRQ(bjac);
1016699817fSBarry Smith     PLogObjectMemory(pc,sizeof(PC_BJacobiMPIAIJ));
1026699817fSBarry Smith     bjac->x      = x;
1036699817fSBarry Smith 
1040452661fSBarry Smith     jac->sles    = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles);
1056699817fSBarry Smith     jac->sles[0] = sles;
1066699817fSBarry Smith     jac->data    = (void *) bjac;
1076699817fSBarry Smith   }
1086699817fSBarry Smith   else {
1096699817fSBarry Smith     sles = jac->sles[0];
1106699817fSBarry Smith   }
11149c46530SBarry Smith   if (jac->l_true[0] == USE_TRUE_MATRIX) {
11249c46530SBarry Smith     ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag);
11349c46530SBarry Smith   }
11449c46530SBarry Smith   else if (jac->use_true_local)
1156699817fSBarry Smith     ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag);
1166699817fSBarry Smith   else
1176699817fSBarry Smith     ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag);
1186699817fSBarry Smith   CHKERRQ(ierr);
1196699817fSBarry Smith 
1206699817fSBarry Smith   return 0;
1216699817fSBarry Smith }
1226699817fSBarry Smith 
12302834360SBarry Smith 
124