xref: /petsc/src/mat/impls/aij/mpi/mpiaijpc.c (revision 3a40ed3dce77c081171d005ae1a6ff4bb9d13b6f)
1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER
2*3a40ed3dSBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.32 1997/08/22 15:13:39 bsmith Exp bsmith $";
36699817fSBarry Smith #endif
46699817fSBarry Smith /*
53914022bSBarry Smith    Defines a block Jacobi preconditioner for the SeqAIJ/MPIAIJ format.
69da4b979SBarry Smith    Handles special case of  single block per processor.
73914022bSBarry Smith    This file knows about storage formats for SeqMPI/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 
205615d1e5SSatish Balay #undef __FUNC__
21d4bb536fSBarry Smith #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 
29*3a40ed3dSBarry Smith   PetscFunctionBegin;
309da4b979SBarry Smith   ierr = SLESDestroy(jac->sles[0]); CHKERRQ(ierr);
310452661fSBarry Smith   PetscFree(jac->sles);
326699817fSBarry Smith   ierr = VecDestroy(bjac->x); CHKERRQ(ierr);
33e2147057SSatish Balay   ierr = VecDestroy(bjac->y); CHKERRQ(ierr);
34b4fd4287SBarry Smith   if (jac->l_lens) PetscFree(jac->l_lens);
35b4fd4287SBarry Smith   if (jac->g_lens) PetscFree(jac->g_lens);
360452661fSBarry Smith   PetscFree(bjac); PetscFree(jac);
37*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
386699817fSBarry Smith }
396699817fSBarry Smith 
406dea57deSBarry Smith 
415615d1e5SSatish Balay #undef __FUNC__
425615d1e5SSatish Balay #define __FUNC__ "PCSetUpOnBlocks_BJacobi_MPIAIJ"
4368e69f27SSatish Balay int PCSetUpOnBlocks_BJacobi_MPIAIJ(PC pc)
446dea57deSBarry Smith {
456dea57deSBarry Smith   int               ierr;
466dea57deSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
4768e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data;
486dea57deSBarry Smith 
49*3a40ed3dSBarry Smith   PetscFunctionBegin;
506dea57deSBarry Smith   ierr = SLESSetUp(jac->sles[0],bjac->x,bjac->y); CHKERRQ(ierr);
51*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
526dea57deSBarry Smith }
536dea57deSBarry Smith 
545615d1e5SSatish Balay #undef __FUNC__
555615d1e5SSatish Balay #define __FUNC__ "PCApply_BJacobi_MPIAIJ"
5668e69f27SSatish Balay int PCApply_BJacobi_MPIAIJ(PC pc,Vec x, Vec y)
576699817fSBarry Smith {
586699817fSBarry Smith   int               ierr,its;
596699817fSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
6068e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data;
61e2147057SSatish Balay   Scalar            *x_array,*x_true_array, *y_array,*y_true_array;
626699817fSBarry Smith 
63*3a40ed3dSBarry Smith   PetscFunctionBegin;
649da4b979SBarry Smith   /*
659da4b979SBarry Smith       The VecPlaceArray() is to avoid having to copy the
669da4b979SBarry Smith     y vector into the bjac->x vector. The reason for
679da4b979SBarry Smith     the bjac->x vector is that we need a sequential vector
689da4b979SBarry Smith     for the sequential solve.
699da4b979SBarry Smith   */
7090f02eecSBarry Smith   VecGetArray_Fast(x,x_array);
7190f02eecSBarry Smith   VecGetArray_Fast(y,y_array);
7290f02eecSBarry Smith   VecGetArray_Fast(bjac->x,x_true_array);
7390f02eecSBarry Smith   VecGetArray_Fast(bjac->y,y_true_array);
7490f02eecSBarry Smith   VecPlaceArray_Fast(bjac->x,x_array);
7590f02eecSBarry Smith   VecPlaceArray_Fast(bjac->y,y_array);
7690f02eecSBarry Smith   ierr = SLESSolve(jac->sles[0],bjac->x,bjac->y,&its);
7790f02eecSBarry Smith   VecPlaceArray_Fast(bjac->x,x_true_array);
7890f02eecSBarry Smith   VecPlaceArray_Fast(bjac->y,y_true_array);
79*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
806699817fSBarry Smith }
816699817fSBarry Smith 
825615d1e5SSatish Balay #undef __FUNC__
835615d1e5SSatish Balay #define __FUNC__ "PCSetUp_BJacobi_MPIAIJ"
8468e69f27SSatish Balay int PCSetUp_BJacobi_MPIAIJ(PC pc)
856699817fSBarry Smith {
866699817fSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
876699817fSBarry Smith   Mat               mat = pc->mat, pmat = pc->pmat;
886699817fSBarry Smith   Mat_MPIAIJ        *pmatin = (Mat_MPIAIJ *) pmat->data;
896699817fSBarry Smith   Mat_MPIAIJ        *matin = 0;
9063b91edcSBarry Smith   int               ierr, m;
916699817fSBarry Smith   SLES              sles;
92e2147057SSatish Balay   Vec               x,y;
9368e69f27SSatish Balay   PC_BJacobi_MPIAIJ *bjac;
946699817fSBarry Smith   KSP               subksp;
956699817fSBarry Smith   PC                subpc;
966699817fSBarry Smith   MatType           type;
976699817fSBarry Smith 
98*3a40ed3dSBarry Smith   PetscFunctionBegin;
996699817fSBarry Smith   if (jac->use_true_local) {
1004b0e389bSBarry Smith     MatGetType(pc->mat,&type,PETSC_NULL);
101e3372554SBarry Smith     if (type != MATMPIAIJ) SETERRQ(1,0,"Incompatible matrix type.");
1026699817fSBarry Smith     matin = (Mat_MPIAIJ *) mat->data;
1036699817fSBarry Smith   }
1046699817fSBarry Smith 
1056699817fSBarry Smith   /* set default direct solver with no Krylov method */
1066699817fSBarry Smith   if (!pc->setupcalled) {
107639f9d9dSBarry Smith     char *prefix;
108029af93fSBarry Smith     ierr = SLESCreate(PETSC_COMM_SELF,&sles); CHKERRQ(ierr);
1096699817fSBarry Smith     PLogObjectParent(pc,sles);
1106699817fSBarry Smith     ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr);
1114b0e389bSBarry Smith     ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr);
1126699817fSBarry Smith     ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr);
1133b90cdfbSSatish Balay     ierr = PCSetType(subpc,PCILU); CHKERRQ(ierr);
114639f9d9dSBarry Smith     ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
115639f9d9dSBarry Smith     ierr = SLESSetOptionsPrefix(sles,prefix); CHKERRQ(ierr);
116639f9d9dSBarry Smith     ierr = SLESAppendOptionsPrefix(sles,"sub_"); CHKERRQ(ierr);
1176699817fSBarry Smith     ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
1186699817fSBarry Smith /*
1196699817fSBarry Smith    This is not so good. The only reason we need to generate this vector
1206699817fSBarry Smith   is so KSP may generate seq vectors for the local solves
1216699817fSBarry Smith */
1226699817fSBarry Smith     ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr);
123029af93fSBarry Smith     ierr = VecCreateSeq(PETSC_COMM_SELF,m,&x); CHKERRQ(ierr);
124029af93fSBarry Smith     ierr = VecCreateSeq(PETSC_COMM_SELF,m,&y); CHKERRQ(ierr);
125a7111324SSatish Balay     PLogObjectParent(pc,x);
126a7111324SSatish Balay     PLogObjectParent(pc,y);
1276699817fSBarry Smith 
12868e69f27SSatish Balay     pc->destroy       = PCDestroy_BJacobi_MPIAIJ;
12968e69f27SSatish Balay     pc->apply         = PCApply_BJacobi_MPIAIJ;
13068e69f27SSatish Balay     pc->setuponblocks = PCSetUpOnBlocks_BJacobi_MPIAIJ;
1316699817fSBarry Smith 
13268e69f27SSatish Balay     bjac         = (PC_BJacobi_MPIAIJ *) PetscMalloc(sizeof(PC_BJacobi_MPIAIJ));CHKPTRQ(bjac);
13368e69f27SSatish Balay     PLogObjectMemory(pc,sizeof(PC_BJacobi_MPIAIJ));
1346699817fSBarry Smith     bjac->x      = x;
135e2147057SSatish Balay     bjac->y      = y;
1366699817fSBarry Smith 
1370452661fSBarry Smith     jac->sles    = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles);
1386699817fSBarry Smith     jac->sles[0] = sles;
1396699817fSBarry Smith     jac->data    = (void *) bjac;
140*3a40ed3dSBarry Smith   } else {
1416699817fSBarry Smith     sles = jac->sles[0];
14268e69f27SSatish Balay     bjac = (PC_BJacobi_MPIAIJ *)jac->data;
1436699817fSBarry Smith   }
1443914022bSBarry Smith   if (jac->use_true_local) {
1453914022bSBarry Smith     ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag); CHKERRQ(ierr);
1463914022bSBarry Smith   }  else {
1473914022bSBarry Smith     ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag); CHKERRQ(ierr);
14849c46530SBarry Smith   }
149*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
1506699817fSBarry Smith }
1516699817fSBarry Smith 
1523914022bSBarry Smith #undef __FUNC__
1533914022bSBarry Smith #define __FUNC__ "PCSetUp_BJacobi_SeqAIJ"
1543914022bSBarry Smith int PCSetUp_BJacobi_SeqAIJ(PC pc)
1553914022bSBarry Smith {
1563914022bSBarry Smith   PC_BJacobi        *jac = (PC_BJacobi *) pc->data;
1573914022bSBarry Smith   Mat               mat = pc->mat, pmat = pc->pmat;
1583914022bSBarry Smith   int               ierr, m;
1593914022bSBarry Smith   SLES              sles;
1603914022bSBarry Smith   Vec               x,y;
1613914022bSBarry Smith   PC_BJacobi_MPIAIJ *bjac;
1623914022bSBarry Smith   KSP               subksp;
1633914022bSBarry Smith   PC                subpc;
1643914022bSBarry Smith   MatType           type;
1653914022bSBarry Smith 
166*3a40ed3dSBarry Smith   PetscFunctionBegin;
1673914022bSBarry Smith   if (jac->use_true_local) {
1683914022bSBarry Smith     MatGetType(mat,&type,PETSC_NULL);
1693914022bSBarry Smith     if (type != MATSEQAIJ) SETERRQ(1,0,"Incompatible matrix type.");
1703914022bSBarry Smith   }
1713914022bSBarry Smith 
1723914022bSBarry Smith   /* set default direct solver with no Krylov method */
1733914022bSBarry Smith   if (!pc->setupcalled) {
1743914022bSBarry Smith     char *prefix;
1753914022bSBarry Smith     ierr = SLESCreate(PETSC_COMM_SELF,&sles); CHKERRQ(ierr);
1763914022bSBarry Smith     PLogObjectParent(pc,sles);
1773914022bSBarry Smith     ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr);
1783914022bSBarry Smith     ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr);
1793914022bSBarry Smith     ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr);
1803914022bSBarry Smith     ierr = PCSetType(subpc,PCILU); CHKERRQ(ierr);
1813914022bSBarry Smith     ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
1823914022bSBarry Smith     ierr = SLESSetOptionsPrefix(sles,prefix); CHKERRQ(ierr);
1833914022bSBarry Smith     ierr = SLESAppendOptionsPrefix(sles,"sub_"); CHKERRQ(ierr);
1843914022bSBarry Smith     ierr = SLESSetFromOptions(sles); CHKERRQ(ierr);
1853914022bSBarry Smith /*
1863914022bSBarry Smith    This is not so good. The only reason we need to generate this vector
1873914022bSBarry Smith   is so KSP may generate seq vectors for the local solves
1883914022bSBarry Smith */
1893914022bSBarry Smith     ierr = MatGetSize(pmat,&m,&m); CHKERRQ(ierr);
1903914022bSBarry Smith     ierr = VecCreateSeq(PETSC_COMM_SELF,m,&x); CHKERRQ(ierr);
1913914022bSBarry Smith     ierr = VecCreateSeq(PETSC_COMM_SELF,m,&y); CHKERRQ(ierr);
1923914022bSBarry Smith     PLogObjectParent(pc,x);
1933914022bSBarry Smith     PLogObjectParent(pc,y);
1943914022bSBarry Smith 
1953914022bSBarry Smith     pc->destroy       = PCDestroy_BJacobi_MPIAIJ;
1963914022bSBarry Smith     pc->apply         = PCApply_BJacobi_MPIAIJ;
1973914022bSBarry Smith     pc->setuponblocks = PCSetUpOnBlocks_BJacobi_MPIAIJ;
1983914022bSBarry Smith 
1993914022bSBarry Smith     bjac         = (PC_BJacobi_MPIAIJ *) PetscMalloc(sizeof(PC_BJacobi_MPIAIJ));CHKPTRQ(bjac);
2003914022bSBarry Smith     PLogObjectMemory(pc,sizeof(PC_BJacobi_MPIAIJ));
2013914022bSBarry Smith     bjac->x      = x;
2023914022bSBarry Smith     bjac->y      = y;
2033914022bSBarry Smith 
2043914022bSBarry Smith     jac->sles    = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles);
2053914022bSBarry Smith     jac->sles[0] = sles;
2063914022bSBarry Smith     jac->data    = (void *) bjac;
207*3a40ed3dSBarry Smith   } else {
2083914022bSBarry Smith     sles = jac->sles[0];
2093914022bSBarry Smith     bjac = (PC_BJacobi_MPIAIJ *)jac->data;
2103914022bSBarry Smith   }
2113914022bSBarry Smith   if (jac->use_true_local) {
2123914022bSBarry Smith     ierr = SLESSetOperators(sles,mat,pmat,pc->flag); CHKERRQ(ierr);
2133914022bSBarry Smith   }  else {
2143914022bSBarry Smith     ierr = SLESSetOperators(sles,pmat,pmat,pc->flag); CHKERRQ(ierr);
2153914022bSBarry Smith   }
216*3a40ed3dSBarry Smith   PetscFunctionReturn(0);
2173914022bSBarry Smith }
21802834360SBarry Smith 
219