16699817fSBarry Smith #ifndef lint 2*68e69f27SSatish Balay static char vcid[] = "$Id: mpiaijpc.c,v 1.16 1996/07/03 16:49:22 balay Exp balay $"; 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; 17*68e69f27SSatish Balay } PC_BJacobi_MPIAIJ; 186699817fSBarry Smith 19*68e69f27SSatish Balay int PCDestroy_BJacobi_MPIAIJ(PetscObject obj) 206699817fSBarry Smith { 216699817fSBarry Smith PC pc = (PC) obj; 226699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 23*68e69f27SSatish 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); 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 386dea57deSBarry Smith 39*68e69f27SSatish Balay int PCSetUpOnBlocks_BJacobi_MPIAIJ(PC pc) 406dea57deSBarry Smith { 416dea57deSBarry Smith int ierr; 426dea57deSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 43*68e69f27SSatish Balay PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data; 446dea57deSBarry Smith 456dea57deSBarry Smith ierr = SLESSetUp(jac->sles[0],bjac->x,bjac->y); CHKERRQ(ierr); 466dea57deSBarry Smith return 0; 476dea57deSBarry Smith } 486dea57deSBarry Smith 49*68e69f27SSatish Balay int PCApply_BJacobi_MPIAIJ(PC pc,Vec x, Vec y) 506699817fSBarry Smith { 516699817fSBarry Smith int ierr,its; 526699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 53*68e69f27SSatish Balay PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data; 54e2147057SSatish Balay Scalar *x_array,*x_true_array, *y_array,*y_true_array; 556699817fSBarry Smith 569da4b979SBarry Smith /* 579da4b979SBarry Smith The VecPlaceArray() is to avoid having to copy the 589da4b979SBarry Smith y vector into the bjac->x vector. The reason for 599da4b979SBarry Smith the bjac->x vector is that we need a sequential vector 609da4b979SBarry Smith for the sequential solve. 619da4b979SBarry Smith */ 62e2147057SSatish Balay ierr = VecGetArray(x,&x_array); CHKERRQ(ierr); 63e2147057SSatish Balay ierr = VecGetArray(y,&y_array); CHKERRQ(ierr); 64e2147057SSatish Balay ierr = VecGetArray(bjac->x,&x_true_array); CHKERRQ(ierr); 65e2147057SSatish Balay ierr = VecGetArray(bjac->y,&y_true_array); CHKERRQ(ierr); 66e2147057SSatish Balay ierr = VecPlaceArray(bjac->x,x_array); CHKERRQ(ierr); 67e2147057SSatish Balay ierr = VecPlaceArray(bjac->y,y_array); CHKERRQ(ierr); 68e2147057SSatish Balay ierr = SLESSolve(jac->sles[0],bjac->x,bjac->y,&its); CHKERRQ(ierr); 69e2147057SSatish Balay ierr = VecPlaceArray(bjac->x,x_true_array); CHKERRQ(ierr); 70e2147057SSatish Balay ierr = VecPlaceArray(bjac->y,y_true_array); CHKERRQ(ierr); 716699817fSBarry Smith return 0; 726699817fSBarry Smith } 736699817fSBarry Smith 74*68e69f27SSatish Balay int PCSetUp_BJacobi_MPIAIJ(PC pc) 756699817fSBarry Smith { 766699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 776699817fSBarry Smith Mat mat = pc->mat, pmat = pc->pmat; 786699817fSBarry Smith Mat_MPIAIJ *pmatin = (Mat_MPIAIJ *) pmat->data; 796699817fSBarry Smith Mat_MPIAIJ *matin = 0; 8063b91edcSBarry Smith int ierr, m; 816699817fSBarry Smith SLES sles; 82e2147057SSatish Balay Vec x,y; 83*68e69f27SSatish Balay PC_BJacobi_MPIAIJ *bjac; 846699817fSBarry Smith KSP subksp; 856699817fSBarry Smith PC subpc; 866699817fSBarry Smith MatType type; 876699817fSBarry Smith 886699817fSBarry Smith if (jac->use_true_local) { 894b0e389bSBarry Smith MatGetType(pc->mat,&type,PETSC_NULL); 90*68e69f27SSatish Balay if (type != MATMPIAIJ) SETERRQ(1,"PCSetUp_BJacobi_MPIAIJ:Incompatible matrix type."); 916699817fSBarry Smith matin = (Mat_MPIAIJ *) mat->data; 926699817fSBarry Smith } 936699817fSBarry Smith 946699817fSBarry Smith /* set default direct solver with no Krylov method */ 956699817fSBarry Smith if (!pc->setupcalled) { 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); 1026daaf66cSBarry Smith ierr = SLESSetOptionsPrefix(sles,"sub_"); CHKERRQ(ierr); 1036699817fSBarry Smith ierr = SLESSetFromOptions(sles); CHKERRQ(ierr); 1046699817fSBarry Smith /* 1056699817fSBarry Smith This is not so good. The only reason we need to generate this vector 1066699817fSBarry Smith is so KSP may generate seq vectors for the local solves 1076699817fSBarry Smith */ 1086699817fSBarry Smith ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr); 1096699817fSBarry Smith ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr); 110e2147057SSatish Balay ierr = VecCreateSeq(MPI_COMM_SELF,m,&y); CHKERRQ(ierr); 1116699817fSBarry Smith PLogObjectParent(pmat,x); 112e2147057SSatish Balay PLogObjectParent(pmat,y); 1136699817fSBarry Smith 114*68e69f27SSatish Balay pc->destroy = PCDestroy_BJacobi_MPIAIJ; 115*68e69f27SSatish Balay pc->apply = PCApply_BJacobi_MPIAIJ; 116*68e69f27SSatish Balay pc->setuponblocks = PCSetUpOnBlocks_BJacobi_MPIAIJ; 1176699817fSBarry Smith 118*68e69f27SSatish Balay bjac = (PC_BJacobi_MPIAIJ *) PetscMalloc(sizeof(PC_BJacobi_MPIAIJ));CHKPTRQ(bjac); 119*68e69f27SSatish Balay PLogObjectMemory(pc,sizeof(PC_BJacobi_MPIAIJ)); 1206699817fSBarry Smith bjac->x = x; 121e2147057SSatish Balay bjac->y = y; 1226699817fSBarry Smith 1230452661fSBarry Smith jac->sles = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles); 1246699817fSBarry Smith jac->sles[0] = sles; 1256699817fSBarry Smith jac->data = (void *) bjac; 1266699817fSBarry Smith } 1276699817fSBarry Smith else { 1286699817fSBarry Smith sles = jac->sles[0]; 129*68e69f27SSatish Balay bjac = (PC_BJacobi_MPIAIJ *)jac->data; 1306699817fSBarry Smith } 13149c46530SBarry Smith if (jac->l_true[0] == USE_TRUE_MATRIX) { 13249c46530SBarry Smith ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag); 13349c46530SBarry Smith } 13449c46530SBarry Smith else if (jac->use_true_local) 1356699817fSBarry Smith ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag); 1366699817fSBarry Smith else 1376699817fSBarry Smith ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag); 1386699817fSBarry Smith CHKERRQ(ierr); 1396699817fSBarry Smith return 0; 1406699817fSBarry Smith } 1416699817fSBarry Smith 14202834360SBarry Smith 143