16699817fSBarry Smith #ifndef lint 2*02834360SBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.1 1995/10/04 03:24:11 bsmith Exp bsmith $"; 36699817fSBarry Smith #endif 46699817fSBarry Smith /* 56699817fSBarry Smith Defines a block Jacobi preconditioner for the MPIAIJ format. 66699817fSBarry Smith At the moment only supports a single block per processor. 76699817fSBarry Smith This file knows about storage formats for MPIAIJ matrices. 86699817fSBarry Smith This code is nearly identical to that for the MPIROW format; 96699817fSBarry Smith */ 10*02834360SBarry Smith #include "mpiaij.h" 11*02834360SBarry Smith #include "src/pc/pcimpl.h" 12*02834360SBarry Smith #include "src/pc/impls/bjacobi/bjacobi.h" 136699817fSBarry Smith #include "sles.h" 146699817fSBarry Smith 156699817fSBarry Smith typedef struct { 166699817fSBarry Smith Vec x; 176699817fSBarry Smith } PC_BJacobiMPIAIJ; 186699817fSBarry Smith 196699817fSBarry Smith int PCDestroy_BJacobiMPIAIJ(PetscObject obj) 206699817fSBarry Smith { 216699817fSBarry Smith PC pc = (PC) obj; 226699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 236699817fSBarry Smith PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data; 246699817fSBarry Smith int i,ierr; 256699817fSBarry Smith 266699817fSBarry Smith for ( i=0; i<jac->n_local; i++ ) { 276699817fSBarry Smith ierr = SLESDestroy(jac->sles[i]); CHKERRQ(ierr); 286699817fSBarry Smith } 296699817fSBarry Smith PETSCFREE(jac->sles); 306699817fSBarry Smith ierr = VecDestroy(bjac->x); CHKERRQ(ierr); 316699817fSBarry Smith PETSCFREE(bjac); PETSCFREE(jac); 326699817fSBarry Smith return 0; 336699817fSBarry Smith } 346699817fSBarry Smith 356699817fSBarry Smith int PCApply_BJacobiMPIAIJ(PC pc,Vec x, Vec y) 366699817fSBarry Smith { 376699817fSBarry Smith int ierr,its; 386699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 396699817fSBarry Smith PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data; 406699817fSBarry Smith 416699817fSBarry Smith ierr = SLESSolve(jac->sles[0],x,bjac->x,&its); CHKERRQ(ierr); 426699817fSBarry Smith ierr = VecCopy(bjac->x,y); CHKERRQ(ierr); 436699817fSBarry Smith return 0; 446699817fSBarry Smith } 456699817fSBarry Smith 466699817fSBarry Smith int PCSetUp_BJacobiMPIAIJ(PC pc) 476699817fSBarry Smith { 486699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 496699817fSBarry Smith Mat mat = pc->mat, pmat = pc->pmat; 506699817fSBarry Smith Mat_MPIAIJ *pmatin = (Mat_MPIAIJ *) pmat->data; 516699817fSBarry Smith Mat_MPIAIJ *matin = 0; 526699817fSBarry Smith int ierr, numtids = pmatin->numtids,m; 536699817fSBarry Smith SLES sles; 546699817fSBarry Smith Vec x; 556699817fSBarry Smith PC_BJacobiMPIAIJ *bjac; 566699817fSBarry Smith KSP subksp; 576699817fSBarry Smith PC subpc; 586699817fSBarry Smith MatType type; 596699817fSBarry Smith 606699817fSBarry Smith if (jac->use_true_local) { 616699817fSBarry Smith MatGetType(pc->mat,&type); 626699817fSBarry Smith if (type != MATMPIAIJ) SETERRQ(1,"PCSetUp_BJacobiMPIAIJ:Incompatible matrix type."); 636699817fSBarry Smith matin = (Mat_MPIAIJ *) mat->data; 646699817fSBarry Smith } 656699817fSBarry Smith 666699817fSBarry Smith if (numtids != jac->n) { 676699817fSBarry Smith SETERRQ(1,"PCSetUp_BJacobiMPIAIJ:Can do only 1 block per processor\n"); 686699817fSBarry Smith } 696699817fSBarry Smith 706699817fSBarry Smith /* set default direct solver with no Krylov method */ 716699817fSBarry Smith if (!pc->setupcalled) { 726699817fSBarry Smith ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr); 736699817fSBarry Smith PLogObjectParent(pc,sles); 746699817fSBarry Smith ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr); 756699817fSBarry Smith ierr = KSPSetMethod(subksp,KSPPREONLY); CHKERRQ(ierr); 766699817fSBarry Smith ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr); 776699817fSBarry Smith ierr = PCSetMethod(subpc,PCLU); CHKERRQ(ierr); 786699817fSBarry Smith ierr = SLESSetOptionsPrefix(sles,"-sub_"); CHKERRQ(ierr); 796699817fSBarry Smith ierr = SLESSetFromOptions(sles); CHKERRQ(ierr); 806699817fSBarry Smith /* 816699817fSBarry Smith This is not so good. The only reason we need to generate this vector 826699817fSBarry Smith is so KSP may generate seq vectors for the local solves 836699817fSBarry Smith */ 846699817fSBarry Smith ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr); 856699817fSBarry Smith ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr); 866699817fSBarry Smith PLogObjectParent(pmat,x); 876699817fSBarry Smith 886699817fSBarry Smith pc->destroy = PCDestroy_BJacobiMPIAIJ; 896699817fSBarry Smith pc->apply = PCApply_BJacobiMPIAIJ; 906699817fSBarry Smith 916699817fSBarry Smith bjac = (PC_BJacobiMPIAIJ *) PETSCMALLOC(sizeof(PC_BJacobiMPIAIJ)); 926699817fSBarry Smith CHKPTRQ(bjac); 936699817fSBarry Smith PLogObjectMemory(pc,sizeof(PC_BJacobiMPIAIJ)); 946699817fSBarry Smith bjac->x = x; 956699817fSBarry Smith 966699817fSBarry Smith jac->sles = (SLES*) PETSCMALLOC( sizeof(SLES) ); CHKPTRQ(jac->sles); 976699817fSBarry Smith jac->sles[0] = sles; 986699817fSBarry Smith jac->data = (void *) bjac; 996699817fSBarry Smith } 1006699817fSBarry Smith else { 1016699817fSBarry Smith sles = jac->sles[0]; 1026699817fSBarry Smith } 1036699817fSBarry Smith if (jac->use_true_local) 1046699817fSBarry Smith ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag); 1056699817fSBarry Smith else 1066699817fSBarry Smith ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag); 1076699817fSBarry Smith CHKERRQ(ierr); 1086699817fSBarry Smith 1096699817fSBarry Smith return 0; 1106699817fSBarry Smith } 1116699817fSBarry Smith 112*02834360SBarry Smith 113