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