xref: /petsc/src/ksp/pc/impls/pbjacobi/pbjacobi.c (revision 90dfcc32938128b90ebf46681dc28f019db51f99)
1dba47a55SKris Buschelman 
24b9ad928SBarry Smith /*
34b9ad928SBarry Smith    Include files needed for the PBJacobi preconditioner:
44b9ad928SBarry Smith      pcimpl.h - private include file intended for use by all preconditioners
54b9ad928SBarry Smith */
64b9ad928SBarry Smith 
7af0996ceSBarry Smith #include <petsc/private/pcimpl.h>   /*I "petscpc.h" I*/
84b9ad928SBarry Smith 
94b9ad928SBarry Smith /*
104b9ad928SBarry Smith    Private context (data structure) for the PBJacobi preconditioner.
114b9ad928SBarry Smith */
124b9ad928SBarry Smith typedef struct {
13713ccfa9SJed Brown   const MatScalar *diag;
14c1ac3661SBarry Smith   PetscInt        bs,mbs;
154b9ad928SBarry Smith } PC_PBJacobi;
164b9ad928SBarry Smith 
17bbead8a2SBarry Smith static PetscErrorCode PCApply_PBJacobi_1(PC pc,Vec x,Vec y)
18bbead8a2SBarry Smith {
19bbead8a2SBarry Smith   PC_PBJacobi       *jac = (PC_PBJacobi*)pc->data;
20bbead8a2SBarry Smith   PetscErrorCode    ierr;
21bbead8a2SBarry Smith   PetscInt          i,m = jac->mbs;
22bbead8a2SBarry Smith   const MatScalar   *diag = jac->diag;
23bbead8a2SBarry Smith   const PetscScalar *xx;
24bbead8a2SBarry Smith   PetscScalar       *yy;
25bbead8a2SBarry Smith 
26bbead8a2SBarry Smith   PetscFunctionBegin;
27bbead8a2SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
28bbead8a2SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
292fa5cd67SKarl Rupp   for (i=0; i<m; i++) yy[i] = diag[i]*xx[i];
30bbead8a2SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
31bbead8a2SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
3279cd6d07SHong Zhang   ierr = PetscLogFlops(m);CHKERRQ(ierr);
33bbead8a2SBarry Smith   PetscFunctionReturn(0);
34bbead8a2SBarry Smith }
35bbead8a2SBarry Smith 
366849ba73SBarry Smith static PetscErrorCode PCApply_PBJacobi_2(PC pc,Vec x,Vec y)
374b9ad928SBarry Smith {
384b9ad928SBarry Smith   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
39dfbe8321SBarry Smith   PetscErrorCode  ierr;
40c1ac3661SBarry Smith   PetscInt        i,m = jac->mbs;
4185f4f44aSBarry Smith   const MatScalar *diag = jac->diag;
420e666e78SToby Isaac   PetscScalar     x0,x1,*yy;
430e666e78SToby Isaac   const PetscScalar *xx;
444b9ad928SBarry Smith 
454b9ad928SBarry Smith   PetscFunctionBegin;
460e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
474b9ad928SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
484b9ad928SBarry Smith   for (i=0; i<m; i++) {
494b9ad928SBarry Smith     x0        = xx[2*i]; x1 = xx[2*i+1];
504b9ad928SBarry Smith     yy[2*i]   = diag[0]*x0 + diag[2]*x1;
514b9ad928SBarry Smith     yy[2*i+1] = diag[1]*x0 + diag[3]*x1;
524b9ad928SBarry Smith     diag     += 4;
534b9ad928SBarry Smith   }
540e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
554b9ad928SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
56dc0b31edSSatish Balay   ierr = PetscLogFlops(6.0*m);CHKERRQ(ierr);
574b9ad928SBarry Smith   PetscFunctionReturn(0);
584b9ad928SBarry Smith }
596849ba73SBarry Smith static PetscErrorCode PCApply_PBJacobi_3(PC pc,Vec x,Vec y)
604b9ad928SBarry Smith {
614b9ad928SBarry Smith   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
62dfbe8321SBarry Smith   PetscErrorCode  ierr;
63c1ac3661SBarry Smith   PetscInt        i,m = jac->mbs;
6485f4f44aSBarry Smith   const MatScalar *diag = jac->diag;
650e666e78SToby Isaac   PetscScalar     x0,x1,x2,*yy;
660e666e78SToby Isaac   const PetscScalar *xx;
674b9ad928SBarry Smith 
684b9ad928SBarry Smith   PetscFunctionBegin;
690e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
704b9ad928SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
714b9ad928SBarry Smith   for (i=0; i<m; i++) {
724b9ad928SBarry Smith     x0 = xx[3*i]; x1 = xx[3*i+1]; x2 = xx[3*i+2];
732fa5cd67SKarl Rupp 
744b9ad928SBarry Smith     yy[3*i]   = diag[0]*x0 + diag[3]*x1 + diag[6]*x2;
754b9ad928SBarry Smith     yy[3*i+1] = diag[1]*x0 + diag[4]*x1 + diag[7]*x2;
764b9ad928SBarry Smith     yy[3*i+2] = diag[2]*x0 + diag[5]*x1 + diag[8]*x2;
774b9ad928SBarry Smith     diag     += 9;
784b9ad928SBarry Smith   }
790e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
804b9ad928SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
81dc0b31edSSatish Balay   ierr = PetscLogFlops(15.0*m);CHKERRQ(ierr);
824b9ad928SBarry Smith   PetscFunctionReturn(0);
834b9ad928SBarry Smith }
846849ba73SBarry Smith static PetscErrorCode PCApply_PBJacobi_4(PC pc,Vec x,Vec y)
854b9ad928SBarry Smith {
864b9ad928SBarry Smith   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
87dfbe8321SBarry Smith   PetscErrorCode  ierr;
88c1ac3661SBarry Smith   PetscInt        i,m = jac->mbs;
8985f4f44aSBarry Smith   const MatScalar *diag = jac->diag;
900e666e78SToby Isaac   PetscScalar     x0,x1,x2,x3,*yy;
910e666e78SToby Isaac   const PetscScalar *xx;
924b9ad928SBarry Smith 
934b9ad928SBarry Smith   PetscFunctionBegin;
940e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
954b9ad928SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
964b9ad928SBarry Smith   for (i=0; i<m; i++) {
974b9ad928SBarry Smith     x0 = xx[4*i]; x1 = xx[4*i+1]; x2 = xx[4*i+2]; x3 = xx[4*i+3];
982fa5cd67SKarl Rupp 
994b9ad928SBarry Smith     yy[4*i]   = diag[0]*x0 + diag[4]*x1 + diag[8]*x2  + diag[12]*x3;
1004b9ad928SBarry Smith     yy[4*i+1] = diag[1]*x0 + diag[5]*x1 + diag[9]*x2  + diag[13]*x3;
1014b9ad928SBarry Smith     yy[4*i+2] = diag[2]*x0 + diag[6]*x1 + diag[10]*x2 + diag[14]*x3;
1024b9ad928SBarry Smith     yy[4*i+3] = diag[3]*x0 + diag[7]*x1 + diag[11]*x2 + diag[15]*x3;
1034b9ad928SBarry Smith     diag     += 16;
1044b9ad928SBarry Smith   }
1050e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1064b9ad928SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
107dc0b31edSSatish Balay   ierr = PetscLogFlops(28.0*m);CHKERRQ(ierr);
1084b9ad928SBarry Smith   PetscFunctionReturn(0);
1094b9ad928SBarry Smith }
1106849ba73SBarry Smith static PetscErrorCode PCApply_PBJacobi_5(PC pc,Vec x,Vec y)
1114b9ad928SBarry Smith {
1124b9ad928SBarry Smith   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
113dfbe8321SBarry Smith   PetscErrorCode  ierr;
114c1ac3661SBarry Smith   PetscInt        i,m = jac->mbs;
11585f4f44aSBarry Smith   const MatScalar *diag = jac->diag;
1160e666e78SToby Isaac   PetscScalar     x0,x1,x2,x3,x4,*yy;
1170e666e78SToby Isaac   const PetscScalar *xx;
1184b9ad928SBarry Smith 
1194b9ad928SBarry Smith   PetscFunctionBegin;
1200e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1214b9ad928SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1224b9ad928SBarry Smith   for (i=0; i<m; i++) {
1234b9ad928SBarry Smith     x0 = xx[5*i]; x1 = xx[5*i+1]; x2 = xx[5*i+2]; x3 = xx[5*i+3]; x4 = xx[5*i+4];
1242fa5cd67SKarl Rupp 
1254b9ad928SBarry Smith     yy[5*i]   = diag[0]*x0 + diag[5]*x1 + diag[10]*x2  + diag[15]*x3 + diag[20]*x4;
1264b9ad928SBarry Smith     yy[5*i+1] = diag[1]*x0 + diag[6]*x1 + diag[11]*x2  + diag[16]*x3 + diag[21]*x4;
1274b9ad928SBarry Smith     yy[5*i+2] = diag[2]*x0 + diag[7]*x1 + diag[12]*x2 + diag[17]*x3 + diag[22]*x4;
1284b9ad928SBarry Smith     yy[5*i+3] = diag[3]*x0 + diag[8]*x1 + diag[13]*x2 + diag[18]*x3 + diag[23]*x4;
1294b9ad928SBarry Smith     yy[5*i+4] = diag[4]*x0 + diag[9]*x1 + diag[14]*x2 + diag[19]*x3 + diag[24]*x4;
1304b9ad928SBarry Smith     diag     += 25;
1314b9ad928SBarry Smith   }
1320e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1334b9ad928SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
134dc0b31edSSatish Balay   ierr = PetscLogFlops(45.0*m);CHKERRQ(ierr);
1354b9ad928SBarry Smith   PetscFunctionReturn(0);
1364b9ad928SBarry Smith }
1370e1b4bd6SMark F. Adams static PetscErrorCode PCApply_PBJacobi_6(PC pc,Vec x,Vec y)
1380e1b4bd6SMark F. Adams {
1390e1b4bd6SMark F. Adams   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
1400e1b4bd6SMark F. Adams   PetscErrorCode  ierr;
1410e1b4bd6SMark F. Adams   PetscInt        i,m = jac->mbs;
1420e1b4bd6SMark F. Adams   const MatScalar *diag = jac->diag;
1430e666e78SToby Isaac   PetscScalar     x0,x1,x2,x3,x4,x5,*yy;
1440e666e78SToby Isaac   const PetscScalar *xx;
1450e1b4bd6SMark F. Adams 
1460e1b4bd6SMark F. Adams   PetscFunctionBegin;
1470e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1480e1b4bd6SMark F. Adams   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1490e1b4bd6SMark F. Adams   for (i=0; i<m; i++) {
1500e1b4bd6SMark F. Adams     x0 = xx[6*i]; x1 = xx[6*i+1]; x2 = xx[6*i+2]; x3 = xx[6*i+3]; x4 = xx[6*i+4]; x5 = xx[6*i+5];
1512fa5cd67SKarl Rupp 
1520e1b4bd6SMark F. Adams     yy[6*i]   = diag[0]*x0 + diag[6]*x1  + diag[12]*x2  + diag[18]*x3 + diag[24]*x4 + diag[30]*x5;
1530e1b4bd6SMark F. Adams     yy[6*i+1] = diag[1]*x0 + diag[7]*x1  + diag[13]*x2  + diag[19]*x3 + diag[25]*x4 + diag[31]*x5;
1540e1b4bd6SMark F. Adams     yy[6*i+2] = diag[2]*x0 + diag[8]*x1  + diag[14]*x2  + diag[20]*x3 + diag[26]*x4 + diag[32]*x5;
1550e1b4bd6SMark F. Adams     yy[6*i+3] = diag[3]*x0 + diag[9]*x1  + diag[15]*x2  + diag[21]*x3 + diag[27]*x4 + diag[33]*x5;
1560e1b4bd6SMark F. Adams     yy[6*i+4] = diag[4]*x0 + diag[10]*x1 + diag[16]*x2  + diag[22]*x3 + diag[28]*x4 + diag[34]*x5;
1570e1b4bd6SMark F. Adams     yy[6*i+5] = diag[5]*x0 + diag[11]*x1 + diag[17]*x2  + diag[23]*x3 + diag[29]*x4 + diag[35]*x5;
1580e1b4bd6SMark F. Adams     diag     += 36;
1590e1b4bd6SMark F. Adams   }
1600e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1610e1b4bd6SMark F. Adams   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1620e1b4bd6SMark F. Adams   ierr = PetscLogFlops(66.0*m);CHKERRQ(ierr);
1630e1b4bd6SMark F. Adams   PetscFunctionReturn(0);
1640e1b4bd6SMark F. Adams }
1650a4ca348SMatthew G Knepley static PetscErrorCode PCApply_PBJacobi_7(PC pc,Vec x,Vec y)
1660a4ca348SMatthew G Knepley {
1670a4ca348SMatthew G Knepley   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
1680a4ca348SMatthew G Knepley   PetscErrorCode  ierr;
1690a4ca348SMatthew G Knepley   PetscInt        i,m = jac->mbs;
1700a4ca348SMatthew G Knepley   const MatScalar *diag = jac->diag;
1710e666e78SToby Isaac   PetscScalar     x0,x1,x2,x3,x4,x5,x6,*yy;
1720e666e78SToby Isaac   const PetscScalar *xx;
1730a4ca348SMatthew G Knepley 
1740a4ca348SMatthew G Knepley   PetscFunctionBegin;
1750e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1760a4ca348SMatthew G Knepley   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1770a4ca348SMatthew G Knepley   for (i=0; i<m; i++) {
1780a4ca348SMatthew G Knepley     x0 = xx[7*i]; x1 = xx[7*i+1]; x2 = xx[7*i+2]; x3 = xx[7*i+3]; x4 = xx[7*i+4]; x5 = xx[7*i+5]; x6 = xx[7*i+6];
1792fa5cd67SKarl Rupp 
1800a4ca348SMatthew G Knepley     yy[7*i]   = diag[0]*x0 + diag[7]*x1  + diag[14]*x2  + diag[21]*x3 + diag[28]*x4 + diag[35]*x5 + diag[42]*x6;
1810a4ca348SMatthew G Knepley     yy[7*i+1] = diag[1]*x0 + diag[8]*x1  + diag[15]*x2  + diag[22]*x3 + diag[29]*x4 + diag[36]*x5 + diag[43]*x6;
1820a4ca348SMatthew G Knepley     yy[7*i+2] = diag[2]*x0 + diag[9]*x1  + diag[16]*x2  + diag[23]*x3 + diag[30]*x4 + diag[37]*x5 + diag[44]*x6;
1830a4ca348SMatthew G Knepley     yy[7*i+3] = diag[3]*x0 + diag[10]*x1 + diag[17]*x2  + diag[24]*x3 + diag[31]*x4 + diag[38]*x5 + diag[45]*x6;
1840a4ca348SMatthew G Knepley     yy[7*i+4] = diag[4]*x0 + diag[11]*x1 + diag[18]*x2  + diag[25]*x3 + diag[32]*x4 + diag[39]*x5 + diag[46]*x6;
1850a4ca348SMatthew G Knepley     yy[7*i+5] = diag[5]*x0 + diag[12]*x1 + diag[19]*x2  + diag[26]*x3 + diag[33]*x4 + diag[40]*x5 + diag[47]*x6;
1860a4ca348SMatthew G Knepley     yy[7*i+6] = diag[6]*x0 + diag[13]*x1 + diag[20]*x2  + diag[27]*x3 + diag[34]*x4 + diag[41]*x5 + diag[48]*x6;
1870a4ca348SMatthew G Knepley     diag     += 49;
1880a4ca348SMatthew G Knepley   }
1890e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1900a4ca348SMatthew G Knepley   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
191054ddcb3SPierre Jolivet   ierr = PetscLogFlops(91.0*m);CHKERRQ(ierr); /* 2*bs2 - bs */
1920a4ca348SMatthew G Knepley   PetscFunctionReturn(0);
1930a4ca348SMatthew G Knepley }
194f79daf70SMark Lohry static PetscErrorCode PCApply_PBJacobi_N(PC pc,Vec x,Vec y)
195f79daf70SMark Lohry {
196f79daf70SMark Lohry   PC_PBJacobi       *jac = (PC_PBJacobi*)pc->data;
197f79daf70SMark Lohry   PetscErrorCode    ierr;
198f79daf70SMark Lohry   PetscInt          i,ib,jb;
199f79daf70SMark Lohry   const PetscInt    m = jac->mbs;
200f79daf70SMark Lohry   const PetscInt    bs = jac->bs;
201f79daf70SMark Lohry   const MatScalar   *diag = jac->diag;
202f79daf70SMark Lohry   PetscScalar       *yy;
203f79daf70SMark Lohry   const PetscScalar *xx;
204f79daf70SMark Lohry 
205f79daf70SMark Lohry   PetscFunctionBegin;
206f79daf70SMark Lohry   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
207f79daf70SMark Lohry   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
208f79daf70SMark Lohry   for (i=0; i<m; i++) {
209f79daf70SMark Lohry     for (ib=0; ib<bs; ib++) {
210f79daf70SMark Lohry       PetscScalar rowsum = 0;
211f79daf70SMark Lohry       for (jb=0; jb<bs; jb++) {
212f79daf70SMark Lohry         rowsum += diag[ib+jb*bs] * xx[bs*i+jb];
213f79daf70SMark Lohry       }
214f79daf70SMark Lohry       yy[bs*i+ib] = rowsum;
215f79daf70SMark Lohry     }
216f79daf70SMark Lohry     diag += bs*bs;
217f79daf70SMark Lohry   }
218f79daf70SMark Lohry   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
219f79daf70SMark Lohry   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
220054ddcb3SPierre Jolivet   ierr = PetscLogFlops((2.0*bs*bs-bs)*m);CHKERRQ(ierr); /* 2*bs2 - bs */
221f79daf70SMark Lohry   PetscFunctionReturn(0);
222f79daf70SMark Lohry }
223faff7d23SJed Brown 
2248cd12025SJed Brown static PetscErrorCode PCApplyTranspose_PBJacobi_N(PC pc,Vec x,Vec y)
2258cd12025SJed Brown {
2268cd12025SJed Brown   PC_PBJacobi       *jac = (PC_PBJacobi*)pc->data;
2278cd12025SJed Brown   PetscErrorCode    ierr;
2288cd12025SJed Brown   PetscInt          i,j,k,m = jac->mbs,bs=jac->bs;
2298cd12025SJed Brown   const MatScalar   *diag = jac->diag;
2308cd12025SJed Brown   const PetscScalar *xx;
2318cd12025SJed Brown   PetscScalar       *yy;
2328cd12025SJed Brown 
2338cd12025SJed Brown   PetscFunctionBegin;
2348cd12025SJed Brown   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
2358cd12025SJed Brown   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
2368cd12025SJed Brown   for (i=0; i<m; i++) {
2378cd12025SJed Brown     for (j=0; j<bs; j++) yy[i*bs+j] = 0.;
2388cd12025SJed Brown     for (j=0; j<bs; j++) {
2398cd12025SJed Brown       for (k=0; k<bs; k++) {
2408cd12025SJed Brown         yy[i*bs+k] += diag[k*bs+j]*xx[i*bs+j];
2418cd12025SJed Brown       }
2428cd12025SJed Brown     }
2438cd12025SJed Brown     diag += bs*bs;
2448cd12025SJed Brown   }
2458cd12025SJed Brown   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2468cd12025SJed Brown   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2478cd12025SJed Brown   ierr = PetscLogFlops(m*bs*(2*bs-1));CHKERRQ(ierr);
2488cd12025SJed Brown   PetscFunctionReturn(0);
2498cd12025SJed Brown }
2508cd12025SJed Brown 
2514b9ad928SBarry Smith /* -------------------------------------------------------------------------- */
2526849ba73SBarry Smith static PetscErrorCode PCSetUp_PBJacobi(PC pc)
2534b9ad928SBarry Smith {
2544b9ad928SBarry Smith   PC_PBJacobi    *jac = (PC_PBJacobi*)pc->data;
255dfbe8321SBarry Smith   PetscErrorCode ierr;
2564b9ad928SBarry Smith   Mat            A = pc->pmat;
25700e125f8SBarry Smith   MatFactorError err;
258539c167fSBarry Smith   PetscInt       nlocal;
2594b9ad928SBarry Smith 
2604b9ad928SBarry Smith   PetscFunctionBegin;
261bbead8a2SBarry Smith   ierr = MatInvertBlockDiagonal(A,&jac->diag);CHKERRQ(ierr);
26200e125f8SBarry Smith   ierr = MatFactorGetError(A,&err);CHKERRQ(ierr);
26300e125f8SBarry Smith   if (err) pc->failedreason = (PCFailedReason)err;
264d7806518SHong Zhang 
26533d57670SJed Brown   ierr = MatGetBlockSize(A,&jac->bs);CHKERRQ(ierr);
266539c167fSBarry Smith   ierr = MatGetLocalSize(A,&nlocal,NULL);CHKERRQ(ierr);
267539c167fSBarry Smith   jac->mbs = nlocal/jac->bs;
268521d7252SBarry Smith   switch (jac->bs) {
269bbead8a2SBarry Smith   case 1:
270bbead8a2SBarry Smith     pc->ops->apply = PCApply_PBJacobi_1;
271bbead8a2SBarry Smith     break;
2724b9ad928SBarry Smith   case 2:
2734b9ad928SBarry Smith     pc->ops->apply = PCApply_PBJacobi_2;
2744b9ad928SBarry Smith     break;
2754b9ad928SBarry Smith   case 3:
2764b9ad928SBarry Smith     pc->ops->apply = PCApply_PBJacobi_3;
2774b9ad928SBarry Smith     break;
2784b9ad928SBarry Smith   case 4:
2794b9ad928SBarry Smith     pc->ops->apply = PCApply_PBJacobi_4;
2804b9ad928SBarry Smith     break;
2814b9ad928SBarry Smith   case 5:
2824b9ad928SBarry Smith     pc->ops->apply = PCApply_PBJacobi_5;
2834b9ad928SBarry Smith     break;
2840e1b4bd6SMark F. Adams   case 6:
2850e1b4bd6SMark F. Adams     pc->ops->apply = PCApply_PBJacobi_6;
2860e1b4bd6SMark F. Adams     break;
2870a4ca348SMatthew G Knepley   case 7:
2880a4ca348SMatthew G Knepley     pc->ops->apply = PCApply_PBJacobi_7;
2890a4ca348SMatthew G Knepley     break;
2904b9ad928SBarry Smith   default:
291f79daf70SMark Lohry     pc->ops->apply = PCApply_PBJacobi_N;
292f79daf70SMark Lohry     break;
2934b9ad928SBarry Smith   }
2948cd12025SJed Brown   pc->ops->applytranspose = PCApplyTranspose_PBJacobi_N;
2954b9ad928SBarry Smith   PetscFunctionReturn(0);
2964b9ad928SBarry Smith }
2974b9ad928SBarry Smith /* -------------------------------------------------------------------------- */
2986849ba73SBarry Smith static PetscErrorCode PCDestroy_PBJacobi(PC pc)
2994b9ad928SBarry Smith {
300dfbe8321SBarry Smith   PetscErrorCode ierr;
3014b9ad928SBarry Smith 
3024b9ad928SBarry Smith   PetscFunctionBegin;
3034b9ad928SBarry Smith   /*
3044b9ad928SBarry Smith       Free the private data structure that was hanging off the PC
3054b9ad928SBarry Smith   */
306c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
3074b9ad928SBarry Smith   PetscFunctionReturn(0);
3084b9ad928SBarry Smith }
309fa939db7SJed Brown 
310fa939db7SJed Brown static PetscErrorCode PCView_PBJacobi(PC pc,PetscViewer viewer)
311fa939db7SJed Brown {
312fa939db7SJed Brown   PetscErrorCode ierr;
313fa939db7SJed Brown   PC_PBJacobi    *jac = (PC_PBJacobi*)pc->data;
314fa939db7SJed Brown   PetscBool      iascii;
315fa939db7SJed Brown 
316fa939db7SJed Brown   PetscFunctionBegin;
317251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
318fa939db7SJed Brown   if (iascii) {
319efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  point-block size %D\n",jac->bs);CHKERRQ(ierr);
32011aeaf0aSBarry Smith   }
321fa939db7SJed Brown   PetscFunctionReturn(0);
322fa939db7SJed Brown }
323fa939db7SJed Brown 
3244b9ad928SBarry Smith /* -------------------------------------------------------------------------- */
32537a17b4dSBarry Smith /*MC
326422a814eSBarry Smith      PCPBJACOBI - Point block Jacobi preconditioner
327422a814eSBarry Smith 
32895452b02SPatrick Sanan    Notes:
329*90dfcc32SBarry Smith      See PCJACOBI for point Jacobi preconditioning, PCVPBJACOBI for variable size point block Jacobi and PCBJACOBI for large blocks
330422a814eSBarry Smith 
331422a814eSBarry Smith      This works for AIJ and BAIJ matrices and uses the blocksize provided to the matrix
332422a814eSBarry Smith 
333422a814eSBarry Smith      Uses dense LU factorization with partial pivoting to invert the blocks; if a zero pivot
334422a814eSBarry Smith      is detected a PETSc error is generated.
335422a814eSBarry Smith 
33695452b02SPatrick Sanan    Developer Notes:
33795452b02SPatrick Sanan      This should support the PCSetErrorIfFailure() flag set to PETSC_TRUE to allow
338422a814eSBarry Smith      the factorization to continue even after a zero pivot is found resulting in a Nan and hence
339422a814eSBarry Smith      terminating KSP with a KSP_DIVERGED_NANORIF allowing
340422a814eSBarry Smith      a nonlinear solver/ODE integrator to recover without stopping the program as currently happens.
341422a814eSBarry Smith 
342*90dfcc32SBarry Smith      Perhaps should provide an option that allows generation of a valid preconditioner
343422a814eSBarry Smith      even if a block is singular as the PCJACOBI does.
34437a17b4dSBarry Smith 
34537a17b4dSBarry Smith    Level: beginner
34637a17b4dSBarry Smith 
347*90dfcc32SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC, PCJACOBI, PCVPBJACOBI, PCBJACOBI
34837a17b4dSBarry Smith 
34937a17b4dSBarry Smith M*/
35037a17b4dSBarry Smith 
3518cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PBJacobi(PC pc)
3524b9ad928SBarry Smith {
3534b9ad928SBarry Smith   PC_PBJacobi    *jac;
354dfbe8321SBarry Smith   PetscErrorCode ierr;
3554b9ad928SBarry Smith 
3564b9ad928SBarry Smith   PetscFunctionBegin;
3574b9ad928SBarry Smith   /*
3584b9ad928SBarry Smith      Creates the private data structure for this preconditioner and
3594b9ad928SBarry Smith      attach it to the PC object.
3604b9ad928SBarry Smith   */
361b00a9115SJed Brown   ierr     = PetscNewLog(pc,&jac);CHKERRQ(ierr);
3624b9ad928SBarry Smith   pc->data = (void*)jac;
3634b9ad928SBarry Smith 
3644b9ad928SBarry Smith   /*
3654b9ad928SBarry Smith      Initialize the pointers to vectors to ZERO; these will be used to store
3664b9ad928SBarry Smith      diagonal entries of the matrix for fast preconditioner application.
3674b9ad928SBarry Smith   */
3680a545947SLisandro Dalcin   jac->diag = NULL;
3694b9ad928SBarry Smith 
3704b9ad928SBarry Smith   /*
3714b9ad928SBarry Smith       Set the pointers for the functions that are provided above.
3724b9ad928SBarry Smith       Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
3734b9ad928SBarry Smith       are called, they will automatically call these functions.  Note we
3744b9ad928SBarry Smith       choose not to provide a couple of these functions since they are
3754b9ad928SBarry Smith       not needed.
3764b9ad928SBarry Smith   */
3770a545947SLisandro Dalcin   pc->ops->apply               = NULL; /*set depending on the block size */
3780a545947SLisandro Dalcin   pc->ops->applytranspose      = NULL;
3794b9ad928SBarry Smith   pc->ops->setup               = PCSetUp_PBJacobi;
3804b9ad928SBarry Smith   pc->ops->destroy             = PCDestroy_PBJacobi;
3810a545947SLisandro Dalcin   pc->ops->setfromoptions      = NULL;
382fa939db7SJed Brown   pc->ops->view                = PCView_PBJacobi;
3830a545947SLisandro Dalcin   pc->ops->applyrichardson     = NULL;
3840a545947SLisandro Dalcin   pc->ops->applysymmetricleft  = NULL;
3850a545947SLisandro Dalcin   pc->ops->applysymmetricright = NULL;
3864b9ad928SBarry Smith   PetscFunctionReturn(0);
3874b9ad928SBarry Smith }
388