16699817fSBarry Smith #ifndef lint 2*029af93fSBarry Smith static char vcid[] = "$Id: mpiaijpc.c,v 1.28 1997/02/22 02:25:15 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" 1290f02eecSBarry Smith #include "src/vec/vecimpl.h" 1302834360SBarry Smith #include "src/pc/impls/bjacobi/bjacobi.h" 146699817fSBarry Smith #include "sles.h" 156699817fSBarry Smith 166699817fSBarry Smith typedef struct { 17e2147057SSatish Balay Vec x, y; 1868e69f27SSatish Balay } PC_BJacobi_MPIAIJ; 196699817fSBarry Smith 205615d1e5SSatish Balay #undef __FUNC__ 215eea60f9SBarry Smith #define __FUNC__ "PCDestroy_BJacobi_MPIAIJ" /* ADIC Ignore */ 2268e69f27SSatish Balay int PCDestroy_BJacobi_MPIAIJ(PetscObject obj) 236699817fSBarry Smith { 246699817fSBarry Smith PC pc = (PC) obj; 256699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 2668e69f27SSatish Balay PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data; 279da4b979SBarry Smith int ierr; 286699817fSBarry Smith 299da4b979SBarry Smith ierr = SLESDestroy(jac->sles[0]); CHKERRQ(ierr); 300452661fSBarry Smith PetscFree(jac->sles); 316699817fSBarry Smith ierr = VecDestroy(bjac->x); CHKERRQ(ierr); 32e2147057SSatish Balay ierr = VecDestroy(bjac->y); CHKERRQ(ierr); 33b4fd4287SBarry Smith if (jac->l_lens) PetscFree(jac->l_lens); 34b4fd4287SBarry Smith if (jac->g_lens) PetscFree(jac->g_lens); 350452661fSBarry Smith PetscFree(bjac); PetscFree(jac); 366699817fSBarry Smith return 0; 376699817fSBarry Smith } 386699817fSBarry Smith 396dea57deSBarry Smith 405615d1e5SSatish Balay #undef __FUNC__ 415615d1e5SSatish Balay #define __FUNC__ "PCSetUpOnBlocks_BJacobi_MPIAIJ" 4268e69f27SSatish Balay int PCSetUpOnBlocks_BJacobi_MPIAIJ(PC pc) 436dea57deSBarry Smith { 446dea57deSBarry Smith int ierr; 456dea57deSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 4668e69f27SSatish Balay PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data; 476dea57deSBarry Smith 486dea57deSBarry Smith ierr = SLESSetUp(jac->sles[0],bjac->x,bjac->y); CHKERRQ(ierr); 496dea57deSBarry Smith return 0; 506dea57deSBarry Smith } 516dea57deSBarry Smith 525615d1e5SSatish Balay #undef __FUNC__ 535615d1e5SSatish Balay #define __FUNC__ "PCApply_BJacobi_MPIAIJ" 5468e69f27SSatish Balay int PCApply_BJacobi_MPIAIJ(PC pc,Vec x, Vec y) 556699817fSBarry Smith { 566699817fSBarry Smith int ierr,its; 576699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 5868e69f27SSatish Balay PC_BJacobi_MPIAIJ *bjac = (PC_BJacobi_MPIAIJ *) jac->data; 59e2147057SSatish Balay Scalar *x_array,*x_true_array, *y_array,*y_true_array; 606699817fSBarry Smith 619da4b979SBarry Smith /* 629da4b979SBarry Smith The VecPlaceArray() is to avoid having to copy the 639da4b979SBarry Smith y vector into the bjac->x vector. The reason for 649da4b979SBarry Smith the bjac->x vector is that we need a sequential vector 659da4b979SBarry Smith for the sequential solve. 669da4b979SBarry Smith */ 6790f02eecSBarry Smith VecGetArray_Fast(x,x_array); 6890f02eecSBarry Smith VecGetArray_Fast(y,y_array); 6990f02eecSBarry Smith VecGetArray_Fast(bjac->x,x_true_array); 7090f02eecSBarry Smith VecGetArray_Fast(bjac->y,y_true_array); 7190f02eecSBarry Smith VecPlaceArray_Fast(bjac->x,x_array); 7290f02eecSBarry Smith VecPlaceArray_Fast(bjac->y,y_array); 7390f02eecSBarry Smith ierr = SLESSolve(jac->sles[0],bjac->x,bjac->y,&its); 7490f02eecSBarry Smith VecPlaceArray_Fast(bjac->x,x_true_array); 7590f02eecSBarry Smith VecPlaceArray_Fast(bjac->y,y_true_array); 766699817fSBarry Smith return 0; 776699817fSBarry Smith } 786699817fSBarry Smith 795615d1e5SSatish Balay #undef __FUNC__ 805615d1e5SSatish Balay #define __FUNC__ "PCSetUp_BJacobi_MPIAIJ" 8168e69f27SSatish Balay int PCSetUp_BJacobi_MPIAIJ(PC pc) 826699817fSBarry Smith { 836699817fSBarry Smith PC_BJacobi *jac = (PC_BJacobi *) pc->data; 846699817fSBarry Smith Mat mat = pc->mat, pmat = pc->pmat; 856699817fSBarry Smith Mat_MPIAIJ *pmatin = (Mat_MPIAIJ *) pmat->data; 866699817fSBarry Smith Mat_MPIAIJ *matin = 0; 8763b91edcSBarry Smith int ierr, m; 886699817fSBarry Smith SLES sles; 89e2147057SSatish Balay Vec x,y; 9068e69f27SSatish Balay PC_BJacobi_MPIAIJ *bjac; 916699817fSBarry Smith KSP subksp; 926699817fSBarry Smith PC subpc; 936699817fSBarry Smith MatType type; 946699817fSBarry Smith 956699817fSBarry Smith if (jac->use_true_local) { 964b0e389bSBarry Smith MatGetType(pc->mat,&type,PETSC_NULL); 97e3372554SBarry Smith if (type != MATMPIAIJ) SETERRQ(1,0,"Incompatible matrix type."); 986699817fSBarry Smith matin = (Mat_MPIAIJ *) mat->data; 996699817fSBarry Smith } 1006699817fSBarry Smith 1016699817fSBarry Smith /* set default direct solver with no Krylov method */ 1026699817fSBarry Smith if (!pc->setupcalled) { 103639f9d9dSBarry Smith char *prefix; 104*029af93fSBarry Smith ierr = SLESCreate(PETSC_COMM_SELF,&sles); CHKERRQ(ierr); 1056699817fSBarry Smith PLogObjectParent(pc,sles); 1066699817fSBarry Smith ierr = SLESGetKSP(sles,&subksp); CHKERRQ(ierr); 1074b0e389bSBarry Smith ierr = KSPSetType(subksp,KSPPREONLY); CHKERRQ(ierr); 1086699817fSBarry Smith ierr = SLESGetPC(sles,&subpc); CHKERRQ(ierr); 1093b90cdfbSSatish Balay ierr = PCSetType(subpc,PCILU); CHKERRQ(ierr); 110639f9d9dSBarry Smith ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); 111639f9d9dSBarry Smith ierr = SLESSetOptionsPrefix(sles,prefix); CHKERRQ(ierr); 112639f9d9dSBarry Smith ierr = SLESAppendOptionsPrefix(sles,"sub_"); CHKERRQ(ierr); 1136699817fSBarry Smith ierr = SLESSetFromOptions(sles); CHKERRQ(ierr); 1146699817fSBarry Smith /* 1156699817fSBarry Smith This is not so good. The only reason we need to generate this vector 1166699817fSBarry Smith is so KSP may generate seq vectors for the local solves 1176699817fSBarry Smith */ 1186699817fSBarry Smith ierr = MatGetSize(pmatin->A,&m,&m); CHKERRQ(ierr); 119*029af93fSBarry Smith ierr = VecCreateSeq(PETSC_COMM_SELF,m,&x); CHKERRQ(ierr); 120*029af93fSBarry Smith ierr = VecCreateSeq(PETSC_COMM_SELF,m,&y); CHKERRQ(ierr); 121a7111324SSatish Balay PLogObjectParent(pc,x); 122a7111324SSatish Balay PLogObjectParent(pc,y); 1236699817fSBarry Smith 12468e69f27SSatish Balay pc->destroy = PCDestroy_BJacobi_MPIAIJ; 12568e69f27SSatish Balay pc->apply = PCApply_BJacobi_MPIAIJ; 12668e69f27SSatish Balay pc->setuponblocks = PCSetUpOnBlocks_BJacobi_MPIAIJ; 1276699817fSBarry Smith 12868e69f27SSatish Balay bjac = (PC_BJacobi_MPIAIJ *) PetscMalloc(sizeof(PC_BJacobi_MPIAIJ));CHKPTRQ(bjac); 12968e69f27SSatish Balay PLogObjectMemory(pc,sizeof(PC_BJacobi_MPIAIJ)); 1306699817fSBarry Smith bjac->x = x; 131e2147057SSatish Balay bjac->y = y; 1326699817fSBarry Smith 1330452661fSBarry Smith jac->sles = (SLES*) PetscMalloc( sizeof(SLES) ); CHKPTRQ(jac->sles); 1346699817fSBarry Smith jac->sles[0] = sles; 1356699817fSBarry Smith jac->data = (void *) bjac; 1366699817fSBarry Smith } 1376699817fSBarry Smith else { 1386699817fSBarry Smith sles = jac->sles[0]; 13968e69f27SSatish Balay bjac = (PC_BJacobi_MPIAIJ *)jac->data; 1406699817fSBarry Smith } 141c915c865SSatish Balay /* if (jac->l_true[0] == USE_TRUE_MATRIX) { 14249c46530SBarry Smith ierr = SLESSetOperators(sles,matin->A,matin->A,pc->flag); 14349c46530SBarry Smith } 144c915c865SSatish Balay else */ if (jac->use_true_local) 1456699817fSBarry Smith ierr = SLESSetOperators(sles,matin->A,pmatin->A,pc->flag); 1466699817fSBarry Smith else 1476699817fSBarry Smith ierr = SLESSetOperators(sles,pmatin->A,pmatin->A,pc->flag); 1486699817fSBarry Smith CHKERRQ(ierr); 1496699817fSBarry Smith return 0; 1506699817fSBarry Smith } 1516699817fSBarry Smith 15202834360SBarry Smith 153