xref: /petsc/src/mat/impls/aij/mpi/mpiaijpc.c (revision 70f55243aafb320636e2a54ff30cab5d1e8d3d7b)
16699817fSBarry Smith #ifndef lint
2*70f55243SBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.19 1996/08/05 22:55:04 balay 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 */
10*70f55243SBarry Smith #include "src/mat/impls/aij/mpi/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 {
16e2147057SSatish Balay   Vec  x, y;
1768e69f27SSatish Balay } PC_BJacobi_MPIAIJ;
186699817fSBarry Smith 
1968e69f27SSatish Balay int PCDestroy_BJacobi_MPIAIJ(PetscObject obj)
206699817fSBarry Smith {
216699817fSBarry Smith   PC                pc = (PC) obj;
226699817fSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
2368e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) 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);
29e2147057SSatish 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);
320452661fSBarry Smith   PetscFree(bjac); PetscFree(jac);
336699817fSBarry Smith   return 0;
346699817fSBarry Smith }
356699817fSBarry Smith 
366dea57deSBarry Smith 
3768e69f27SSatish Balay int PCSetUpOnBlocks_BJacobi_MPIAIJ(PC pc)
386dea57deSBarry Smith {
396dea57deSBarry Smith   int               ierr;
406dea57deSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
4168e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data;
426dea57deSBarry Smith 
436dea57deSBarry Smith   ierr = SLESSetUp(jac->sles[0],bjac->x,bjac->y); CHKERRQ(ierr);
446dea57deSBarry Smith   return 0;
456dea57deSBarry Smith }
466dea57deSBarry Smith 
4768e69f27SSatish Balay int PCApply_BJacobi_MPIAIJ(PC pc,Vec x, Vec y)
486699817fSBarry Smith {
496699817fSBarry Smith   int               ierr,its;
506699817fSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
5168e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data;
52e2147057SSatish Balay   Scalar            *x_array,*x_true_array, *y_array,*y_true_array;
536699817fSBarry Smith 
549da4b979SBarry Smith   /*
559da4b979SBarry Smith       The VecPlaceArray() is to avoid having to copy the
569da4b979SBarry Smith     y vector into the bjac->x vector. The reason for
579da4b979SBarry Smith     the bjac->x vector is that we need a sequential vector
589da4b979SBarry Smith     for the sequential solve.
599da4b979SBarry Smith   */
60e2147057SSatish Balay   ierr = VecGetArray(x,&x_array); CHKERRQ(ierr);
61e2147057SSatish Balay   ierr = VecGetArray(y,&y_array); CHKERRQ(ierr);
62e2147057SSatish Balay   ierr = VecGetArray(bjac->x,&x_true_array); CHKERRQ(ierr);
63e2147057SSatish Balay   ierr = VecGetArray(bjac->y,&y_true_array); CHKERRQ(ierr);
64e2147057SSatish Balay   ierr = VecPlaceArray(bjac->x,x_array); CHKERRQ(ierr);
65e2147057SSatish Balay   ierr = VecPlaceArray(bjac->y,y_array); CHKERRQ(ierr);
66e2147057SSatish Balay   ierr = SLESSolve(jac->sles[0],bjac->x,bjac->y,&its); CHKERRQ(ierr);
67e2147057SSatish Balay   ierr = VecPlaceArray(bjac->x,x_true_array); CHKERRQ(ierr);
68e2147057SSatish Balay   ierr = VecPlaceArray(bjac->y,y_true_array); CHKERRQ(ierr);
696699817fSBarry Smith   return 0;
706699817fSBarry Smith }
716699817fSBarry Smith 
7268e69f27SSatish Balay int PCSetUp_BJacobi_MPIAIJ(PC pc)
736699817fSBarry Smith {
746699817fSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
756699817fSBarry Smith   Mat               mat = pc->mat, pmat = pc->pmat;
766699817fSBarry Smith   Mat_MPIAIJ        *pmatin = (Mat_MPIAIJ *) pmat->data;
776699817fSBarry Smith   Mat_MPIAIJ        *matin = 0;
7863b91edcSBarry Smith   int               ierr, m;
796699817fSBarry Smith   SLES              sles;
80e2147057SSatish Balay   Vec               x,y;
8168e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac;
826699817fSBarry Smith   KSP               subksp;
836699817fSBarry Smith   PC                subpc;
846699817fSBarry Smith   MatType           type;
856699817fSBarry Smith 
866699817fSBarry Smith   if (jac->use_true_local) {
874b0e389bSBarry Smith     MatGetType(pc->mat,&type,PETSC_NULL);
8868e69f27SSatish Balay     if (type != MATMPIAIJ) SETERRQ(1,"PCSetUp_BJacobi_MPIAIJ:Incompatible matrix type.");
896699817fSBarry Smith     matin = (Mat_MPIAIJ *) mat->data;
906699817fSBarry Smith   }
916699817fSBarry Smith 
926699817fSBarry Smith   /* set default direct solver with no Krylov method */
936699817fSBarry Smith   if (!pc->setupcalled) {
946699817fSBarry Smith     ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr);
956699817fSBarry Smith     PLogObjectParent(pc,sles);
966699817fSBarry Smith     ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr);
974b0e389bSBarry Smith     ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr);
986699817fSBarry Smith     ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr);
993b90cdfbSSatish Balay     ierr = PCSetType(subpc,PCILU); CHKERRQ(ierr);
1006daaf66cSBarry Smith     ierr = SLESSetOptionsPrefix(sles,"sub_"); CHKERRQ(ierr);
1016699817fSBarry Smith     ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
1026699817fSBarry Smith /*
1036699817fSBarry Smith    This is not so good. The only reason we need to generate this vector
1046699817fSBarry Smith   is so KSP may generate seq vectors for the local solves
1056699817fSBarry Smith */
1066699817fSBarry Smith     ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr);
1076699817fSBarry Smith     ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr);
108e2147057SSatish Balay     ierr = VecCreateSeq(MPI_COMM_SELF,m,&y); CHKERRQ(ierr);
1096699817fSBarry Smith     PLogObjectParent(pmat,x);
110e2147057SSatish Balay     PLogObjectParent(pmat,y);
1116699817fSBarry Smith 
11268e69f27SSatish Balay     pc->destroy       = PCDestroy_BJacobi_MPIAIJ;
11368e69f27SSatish Balay     pc->apply         = PCApply_BJacobi_MPIAIJ;
11468e69f27SSatish Balay     pc->setuponblocks = PCSetUpOnBlocks_BJacobi_MPIAIJ;
1156699817fSBarry Smith 
11668e69f27SSatish Balay     bjac         = (PC_BJacobi_MPIAIJ *) PetscMalloc(sizeof(PC_BJacobi_MPIAIJ));CHKPTRQ(bjac);
11768e69f27SSatish Balay     PLogObjectMemory(pc,sizeof(PC_BJacobi_MPIAIJ));
1186699817fSBarry Smith     bjac->x      = x;
119e2147057SSatish Balay     bjac->y      = y;
1206699817fSBarry Smith 
1210452661fSBarry Smith     jac->sles    = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles);
1226699817fSBarry Smith     jac->sles[0] = sles;
1236699817fSBarry Smith     jac->data    = (void *) bjac;
1246699817fSBarry Smith   }
1256699817fSBarry Smith   else {
1266699817fSBarry Smith     sles = jac->sles[0];
12768e69f27SSatish Balay     bjac = (PC_BJacobi_MPIAIJ *)jac->data;
1286699817fSBarry Smith   }
129c915c865SSatish Balay   /* if (jac->l_true[0] == USE_TRUE_MATRIX) {
13049c46530SBarry Smith     ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag);
13149c46530SBarry Smith   }
132c915c865SSatish Balay   else */ if (jac->use_true_local)
1336699817fSBarry Smith     ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag);
1346699817fSBarry Smith   else
1356699817fSBarry Smith     ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag);
1366699817fSBarry Smith   CHKERRQ(ierr);
1376699817fSBarry Smith   return 0;
1386699817fSBarry Smith }
1396699817fSBarry Smith 
14002834360SBarry Smith 
141