xref: /petsc/src/mat/impls/aij/mpi/mpiaijpc.c (revision 5615d1e584023db9367fb782d85b1b4ebbb8df18)
16699817fSBarry Smith #ifndef lint
2*5615d1e5SSatish Balay static char vcid[] = "$Id: mpiaijpc.c,v 1.25 1997/01/01 03:37:44 bsmith Exp balay $";
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"
1290f02eecSBarry 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 
20*5615d1e5SSatish Balay #undef __FUNC__
21*5615d1e5SSatish Balay #define __FUNC__ "PCDestroy_BJacobi_MPIAIJ"
2268e69f27SSatish Balay int PCDestroy_BJacobi_MPIAIJ(PetscObject obj)
236699817fSBarry Smith {
246699817fSBarry Smith   PC                pc = (PC) obj;
256699817fSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
2668e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data;
279da4b979SBarry Smith   int               ierr;
286699817fSBarry Smith 
299da4b979SBarry Smith   ierr = SLESDestroy(jac->sles[0]); CHKERRQ(ierr);
300452661fSBarry Smith   PetscFree(jac->sles);
316699817fSBarry Smith   ierr = VecDestroy(bjac->x); CHKERRQ(ierr);
32e2147057SSatish Balay   ierr = VecDestroy(bjac->y); CHKERRQ(ierr);
33b4fd4287SBarry Smith   if (jac->l_lens) PetscFree(jac->l_lens);
34b4fd4287SBarry Smith   if (jac->g_lens) PetscFree(jac->g_lens);
350452661fSBarry Smith   PetscFree(bjac); PetscFree(jac);
366699817fSBarry Smith   return 0;
376699817fSBarry Smith }
386699817fSBarry Smith 
396dea57deSBarry Smith 
40*5615d1e5SSatish Balay #undef __FUNC__
41*5615d1e5SSatish Balay #define __FUNC__ "PCSetUpOnBlocks_BJacobi_MPIAIJ"
4268e69f27SSatish Balay int PCSetUpOnBlocks_BJacobi_MPIAIJ(PC pc)
436dea57deSBarry Smith {
446dea57deSBarry Smith   int               ierr;
456dea57deSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
4668e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data;
476dea57deSBarry Smith 
486dea57deSBarry Smith   ierr = SLESSetUp(jac->sles[0],bjac->x,bjac->y); CHKERRQ(ierr);
496dea57deSBarry Smith   return 0;
506dea57deSBarry Smith }
516dea57deSBarry Smith 
52*5615d1e5SSatish Balay #undef __FUNC__
53*5615d1e5SSatish Balay #define __FUNC__ "PCApply_BJacobi_MPIAIJ"
5468e69f27SSatish Balay int PCApply_BJacobi_MPIAIJ(PC pc,Vec x, Vec y)
556699817fSBarry Smith {
566699817fSBarry Smith   int               ierr,its;
576699817fSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
5868e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data;
59e2147057SSatish Balay   Scalar            *x_array,*x_true_array, *y_array,*y_true_array;
606699817fSBarry Smith 
619da4b979SBarry Smith   /*
629da4b979SBarry Smith       The VecPlaceArray() is to avoid having to copy the
639da4b979SBarry Smith     y vector into the bjac->x vector. The reason for
649da4b979SBarry Smith     the bjac->x vector is that we need a sequential vector
659da4b979SBarry Smith     for the sequential solve.
669da4b979SBarry Smith   */
6790f02eecSBarry Smith   VecGetArray_Fast(x,x_array);
6890f02eecSBarry Smith   VecGetArray_Fast(y,y_array);
6990f02eecSBarry Smith   VecGetArray_Fast(bjac->x,x_true_array);
7090f02eecSBarry Smith   VecGetArray_Fast(bjac->y,y_true_array);
7190f02eecSBarry Smith   VecPlaceArray_Fast(bjac->x,x_array);
7290f02eecSBarry Smith   VecPlaceArray_Fast(bjac->y,y_array);
7390f02eecSBarry Smith   ierr = SLESSolve(jac->sles[0],bjac->x,bjac->y,&its);
7490f02eecSBarry Smith   VecPlaceArray_Fast(bjac->x,x_true_array);
7590f02eecSBarry Smith   VecPlaceArray_Fast(bjac->y,y_true_array);
766699817fSBarry Smith   return 0;
776699817fSBarry Smith }
786699817fSBarry Smith 
79*5615d1e5SSatish Balay #undef __FUNC__
80*5615d1e5SSatish Balay #define __FUNC__ "PCSetUp_BJacobi_MPIAIJ"
8168e69f27SSatish Balay int PCSetUp_BJacobi_MPIAIJ(PC pc)
826699817fSBarry Smith {
836699817fSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
846699817fSBarry Smith   Mat               mat = pc->mat, pmat = pc->pmat;
856699817fSBarry Smith   Mat_MPIAIJ        *pmatin = (Mat_MPIAIJ *) pmat->data;
866699817fSBarry Smith   Mat_MPIAIJ        *matin = 0;
8763b91edcSBarry Smith   int               ierr, m;
886699817fSBarry Smith   SLES              sles;
89e2147057SSatish Balay   Vec               x,y;
9068e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac;
916699817fSBarry Smith   KSP               subksp;
926699817fSBarry Smith   PC                subpc;
936699817fSBarry Smith   MatType           type;
946699817fSBarry Smith 
956699817fSBarry Smith   if (jac->use_true_local) {
964b0e389bSBarry Smith     MatGetType(pc->mat,&type,PETSC_NULL);
97e3372554SBarry Smith     if (type != MATMPIAIJ) SETERRQ(1,0,"Incompatible matrix type.");
986699817fSBarry Smith     matin = (Mat_MPIAIJ *) mat->data;
996699817fSBarry Smith   }
1006699817fSBarry Smith 
1016699817fSBarry Smith   /* set default direct solver with no Krylov method */
1026699817fSBarry Smith   if (!pc->setupcalled) {
103639f9d9dSBarry Smith     char *prefix;
1046699817fSBarry Smith     ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr);
1056699817fSBarry Smith     PLogObjectParent(pc,sles);
1066699817fSBarry Smith     ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr);
1074b0e389bSBarry Smith     ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr);
1086699817fSBarry Smith     ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr);
1093b90cdfbSSatish Balay     ierr = PCSetType(subpc,PCILU); CHKERRQ(ierr);
110639f9d9dSBarry Smith     ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
111639f9d9dSBarry Smith     ierr = SLESSetOptionsPrefix(sles,prefix); CHKERRQ(ierr);
112639f9d9dSBarry Smith     ierr = SLESAppendOptionsPrefix(sles,"sub_"); CHKERRQ(ierr);
1136699817fSBarry Smith     ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
1146699817fSBarry Smith /*
1156699817fSBarry Smith    This is not so good. The only reason we need to generate this vector
1166699817fSBarry Smith   is so KSP may generate seq vectors for the local solves
1176699817fSBarry Smith */
1186699817fSBarry Smith     ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr);
1196699817fSBarry Smith     ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr);
120e2147057SSatish Balay     ierr = VecCreateSeq(MPI_COMM_SELF,m,&y); CHKERRQ(ierr);
1216699817fSBarry Smith     PLogObjectParent(pmat,x);
122e2147057SSatish Balay     PLogObjectParent(pmat,y);
1236699817fSBarry Smith 
12468e69f27SSatish Balay     pc->destroy       = PCDestroy_BJacobi_MPIAIJ;
12568e69f27SSatish Balay     pc->apply         = PCApply_BJacobi_MPIAIJ;
12668e69f27SSatish Balay     pc->setuponblocks = PCSetUpOnBlocks_BJacobi_MPIAIJ;
1276699817fSBarry Smith 
12868e69f27SSatish Balay     bjac         = (PC_BJacobi_MPIAIJ *) PetscMalloc(sizeof(PC_BJacobi_MPIAIJ));CHKPTRQ(bjac);
12968e69f27SSatish Balay     PLogObjectMemory(pc,sizeof(PC_BJacobi_MPIAIJ));
1306699817fSBarry Smith     bjac->x      = x;
131e2147057SSatish Balay     bjac->y      = y;
1326699817fSBarry Smith 
1330452661fSBarry Smith     jac->sles    = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles);
1346699817fSBarry Smith     jac->sles[0] = sles;
1356699817fSBarry Smith     jac->data    = (void *) bjac;
1366699817fSBarry Smith   }
1376699817fSBarry Smith   else {
1386699817fSBarry Smith     sles = jac->sles[0];
13968e69f27SSatish Balay     bjac = (PC_BJacobi_MPIAIJ *)jac->data;
1406699817fSBarry Smith   }
141c915c865SSatish Balay   /* if (jac->l_true[0] == USE_TRUE_MATRIX) {
14249c46530SBarry Smith     ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag);
14349c46530SBarry Smith   }
144c915c865SSatish Balay   else */ if (jac->use_true_local)
1456699817fSBarry Smith     ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag);
1466699817fSBarry Smith   else
1476699817fSBarry Smith     ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag);
1486699817fSBarry Smith   CHKERRQ(ierr);
1496699817fSBarry Smith   return 0;
1506699817fSBarry Smith }
1516699817fSBarry Smith 
15202834360SBarry Smith 
153