16699817fSBarry Smith #ifndef lint 2*639f9d9dSBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.20 1996/08/08 14:42:52 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" 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) { 94*639f9d9dSBarry Smith char *prefix; 956699817fSBarry Smith ierr = SLESCreate(MPI_COMM_SELF,&sles); CHKERRQ(ierr); 966699817fSBarry Smith PLogObjectParent(pc,sles); 976699817fSBarry Smith ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr); 984b0e389bSBarry Smith ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr); 996699817fSBarry Smith ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr); 1003b90cdfbSSatish Balay ierr = PCSetType(subpc,PCILU); CHKERRQ(ierr); 101*639f9d9dSBarry Smith ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); 102*639f9d9dSBarry Smith ierr = SLESSetOptionsPrefix(sles,prefix); CHKERRQ(ierr); 103*639f9d9dSBarry Smith ierr = SLESAppendOptionsPrefix(sles,"sub_"); CHKERRQ(ierr); 1046699817fSBarry Smith ierr = SLESSetFromOptions(sles); CHKERRQ(ierr); 1056699817fSBarry Smith /* 1066699817fSBarry Smith This is not so good. The only reason we need to generate this vector 1076699817fSBarry Smith is so KSP may generate seq vectors for the local solves 1086699817fSBarry Smith */ 1096699817fSBarry Smith ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr); 1106699817fSBarry Smith ierr = VecCreateSeq(MPI_COMM_SELF,m,&x); CHKERRQ(ierr); 111e2147057SSatish Balay ierr = VecCreateSeq(MPI_COMM_SELF,m,&y); CHKERRQ(ierr); 1126699817fSBarry Smith PLogObjectParent(pmat,x); 113e2147057SSatish Balay PLogObjectParent(pmat,y); 1146699817fSBarry Smith 11568e69f27SSatish Balay pc->destroy = PCDestroy_BJacobi_MPIAIJ; 11668e69f27SSatish Balay pc->apply = PCApply_BJacobi_MPIAIJ; 11768e69f27SSatish Balay pc->setuponblocks = PCSetUpOnBlocks_BJacobi_MPIAIJ; 1186699817fSBarry Smith 11968e69f27SSatish Balay bjac = (PC_BJacobi_MPIAIJ *) PetscMalloc(sizeof(PC_BJacobi_MPIAIJ));CHKPTRQ(bjac); 12068e69f27SSatish Balay PLogObjectMemory(pc,sizeof(PC_BJacobi_MPIAIJ)); 1216699817fSBarry Smith bjac->x = x; 122e2147057SSatish Balay bjac->y = y; 1236699817fSBarry Smith 1240452661fSBarry Smith jac->sles = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles); 1256699817fSBarry Smith jac->sles[0] = sles; 1266699817fSBarry Smith jac->data = (void *) bjac; 1276699817fSBarry Smith } 1286699817fSBarry Smith else { 1296699817fSBarry Smith sles = jac->sles[0]; 13068e69f27SSatish Balay bjac = (PC_BJacobi_MPIAIJ *)jac->data; 1316699817fSBarry Smith } 132c915c865SSatish Balay /* if (jac->l_true[0] == USE_TRUE_MATRIX) { 13349c46530SBarry Smith ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag); 13449c46530SBarry Smith } 135c915c865SSatish Balay else */ if (jac->use_true_local) 1366699817fSBarry Smith ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag); 1376699817fSBarry Smith else 1386699817fSBarry Smith ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag); 1396699817fSBarry Smith CHKERRQ(ierr); 1406699817fSBarry Smith return 0; 1416699817fSBarry Smith } 1426699817fSBarry Smith 14302834360SBarry Smith 144