xref: /petsc/src/mat/impls/aij/mpi/mpiaijpc.c (revision 90f02eec332fcca4c33b4e7b21cabed76bf0614e)
16699817fSBarry Smith #ifndef lint
2*90f02eecSBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.21 1996/11/07 15:09:25 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 */
1070f55243SBarry Smith #include "src/mat/impls/aij/mpi/mpiaij.h"
1102834360SBarry Smith #include "src/pc/pcimpl.h"
12*90f02eecSBarry Smith #include "src/vec/vecimpl.h"
1302834360SBarry Smith #include "src/pc/impls/bjacobi/bjacobi.h"
146699817fSBarry Smith #include "sles.h"
156699817fSBarry Smith 
166699817fSBarry Smith typedef struct {
17e2147057SSatish Balay   Vec  x, y;
1868e69f27SSatish Balay } PC_BJacobi_MPIAIJ;
196699817fSBarry Smith 
2068e69f27SSatish Balay int PCDestroy_BJacobi_MPIAIJ(PetscObject obj)
216699817fSBarry Smith {
226699817fSBarry Smith   PC                pc = (PC) obj;
236699817fSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
2468e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data;
259da4b979SBarry Smith   int               ierr;
266699817fSBarry Smith 
279da4b979SBarry Smith   ierr = SLESDestroy(jac->sles[0]); CHKERRQ(ierr);
280452661fSBarry Smith   PetscFree(jac->sles);
296699817fSBarry Smith   ierr = VecDestroy(bjac->x); CHKERRQ(ierr);
30e2147057SSatish Balay   ierr = VecDestroy(bjac->y); CHKERRQ(ierr);
31b4fd4287SBarry Smith   if (jac->l_lens) PetscFree(jac->l_lens);
32b4fd4287SBarry Smith   if (jac->g_lens) PetscFree(jac->g_lens);
330452661fSBarry Smith   PetscFree(bjac); PetscFree(jac);
346699817fSBarry Smith   return 0;
356699817fSBarry Smith }
366699817fSBarry Smith 
376dea57deSBarry Smith 
3868e69f27SSatish Balay int PCSetUpOnBlocks_BJacobi_MPIAIJ(PC pc)
396dea57deSBarry Smith {
406dea57deSBarry Smith   int               ierr;
416dea57deSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
4268e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data;
436dea57deSBarry Smith 
446dea57deSBarry Smith   ierr = SLESSetUp(jac->sles[0],bjac->x,bjac->y); CHKERRQ(ierr);
456dea57deSBarry Smith   return 0;
466dea57deSBarry Smith }
476dea57deSBarry Smith 
4868e69f27SSatish Balay int PCApply_BJacobi_MPIAIJ(PC pc,Vec x, Vec y)
496699817fSBarry Smith {
506699817fSBarry Smith   int               ierr,its;
516699817fSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
5268e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data;
53e2147057SSatish Balay   Scalar            *x_array,*x_true_array, *y_array,*y_true_array;
546699817fSBarry Smith 
559da4b979SBarry Smith   /*
569da4b979SBarry Smith       The VecPlaceArray() is to avoid having to copy the
579da4b979SBarry Smith     y vector into the bjac->x vector. The reason for
589da4b979SBarry Smith     the bjac->x vector is that we need a sequential vector
599da4b979SBarry Smith     for the sequential solve.
609da4b979SBarry Smith   */
61*90f02eecSBarry Smith   VecGetArray_Fast(x,x_array);
62*90f02eecSBarry Smith   VecGetArray_Fast(y,y_array);
63*90f02eecSBarry Smith   VecGetArray_Fast(bjac->x,x_true_array);
64*90f02eecSBarry Smith   VecGetArray_Fast(bjac->y,y_true_array);
65*90f02eecSBarry Smith   VecPlaceArray_Fast(bjac->x,x_array);
66*90f02eecSBarry Smith   VecPlaceArray_Fast(bjac->y,y_array);
67*90f02eecSBarry Smith   ierr = SLESSolve(jac->sles[0],bjac->x,bjac->y,&its);
68*90f02eecSBarry Smith   VecPlaceArray_Fast(bjac->x,x_true_array);
69*90f02eecSBarry Smith   VecPlaceArray_Fast(bjac->y,y_true_array);
706699817fSBarry Smith   return 0;
716699817fSBarry Smith }
726699817fSBarry Smith 
7368e69f27SSatish Balay int PCSetUp_BJacobi_MPIAIJ(PC pc)
746699817fSBarry Smith {
756699817fSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
766699817fSBarry Smith   Mat               mat = pc->mat, pmat = pc->pmat;
776699817fSBarry Smith   Mat_MPIAIJ        *pmatin = (Mat_MPIAIJ *) pmat->data;
786699817fSBarry Smith   Mat_MPIAIJ        *matin = 0;
7963b91edcSBarry Smith   int               ierr, m;
806699817fSBarry Smith   SLES              sles;
81e2147057SSatish Balay   Vec               x,y;
8268e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac;
836699817fSBarry Smith   KSP               subksp;
846699817fSBarry Smith   PC                subpc;
856699817fSBarry Smith   MatType           type;
866699817fSBarry Smith 
876699817fSBarry Smith   if (jac->use_true_local) {
884b0e389bSBarry Smith     MatGetType(pc->mat,&type,PETSC_NULL);
8968e69f27SSatish Balay     if (type != MATMPIAIJ) SETERRQ(1,"PCSetUp_BJacobi_MPIAIJ:Incompatible matrix type.");
906699817fSBarry Smith     matin = (Mat_MPIAIJ *) mat->data;
916699817fSBarry Smith   }
926699817fSBarry Smith 
936699817fSBarry Smith   /* set default direct solver with no Krylov method */
946699817fSBarry Smith   if (!pc->setupcalled) {
95639f9d9dSBarry Smith     char *prefix;
966699817fSBarry Smith     ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr);
976699817fSBarry Smith     PLogObjectParent(pc,sles);
986699817fSBarry Smith     ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr);
994b0e389bSBarry Smith     ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr);
1006699817fSBarry Smith     ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr);
1013b90cdfbSSatish Balay     ierr = PCSetType(subpc,PCILU); CHKERRQ(ierr);
102639f9d9dSBarry Smith     ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
103639f9d9dSBarry Smith     ierr = SLESSetOptionsPrefix(sles,prefix); CHKERRQ(ierr);
104639f9d9dSBarry Smith     ierr = SLESAppendOptionsPrefix(sles,"sub_"); CHKERRQ(ierr);
1056699817fSBarry Smith     ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
1066699817fSBarry Smith /*
1076699817fSBarry Smith    This is not so good. The only reason we need to generate this vector
1086699817fSBarry Smith   is so KSP may generate seq vectors for the local solves
1096699817fSBarry Smith */
1106699817fSBarry Smith     ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr);
1116699817fSBarry Smith     ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr);
112e2147057SSatish Balay     ierr = VecCreateSeq(MPI_COMM_SELF,m,&y); CHKERRQ(ierr);
1136699817fSBarry Smith     PLogObjectParent(pmat,x);
114e2147057SSatish Balay     PLogObjectParent(pmat,y);
1156699817fSBarry Smith 
11668e69f27SSatish Balay     pc->destroy       = PCDestroy_BJacobi_MPIAIJ;
11768e69f27SSatish Balay     pc->apply         = PCApply_BJacobi_MPIAIJ;
11868e69f27SSatish Balay     pc->setuponblocks = PCSetUpOnBlocks_BJacobi_MPIAIJ;
1196699817fSBarry Smith 
12068e69f27SSatish Balay     bjac         = (PC_BJacobi_MPIAIJ *) PetscMalloc(sizeof(PC_BJacobi_MPIAIJ));CHKPTRQ(bjac);
12168e69f27SSatish Balay     PLogObjectMemory(pc,sizeof(PC_BJacobi_MPIAIJ));
1226699817fSBarry Smith     bjac->x      = x;
123e2147057SSatish Balay     bjac->y      = y;
1246699817fSBarry Smith 
1250452661fSBarry Smith     jac->sles    = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles);
1266699817fSBarry Smith     jac->sles[0] = sles;
1276699817fSBarry Smith     jac->data    = (void *) bjac;
1286699817fSBarry Smith   }
1296699817fSBarry Smith   else {
1306699817fSBarry Smith     sles = jac->sles[0];
13168e69f27SSatish Balay     bjac = (PC_BJacobi_MPIAIJ *)jac->data;
1326699817fSBarry Smith   }
133c915c865SSatish Balay   /* if (jac->l_true[0] == USE_TRUE_MATRIX) {
13449c46530SBarry Smith     ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag);
13549c46530SBarry Smith   }
136c915c865SSatish Balay   else */ if (jac->use_true_local)
1376699817fSBarry Smith     ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag);
1386699817fSBarry Smith   else
1396699817fSBarry Smith     ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag);
1406699817fSBarry Smith   CHKERRQ(ierr);
1416699817fSBarry Smith   return 0;
1426699817fSBarry Smith }
1436699817fSBarry Smith 
14402834360SBarry Smith 
145