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