16699817fSBarry Smith #ifndef lint 2*e5c453d8SLois Curfman McInnes static char vcid[] = "$Id: mpiaijpc.c,v 1.13 1996/02/24 19:49:30 balay Exp curfman $"; 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 */ 1002834360SBarry Smith #include "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; 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; 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); 32b4fd4287SBarry Smith if (jac->l_true) PetscFree(jac->l_true); 33b4fd4287SBarry Smith if (jac->g_true) PetscFree(jac->g_true); 340452661fSBarry Smith PetscFree(bjac); PetscFree(jac); 356699817fSBarry Smith return 0; 366699817fSBarry Smith } 376699817fSBarry Smith 386699817fSBarry Smith int PCApply_BJacobiMPIAIJ(PC pc,Vec x, Vec y) 396699817fSBarry Smith { 406699817fSBarry Smith int ierr,its; 416699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 426699817fSBarry Smith PC_BJacobiMPIAIJ *bjac = (PC_BJacobiMPIAIJ *) jac->data; 43e2147057SSatish Balay Scalar *x_array,*x_true_array, *y_array,*y_true_array; 446699817fSBarry Smith 459da4b979SBarry Smith /* 469da4b979SBarry Smith The VecPlaceArray() is to avoid having to copy the 479da4b979SBarry Smith y vector into the bjac->x vector. The reason for 489da4b979SBarry Smith the bjac->x vector is that we need a sequential vector 499da4b979SBarry Smith for the sequential solve. 509da4b979SBarry Smith */ 51e2147057SSatish Balay ierr = VecGetArray(x,&x_array); CHKERRQ(ierr); 52e2147057SSatish Balay ierr = VecGetArray(y,&y_array); CHKERRQ(ierr); 53e2147057SSatish Balay ierr = VecGetArray(bjac->x,&x_true_array); CHKERRQ(ierr); 54e2147057SSatish Balay ierr = VecGetArray(bjac->y,&y_true_array); CHKERRQ(ierr); 55e2147057SSatish Balay ierr = VecPlaceArray(bjac->x,x_array); CHKERRQ(ierr); 56e2147057SSatish Balay ierr = VecPlaceArray(bjac->y,y_array); CHKERRQ(ierr); 57e2147057SSatish Balay ierr = SLESSolve(jac->sles[0],bjac->x,bjac->y,&its); CHKERRQ(ierr); 58e2147057SSatish Balay ierr = VecPlaceArray(bjac->x,x_true_array); CHKERRQ(ierr); 59e2147057SSatish Balay ierr = VecPlaceArray(bjac->y,y_true_array); CHKERRQ(ierr); 609da4b979SBarry Smith 616699817fSBarry Smith return 0; 626699817fSBarry Smith } 636699817fSBarry Smith 646699817fSBarry Smith int PCSetUp_BJacobiMPIAIJ(PC pc) 656699817fSBarry Smith { 666699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 676699817fSBarry Smith Mat mat = pc->mat, pmat = pc->pmat; 686699817fSBarry Smith Mat_MPIAIJ *pmatin = (Mat_MPIAIJ *) pmat->data; 696699817fSBarry Smith Mat_MPIAIJ *matin = 0; 7063b91edcSBarry Smith int ierr, m; 716699817fSBarry Smith SLES sles; 72e2147057SSatish Balay Vec x,y; 736699817fSBarry Smith PC_BJacobiMPIAIJ *bjac; 746699817fSBarry Smith KSP subksp; 756699817fSBarry Smith PC subpc; 766699817fSBarry Smith MatType type; 776699817fSBarry Smith 786699817fSBarry Smith if (jac->use_true_local) { 794b0e389bSBarry Smith MatGetType(pc->mat,&type,PETSC_NULL); 806699817fSBarry Smith if (type != MATMPIAIJ) SETERRQ(1,"PCSetUp_BJacobiMPIAIJ:Incompatible matrix type."); 816699817fSBarry Smith matin = (Mat_MPIAIJ *) mat->data; 826699817fSBarry Smith } 836699817fSBarry Smith 846699817fSBarry Smith /* set default direct solver with no Krylov method */ 856699817fSBarry Smith if (!pc->setupcalled) { 866699817fSBarry Smith ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr); 876699817fSBarry Smith PLogObjectParent(pc,sles); 886699817fSBarry Smith ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr); 894b0e389bSBarry Smith ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr); 906699817fSBarry Smith ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr); 914b0e389bSBarry Smith ierr = PCSetType(subpc,PCLU); CHKERRQ(ierr); 926daaf66cSBarry Smith ierr = SLESSetOptionsPrefix(sles,"sub_"); CHKERRQ(ierr); 936699817fSBarry Smith ierr = SLESSetFromOptions(sles); CHKERRQ(ierr); 946699817fSBarry Smith /* 956699817fSBarry Smith This is not so good. The only reason we need to generate this vector 966699817fSBarry Smith is so KSP may generate seq vectors for the local solves 976699817fSBarry Smith */ 986699817fSBarry Smith ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr); 996699817fSBarry Smith ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr); 100e2147057SSatish Balay ierr = VecCreateSeq(MPI_COMM_SELF,m,&y); CHKERRQ(ierr); 1016699817fSBarry Smith PLogObjectParent(pmat,x); 102e2147057SSatish Balay PLogObjectParent(pmat,y); 1036699817fSBarry Smith 1046699817fSBarry Smith pc->destroy = PCDestroy_BJacobiMPIAIJ; 1056699817fSBarry Smith pc->apply = PCApply_BJacobiMPIAIJ; 1066699817fSBarry Smith 10749c46530SBarry Smith bjac = (PC_BJacobiMPIAIJ *) PetscMalloc(sizeof(PC_BJacobiMPIAIJ));CHKPTRQ(bjac); 1086699817fSBarry Smith PLogObjectMemory(pc,sizeof(PC_BJacobiMPIAIJ)); 1096699817fSBarry Smith bjac->x = x; 110e2147057SSatish Balay bjac->y = y; 1116699817fSBarry Smith 1120452661fSBarry Smith jac->sles = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles); 1136699817fSBarry Smith jac->sles[0] = sles; 1146699817fSBarry Smith jac->data = (void *) bjac; 1156699817fSBarry Smith } 1166699817fSBarry Smith else { 1176699817fSBarry Smith sles = jac->sles[0]; 118*e5c453d8SLois Curfman McInnes bjac = (PC_BJacobiMPIAIJ *)jac->data; 1196699817fSBarry Smith } 12049c46530SBarry Smith if (jac->l_true[0] == USE_TRUE_MATRIX) { 12149c46530SBarry Smith ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag); 12249c46530SBarry Smith } 12349c46530SBarry Smith else if (jac->use_true_local) 1246699817fSBarry Smith ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag); 1256699817fSBarry Smith else 1266699817fSBarry Smith ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag); 1276699817fSBarry Smith CHKERRQ(ierr); 128e2147057SSatish Balay ierr = SLESSetUp(sles,bjac->x,bjac->y); CHKERRQ(ierr); 1296699817fSBarry Smith return 0; 1306699817fSBarry Smith } 1316699817fSBarry Smith 13202834360SBarry Smith 133