1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*d4bb536fSBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.31 1997/08/07 14:39:24 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__ 21*d4bb536fSBarry 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 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 405615d1e5SSatish Balay #undef __FUNC__ 415615d1e5SSatish 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 525615d1e5SSatish Balay #undef __FUNC__ 535615d1e5SSatish 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 795615d1e5SSatish Balay #undef __FUNC__ 805615d1e5SSatish 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; 104029af93fSBarry Smith ierr = SLESCreate(PETSC_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); 119029af93fSBarry Smith ierr = VecCreateSeq(PETSC_COMM_SELF,m,&x); CHKERRQ(ierr); 120029af93fSBarry Smith ierr = VecCreateSeq(PETSC_COMM_SELF,m,&y); CHKERRQ(ierr); 121a7111324SSatish Balay PLogObjectParent(pc,x); 122a7111324SSatish Balay PLogObjectParent(pc,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 } 1413914022bSBarry Smith if (jac->use_true_local) { 1423914022bSBarry Smith ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag); CHKERRQ(ierr); 1433914022bSBarry Smith } else { 1443914022bSBarry Smith ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag); CHKERRQ(ierr); 14549c46530SBarry Smith } 1466699817fSBarry Smith return 0; 1476699817fSBarry Smith } 1486699817fSBarry Smith 1493914022bSBarry Smith #undef __FUNC__ 1503914022bSBarry Smith #define __FUNC__ "PCSetUp_BJacobi_SeqAIJ" 1513914022bSBarry Smith int PCSetUp_BJacobi_SeqAIJ(PC pc) 1523914022bSBarry Smith { 1533914022bSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 1543914022bSBarry Smith Mat mat = pc->mat, pmat = pc->pmat; 1553914022bSBarry Smith int ierr, m; 1563914022bSBarry Smith SLES sles; 1573914022bSBarry Smith Vec x,y; 1583914022bSBarry Smith PC_BJacobi_MPIAIJ *bjac; 1593914022bSBarry Smith KSP subksp; 1603914022bSBarry Smith PC subpc; 1613914022bSBarry Smith MatType type; 1623914022bSBarry Smith 1633914022bSBarry Smith if (jac->use_true_local) { 1643914022bSBarry Smith MatGetType(mat,&type,PETSC_NULL); 1653914022bSBarry Smith if (type != MATSEQAIJ) SETERRQ(1,0,"Incompatible matrix type."); 1663914022bSBarry Smith } 1673914022bSBarry Smith 1683914022bSBarry Smith /* set default direct solver with no Krylov method */ 1693914022bSBarry Smith if (!pc->setupcalled) { 1703914022bSBarry Smith char *prefix; 1713914022bSBarry Smith ierr = SLESCreate(PETSC_COMM_SELF,&sles); CHKERRQ(ierr); 1723914022bSBarry Smith PLogObjectParent(pc,sles); 1733914022bSBarry Smith ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr); 1743914022bSBarry Smith ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr); 1753914022bSBarry Smith ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr); 1763914022bSBarry Smith ierr = PCSetType(subpc,PCILU); CHKERRQ(ierr); 1773914022bSBarry Smith ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); 1783914022bSBarry Smith ierr = SLESSetOptionsPrefix(sles,prefix); CHKERRQ(ierr); 1793914022bSBarry Smith ierr = SLESAppendOptionsPrefix(sles,"sub_"); CHKERRQ(ierr); 1803914022bSBarry Smith ierr = SLESSetFromOptions(sles); CHKERRQ(ierr); 1813914022bSBarry Smith /* 1823914022bSBarry Smith This is not so good. The only reason we need to generate this vector 1833914022bSBarry Smith is so KSP may generate seq vectors for the local solves 1843914022bSBarry Smith */ 1853914022bSBarry Smith ierr = MatGetSize(pmat,&m,&m); CHKERRQ(ierr); 1863914022bSBarry Smith ierr = VecCreateSeq(PETSC_COMM_SELF,m,&x); CHKERRQ(ierr); 1873914022bSBarry Smith ierr = VecCreateSeq(PETSC_COMM_SELF,m,&y); CHKERRQ(ierr); 1883914022bSBarry Smith PLogObjectParent(pc,x); 1893914022bSBarry Smith PLogObjectParent(pc,y); 1903914022bSBarry Smith 1913914022bSBarry Smith pc->destroy = PCDestroy_BJacobi_MPIAIJ; 1923914022bSBarry Smith pc->apply = PCApply_BJacobi_MPIAIJ; 1933914022bSBarry Smith pc->setuponblocks = PCSetUpOnBlocks_BJacobi_MPIAIJ; 1943914022bSBarry Smith 1953914022bSBarry Smith bjac = (PC_BJacobi_MPIAIJ *) PetscMalloc(sizeof(PC_BJacobi_MPIAIJ));CHKPTRQ(bjac); 1963914022bSBarry Smith PLogObjectMemory(pc,sizeof(PC_BJacobi_MPIAIJ)); 1973914022bSBarry Smith bjac->x = x; 1983914022bSBarry Smith bjac->y = y; 1993914022bSBarry Smith 2003914022bSBarry Smith jac->sles = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles); 2013914022bSBarry Smith jac->sles[0] = sles; 2023914022bSBarry Smith jac->data = (void *) bjac; 2033914022bSBarry Smith } 2043914022bSBarry Smith else { 2053914022bSBarry Smith sles = jac->sles[0]; 2063914022bSBarry Smith bjac = (PC_BJacobi_MPIAIJ *)jac->data; 2073914022bSBarry Smith } 2083914022bSBarry Smith if (jac->use_true_local) { 2093914022bSBarry Smith ierr = SLESSetOperators(sles,mat,pmat,pc->flag); CHKERRQ(ierr); 2103914022bSBarry Smith } else { 2113914022bSBarry Smith ierr = SLESSetOperators(sles,pmat,pmat,pc->flag); CHKERRQ(ierr); 2123914022bSBarry Smith } 2133914022bSBarry Smith return 0; 2143914022bSBarry Smith } 21502834360SBarry Smith 216