16699817fSBarry Smith #ifndef lint 2*70f55243SBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.19 1996/08/05 22:55:04 balay 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 */ 10*70f55243SBarry Smith #include "src/mat/impls/aij/mpi/mpiaij.h" 1102834360SBarry Smith #include "src/pc/pcimpl.h" 1202834360SBarry Smith #include "src/pc/impls/bjacobi/bjacobi.h" 136699817fSBarry Smith #include "sles.h" 146699817fSBarry Smith 156699817fSBarry Smith typedef struct { 16e2147057SSatish Balay Vec x, y; 1768e69f27SSatish Balay } PC_BJacobi_MPIAIJ; 186699817fSBarry Smith 1968e69f27SSatish Balay int PCDestroy_BJacobi_MPIAIJ(PetscObject obj) 206699817fSBarry Smith { 216699817fSBarry Smith PC pc = (PC) obj; 226699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 2368e69f27SSatish Balay PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data; 249da4b979SBarry Smith int ierr; 256699817fSBarry Smith 269da4b979SBarry Smith ierr = SLESDestroy(jac->sles[0]); CHKERRQ(ierr); 270452661fSBarry Smith PetscFree(jac->sles); 286699817fSBarry Smith ierr = VecDestroy(bjac->x); CHKERRQ(ierr); 29e2147057SSatish Balay ierr = VecDestroy(bjac->y); CHKERRQ(ierr); 30b4fd4287SBarry Smith if (jac->l_lens) PetscFree(jac->l_lens); 31b4fd4287SBarry Smith if (jac->g_lens) PetscFree(jac->g_lens); 320452661fSBarry Smith PetscFree(bjac); PetscFree(jac); 336699817fSBarry Smith return 0; 346699817fSBarry Smith } 356699817fSBarry Smith 366dea57deSBarry Smith 3768e69f27SSatish Balay int PCSetUpOnBlocks_BJacobi_MPIAIJ(PC pc) 386dea57deSBarry Smith { 396dea57deSBarry Smith int ierr; 406dea57deSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 4168e69f27SSatish Balay PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data; 426dea57deSBarry Smith 436dea57deSBarry Smith ierr = SLESSetUp(jac->sles[0],bjac->x,bjac->y); CHKERRQ(ierr); 446dea57deSBarry Smith return 0; 456dea57deSBarry Smith } 466dea57deSBarry Smith 4768e69f27SSatish Balay int PCApply_BJacobi_MPIAIJ(PC pc,Vec x, Vec y) 486699817fSBarry Smith { 496699817fSBarry Smith int ierr,its; 506699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 5168e69f27SSatish Balay PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data; 52e2147057SSatish Balay Scalar *x_array,*x_true_array, *y_array,*y_true_array; 536699817fSBarry Smith 549da4b979SBarry Smith /* 559da4b979SBarry Smith The VecPlaceArray() is to avoid having to copy the 569da4b979SBarry Smith y vector into the bjac->x vector. The reason for 579da4b979SBarry Smith the bjac->x vector is that we need a sequential vector 589da4b979SBarry Smith for the sequential solve. 599da4b979SBarry Smith */ 60e2147057SSatish Balay ierr = VecGetArray(x,&x_array); CHKERRQ(ierr); 61e2147057SSatish Balay ierr = VecGetArray(y,&y_array); CHKERRQ(ierr); 62e2147057SSatish Balay ierr = VecGetArray(bjac->x,&x_true_array); CHKERRQ(ierr); 63e2147057SSatish Balay ierr = VecGetArray(bjac->y,&y_true_array); CHKERRQ(ierr); 64e2147057SSatish Balay ierr = VecPlaceArray(bjac->x,x_array); CHKERRQ(ierr); 65e2147057SSatish Balay ierr = VecPlaceArray(bjac->y,y_array); CHKERRQ(ierr); 66e2147057SSatish Balay ierr = SLESSolve(jac->sles[0],bjac->x,bjac->y,&its); CHKERRQ(ierr); 67e2147057SSatish Balay ierr = VecPlaceArray(bjac->x,x_true_array); CHKERRQ(ierr); 68e2147057SSatish Balay ierr = VecPlaceArray(bjac->y,y_true_array); CHKERRQ(ierr); 696699817fSBarry Smith return 0; 706699817fSBarry Smith } 716699817fSBarry Smith 7268e69f27SSatish Balay int PCSetUp_BJacobi_MPIAIJ(PC pc) 736699817fSBarry Smith { 746699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 756699817fSBarry Smith Mat mat = pc->mat, pmat = pc->pmat; 766699817fSBarry Smith Mat_MPIAIJ *pmatin = (Mat_MPIAIJ *) pmat->data; 776699817fSBarry Smith Mat_MPIAIJ *matin = 0; 7863b91edcSBarry Smith int ierr, m; 796699817fSBarry Smith SLES sles; 80e2147057SSatish Balay Vec x,y; 8168e69f27SSatish Balay PC_BJacobi_MPIAIJ *bjac; 826699817fSBarry Smith KSP subksp; 836699817fSBarry Smith PC subpc; 846699817fSBarry Smith MatType type; 856699817fSBarry Smith 866699817fSBarry Smith if (jac->use_true_local) { 874b0e389bSBarry Smith MatGetType(pc->mat,&type,PETSC_NULL); 8868e69f27SSatish Balay if (type != MATMPIAIJ) SETERRQ(1,"PCSetUp_BJacobi_MPIAIJ:Incompatible matrix type."); 896699817fSBarry Smith matin = (Mat_MPIAIJ *) mat->data; 906699817fSBarry Smith } 916699817fSBarry Smith 926699817fSBarry Smith /* set default direct solver with no Krylov method */ 936699817fSBarry Smith if (!pc->setupcalled) { 946699817fSBarry Smith ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr); 956699817fSBarry Smith PLogObjectParent(pc,sles); 966699817fSBarry Smith ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr); 974b0e389bSBarry Smith ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr); 986699817fSBarry Smith ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr); 993b90cdfbSSatish Balay ierr = PCSetType(subpc,PCILU); CHKERRQ(ierr); 1006daaf66cSBarry Smith ierr = SLESSetOptionsPrefix(sles,"sub_"); CHKERRQ(ierr); 1016699817fSBarry Smith ierr = SLESSetFromOptions(sles); CHKERRQ(ierr); 1026699817fSBarry Smith /* 1036699817fSBarry Smith This is not so good. The only reason we need to generate this vector 1046699817fSBarry Smith is so KSP may generate seq vectors for the local solves 1056699817fSBarry Smith */ 1066699817fSBarry Smith ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr); 1076699817fSBarry Smith ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr); 108e2147057SSatish Balay ierr = VecCreateSeq(MPI_COMM_SELF,m,&y); CHKERRQ(ierr); 1096699817fSBarry Smith PLogObjectParent(pmat,x); 110e2147057SSatish Balay PLogObjectParent(pmat,y); 1116699817fSBarry Smith 11268e69f27SSatish Balay pc->destroy = PCDestroy_BJacobi_MPIAIJ; 11368e69f27SSatish Balay pc->apply = PCApply_BJacobi_MPIAIJ; 11468e69f27SSatish Balay pc->setuponblocks = PCSetUpOnBlocks_BJacobi_MPIAIJ; 1156699817fSBarry Smith 11668e69f27SSatish Balay bjac = (PC_BJacobi_MPIAIJ *) PetscMalloc(sizeof(PC_BJacobi_MPIAIJ));CHKPTRQ(bjac); 11768e69f27SSatish Balay PLogObjectMemory(pc,sizeof(PC_BJacobi_MPIAIJ)); 1186699817fSBarry Smith bjac->x = x; 119e2147057SSatish Balay bjac->y = y; 1206699817fSBarry Smith 1210452661fSBarry Smith jac->sles = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles); 1226699817fSBarry Smith jac->sles[0] = sles; 1236699817fSBarry Smith jac->data = (void *) bjac; 1246699817fSBarry Smith } 1256699817fSBarry Smith else { 1266699817fSBarry Smith sles = jac->sles[0]; 12768e69f27SSatish Balay bjac = (PC_BJacobi_MPIAIJ *)jac->data; 1286699817fSBarry Smith } 129c915c865SSatish Balay /* if (jac->l_true[0] == USE_TRUE_MATRIX) { 13049c46530SBarry Smith ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag); 13149c46530SBarry Smith } 132c915c865SSatish Balay else */ if (jac->use_true_local) 1336699817fSBarry Smith ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag); 1346699817fSBarry Smith else 1356699817fSBarry Smith ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag); 1366699817fSBarry Smith CHKERRQ(ierr); 1376699817fSBarry Smith return 0; 1386699817fSBarry Smith } 1396699817fSBarry Smith 14002834360SBarry Smith 141