xref: /petsc/src/ksp/pc/impls/pbjacobi/pbjacobi.c (revision 422a814ef4a731b8529cf3a6428db526d183e312)
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/matimpl.h>
8af0996ceSBarry Smith #include <petsc/private/pcimpl.h>   /*I "petscpc.h" I*/
94b9ad928SBarry Smith 
104b9ad928SBarry Smith /*
114b9ad928SBarry Smith    Private context (data structure) for the PBJacobi preconditioner.
124b9ad928SBarry Smith */
134b9ad928SBarry Smith typedef struct {
14713ccfa9SJed Brown   const MatScalar *diag;
15c1ac3661SBarry Smith   PetscInt        bs,mbs;
164b9ad928SBarry Smith } PC_PBJacobi;
174b9ad928SBarry Smith 
184b9ad928SBarry Smith 
194b9ad928SBarry Smith #undef __FUNCT__
20bbead8a2SBarry Smith #define __FUNCT__ "PCApply_PBJacobi_1"
21bbead8a2SBarry Smith static PetscErrorCode PCApply_PBJacobi_1(PC pc,Vec x,Vec y)
22bbead8a2SBarry Smith {
23bbead8a2SBarry Smith   PC_PBJacobi       *jac = (PC_PBJacobi*)pc->data;
24bbead8a2SBarry Smith   PetscErrorCode    ierr;
25bbead8a2SBarry Smith   PetscInt          i,m = jac->mbs;
26bbead8a2SBarry Smith   const MatScalar   *diag = jac->diag;
27bbead8a2SBarry Smith   const PetscScalar *xx;
28bbead8a2SBarry Smith   PetscScalar       *yy;
29bbead8a2SBarry Smith 
30bbead8a2SBarry Smith   PetscFunctionBegin;
31bbead8a2SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
32bbead8a2SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
332fa5cd67SKarl Rupp   for (i=0; i<m; i++) yy[i] = diag[i]*xx[i];
34bbead8a2SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
35bbead8a2SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
36bbead8a2SBarry Smith   ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr);
37bbead8a2SBarry Smith   PetscFunctionReturn(0);
38bbead8a2SBarry Smith }
39bbead8a2SBarry Smith 
40bbead8a2SBarry Smith #undef __FUNCT__
414b9ad928SBarry Smith #define __FUNCT__ "PCApply_PBJacobi_2"
426849ba73SBarry Smith static PetscErrorCode PCApply_PBJacobi_2(PC pc,Vec x,Vec y)
434b9ad928SBarry Smith {
444b9ad928SBarry Smith   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
45dfbe8321SBarry Smith   PetscErrorCode  ierr;
46c1ac3661SBarry Smith   PetscInt        i,m = jac->mbs;
4785f4f44aSBarry Smith   const MatScalar *diag = jac->diag;
480e666e78SToby Isaac   PetscScalar     x0,x1,*yy;
490e666e78SToby Isaac   const PetscScalar *xx;
504b9ad928SBarry Smith 
514b9ad928SBarry Smith   PetscFunctionBegin;
520e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
534b9ad928SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
544b9ad928SBarry Smith   for (i=0; i<m; i++) {
554b9ad928SBarry Smith     x0        = xx[2*i]; x1 = xx[2*i+1];
564b9ad928SBarry Smith     yy[2*i]   = diag[0]*x0 + diag[2]*x1;
574b9ad928SBarry Smith     yy[2*i+1] = diag[1]*x0 + diag[3]*x1;
584b9ad928SBarry Smith     diag     += 4;
594b9ad928SBarry Smith   }
600e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
614b9ad928SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
62dc0b31edSSatish Balay   ierr = PetscLogFlops(6.0*m);CHKERRQ(ierr);
634b9ad928SBarry Smith   PetscFunctionReturn(0);
644b9ad928SBarry Smith }
654b9ad928SBarry Smith #undef __FUNCT__
664b9ad928SBarry Smith #define __FUNCT__ "PCApply_PBJacobi_3"
676849ba73SBarry Smith static PetscErrorCode PCApply_PBJacobi_3(PC pc,Vec x,Vec y)
684b9ad928SBarry Smith {
694b9ad928SBarry Smith   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
70dfbe8321SBarry Smith   PetscErrorCode  ierr;
71c1ac3661SBarry Smith   PetscInt        i,m = jac->mbs;
7285f4f44aSBarry Smith   const MatScalar *diag = jac->diag;
730e666e78SToby Isaac   PetscScalar     x0,x1,x2,*yy;
740e666e78SToby Isaac   const PetscScalar *xx;
754b9ad928SBarry Smith 
764b9ad928SBarry Smith   PetscFunctionBegin;
770e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
784b9ad928SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
794b9ad928SBarry Smith   for (i=0; i<m; i++) {
804b9ad928SBarry Smith     x0 = xx[3*i]; x1 = xx[3*i+1]; x2 = xx[3*i+2];
812fa5cd67SKarl Rupp 
824b9ad928SBarry Smith     yy[3*i]   = diag[0]*x0 + diag[3]*x1 + diag[6]*x2;
834b9ad928SBarry Smith     yy[3*i+1] = diag[1]*x0 + diag[4]*x1 + diag[7]*x2;
844b9ad928SBarry Smith     yy[3*i+2] = diag[2]*x0 + diag[5]*x1 + diag[8]*x2;
854b9ad928SBarry Smith     diag     += 9;
864b9ad928SBarry Smith   }
870e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
884b9ad928SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
89dc0b31edSSatish Balay   ierr = PetscLogFlops(15.0*m);CHKERRQ(ierr);
904b9ad928SBarry Smith   PetscFunctionReturn(0);
914b9ad928SBarry Smith }
924b9ad928SBarry Smith #undef __FUNCT__
934b9ad928SBarry Smith #define __FUNCT__ "PCApply_PBJacobi_4"
946849ba73SBarry Smith static PetscErrorCode PCApply_PBJacobi_4(PC pc,Vec x,Vec y)
954b9ad928SBarry Smith {
964b9ad928SBarry Smith   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
97dfbe8321SBarry Smith   PetscErrorCode  ierr;
98c1ac3661SBarry Smith   PetscInt        i,m = jac->mbs;
9985f4f44aSBarry Smith   const MatScalar *diag = jac->diag;
1000e666e78SToby Isaac   PetscScalar     x0,x1,x2,x3,*yy;
1010e666e78SToby Isaac   const PetscScalar *xx;
1024b9ad928SBarry Smith 
1034b9ad928SBarry Smith   PetscFunctionBegin;
1040e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1054b9ad928SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1064b9ad928SBarry Smith   for (i=0; i<m; i++) {
1074b9ad928SBarry Smith     x0 = xx[4*i]; x1 = xx[4*i+1]; x2 = xx[4*i+2]; x3 = xx[4*i+3];
1082fa5cd67SKarl Rupp 
1094b9ad928SBarry Smith     yy[4*i]   = diag[0]*x0 + diag[4]*x1 + diag[8]*x2  + diag[12]*x3;
1104b9ad928SBarry Smith     yy[4*i+1] = diag[1]*x0 + diag[5]*x1 + diag[9]*x2  + diag[13]*x3;
1114b9ad928SBarry Smith     yy[4*i+2] = diag[2]*x0 + diag[6]*x1 + diag[10]*x2 + diag[14]*x3;
1124b9ad928SBarry Smith     yy[4*i+3] = diag[3]*x0 + diag[7]*x1 + diag[11]*x2 + diag[15]*x3;
1134b9ad928SBarry Smith     diag     += 16;
1144b9ad928SBarry Smith   }
1150e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1164b9ad928SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
117dc0b31edSSatish Balay   ierr = PetscLogFlops(28.0*m);CHKERRQ(ierr);
1184b9ad928SBarry Smith   PetscFunctionReturn(0);
1194b9ad928SBarry Smith }
1204b9ad928SBarry Smith #undef __FUNCT__
1214b9ad928SBarry Smith #define __FUNCT__ "PCApply_PBJacobi_5"
1226849ba73SBarry Smith static PetscErrorCode PCApply_PBJacobi_5(PC pc,Vec x,Vec y)
1234b9ad928SBarry Smith {
1244b9ad928SBarry Smith   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
125dfbe8321SBarry Smith   PetscErrorCode  ierr;
126c1ac3661SBarry Smith   PetscInt        i,m = jac->mbs;
12785f4f44aSBarry Smith   const MatScalar *diag = jac->diag;
1280e666e78SToby Isaac   PetscScalar     x0,x1,x2,x3,x4,*yy;
1290e666e78SToby Isaac   const PetscScalar *xx;
1304b9ad928SBarry Smith 
1314b9ad928SBarry Smith   PetscFunctionBegin;
1320e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1334b9ad928SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1344b9ad928SBarry Smith   for (i=0; i<m; i++) {
1354b9ad928SBarry 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];
1362fa5cd67SKarl Rupp 
1374b9ad928SBarry Smith     yy[5*i]   = diag[0]*x0 + diag[5]*x1 + diag[10]*x2  + diag[15]*x3 + diag[20]*x4;
1384b9ad928SBarry Smith     yy[5*i+1] = diag[1]*x0 + diag[6]*x1 + diag[11]*x2  + diag[16]*x3 + diag[21]*x4;
1394b9ad928SBarry Smith     yy[5*i+2] = diag[2]*x0 + diag[7]*x1 + diag[12]*x2 + diag[17]*x3 + diag[22]*x4;
1404b9ad928SBarry Smith     yy[5*i+3] = diag[3]*x0 + diag[8]*x1 + diag[13]*x2 + diag[18]*x3 + diag[23]*x4;
1414b9ad928SBarry Smith     yy[5*i+4] = diag[4]*x0 + diag[9]*x1 + diag[14]*x2 + diag[19]*x3 + diag[24]*x4;
1424b9ad928SBarry Smith     diag     += 25;
1434b9ad928SBarry Smith   }
1440e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1454b9ad928SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
146dc0b31edSSatish Balay   ierr = PetscLogFlops(45.0*m);CHKERRQ(ierr);
1474b9ad928SBarry Smith   PetscFunctionReturn(0);
1484b9ad928SBarry Smith }
1490e1b4bd6SMark F. Adams #undef __FUNCT__
1500e1b4bd6SMark F. Adams #define __FUNCT__ "PCApply_PBJacobi_6"
1510e1b4bd6SMark F. Adams static PetscErrorCode PCApply_PBJacobi_6(PC pc,Vec x,Vec y)
1520e1b4bd6SMark F. Adams {
1530e1b4bd6SMark F. Adams   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
1540e1b4bd6SMark F. Adams   PetscErrorCode  ierr;
1550e1b4bd6SMark F. Adams   PetscInt        i,m = jac->mbs;
1560e1b4bd6SMark F. Adams   const MatScalar *diag = jac->diag;
1570e666e78SToby Isaac   PetscScalar     x0,x1,x2,x3,x4,x5,*yy;
1580e666e78SToby Isaac   const PetscScalar *xx;
1590e1b4bd6SMark F. Adams 
1600e1b4bd6SMark F. Adams   PetscFunctionBegin;
1610e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1620e1b4bd6SMark F. Adams   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1630e1b4bd6SMark F. Adams   for (i=0; i<m; i++) {
1640e1b4bd6SMark 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];
1652fa5cd67SKarl Rupp 
1660e1b4bd6SMark F. Adams     yy[6*i]   = diag[0]*x0 + diag[6]*x1  + diag[12]*x2  + diag[18]*x3 + diag[24]*x4 + diag[30]*x5;
1670e1b4bd6SMark F. Adams     yy[6*i+1] = diag[1]*x0 + diag[7]*x1  + diag[13]*x2  + diag[19]*x3 + diag[25]*x4 + diag[31]*x5;
1680e1b4bd6SMark F. Adams     yy[6*i+2] = diag[2]*x0 + diag[8]*x1  + diag[14]*x2  + diag[20]*x3 + diag[26]*x4 + diag[32]*x5;
1690e1b4bd6SMark F. Adams     yy[6*i+3] = diag[3]*x0 + diag[9]*x1  + diag[15]*x2  + diag[21]*x3 + diag[27]*x4 + diag[33]*x5;
1700e1b4bd6SMark F. Adams     yy[6*i+4] = diag[4]*x0 + diag[10]*x1 + diag[16]*x2  + diag[22]*x3 + diag[28]*x4 + diag[34]*x5;
1710e1b4bd6SMark F. Adams     yy[6*i+5] = diag[5]*x0 + diag[11]*x1 + diag[17]*x2  + diag[23]*x3 + diag[29]*x4 + diag[35]*x5;
1720e1b4bd6SMark F. Adams     diag     += 36;
1730e1b4bd6SMark F. Adams   }
1740e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1750e1b4bd6SMark F. Adams   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1760e1b4bd6SMark F. Adams   ierr = PetscLogFlops(66.0*m);CHKERRQ(ierr);
1770e1b4bd6SMark F. Adams   PetscFunctionReturn(0);
1780e1b4bd6SMark F. Adams }
1790a4ca348SMatthew G Knepley #undef __FUNCT__
1800a4ca348SMatthew G Knepley #define __FUNCT__ "PCApply_PBJacobi_7"
1810a4ca348SMatthew G Knepley static PetscErrorCode PCApply_PBJacobi_7(PC pc,Vec x,Vec y)
1820a4ca348SMatthew G Knepley {
1830a4ca348SMatthew G Knepley   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
1840a4ca348SMatthew G Knepley   PetscErrorCode  ierr;
1850a4ca348SMatthew G Knepley   PetscInt        i,m = jac->mbs;
1860a4ca348SMatthew G Knepley   const MatScalar *diag = jac->diag;
1870e666e78SToby Isaac   PetscScalar     x0,x1,x2,x3,x4,x5,x6,*yy;
1880e666e78SToby Isaac   const PetscScalar *xx;
1890a4ca348SMatthew G Knepley 
1900a4ca348SMatthew G Knepley   PetscFunctionBegin;
1910e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1920a4ca348SMatthew G Knepley   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1930a4ca348SMatthew G Knepley   for (i=0; i<m; i++) {
1940a4ca348SMatthew 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];
1952fa5cd67SKarl Rupp 
1960a4ca348SMatthew 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;
1970a4ca348SMatthew 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;
1980a4ca348SMatthew 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;
1990a4ca348SMatthew 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;
2000a4ca348SMatthew 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;
2010a4ca348SMatthew 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;
2020a4ca348SMatthew 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;
2030a4ca348SMatthew G Knepley     diag     += 49;
2040a4ca348SMatthew G Knepley   }
2050e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
2060a4ca348SMatthew G Knepley   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
2070a4ca348SMatthew G Knepley   ierr = PetscLogFlops(80.0*m);CHKERRQ(ierr);
2080a4ca348SMatthew G Knepley   PetscFunctionReturn(0);
2090a4ca348SMatthew G Knepley }
2104b9ad928SBarry Smith /* -------------------------------------------------------------------------- */
2114b9ad928SBarry Smith #undef __FUNCT__
2124b9ad928SBarry Smith #define __FUNCT__ "PCSetUp_PBJacobi"
2136849ba73SBarry Smith static PetscErrorCode PCSetUp_PBJacobi(PC pc)
2144b9ad928SBarry Smith {
2154b9ad928SBarry Smith   PC_PBJacobi    *jac = (PC_PBJacobi*)pc->data;
216dfbe8321SBarry Smith   PetscErrorCode ierr;
2174b9ad928SBarry Smith   Mat            A = pc->pmat;
2184b9ad928SBarry Smith 
2194b9ad928SBarry Smith   PetscFunctionBegin;
220e32f2f54SBarry Smith   if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Supported only for square matrices and square storage");
221a1d92eedSBarry Smith 
222bbead8a2SBarry Smith   ierr = MatInvertBlockDiagonal(A,&jac->diag);CHKERRQ(ierr);
22333d57670SJed Brown   ierr = MatGetBlockSize(A,&jac->bs);CHKERRQ(ierr);
22433d57670SJed Brown   jac->mbs = A->rmap->n/jac->bs;
225521d7252SBarry Smith   switch (jac->bs) {
226bbead8a2SBarry Smith   case 1:
227bbead8a2SBarry Smith     pc->ops->apply = PCApply_PBJacobi_1;
228bbead8a2SBarry Smith     break;
2294b9ad928SBarry Smith   case 2:
2304b9ad928SBarry Smith     pc->ops->apply = PCApply_PBJacobi_2;
2314b9ad928SBarry Smith     break;
2324b9ad928SBarry Smith   case 3:
2334b9ad928SBarry Smith     pc->ops->apply = PCApply_PBJacobi_3;
2344b9ad928SBarry Smith     break;
2354b9ad928SBarry Smith   case 4:
2364b9ad928SBarry Smith     pc->ops->apply = PCApply_PBJacobi_4;
2374b9ad928SBarry Smith     break;
2384b9ad928SBarry Smith   case 5:
2394b9ad928SBarry Smith     pc->ops->apply = PCApply_PBJacobi_5;
2404b9ad928SBarry Smith     break;
2410e1b4bd6SMark F. Adams   case 6:
2420e1b4bd6SMark F. Adams     pc->ops->apply = PCApply_PBJacobi_6;
2430e1b4bd6SMark F. Adams     break;
2440a4ca348SMatthew G Knepley   case 7:
2450a4ca348SMatthew G Knepley     pc->ops->apply = PCApply_PBJacobi_7;
2460a4ca348SMatthew G Knepley     break;
2474b9ad928SBarry Smith   default:
248ce94432eSBarry Smith     SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"not supported for block size %D",jac->bs);
2494b9ad928SBarry Smith   }
2504b9ad928SBarry Smith   PetscFunctionReturn(0);
2514b9ad928SBarry Smith }
2524b9ad928SBarry Smith /* -------------------------------------------------------------------------- */
2534b9ad928SBarry Smith #undef __FUNCT__
2544b9ad928SBarry Smith #define __FUNCT__ "PCDestroy_PBJacobi"
2556849ba73SBarry Smith static PetscErrorCode PCDestroy_PBJacobi(PC pc)
2564b9ad928SBarry Smith {
257dfbe8321SBarry Smith   PetscErrorCode ierr;
2584b9ad928SBarry Smith 
2594b9ad928SBarry Smith   PetscFunctionBegin;
2604b9ad928SBarry Smith   /*
2614b9ad928SBarry Smith       Free the private data structure that was hanging off the PC
2624b9ad928SBarry Smith   */
263c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
2644b9ad928SBarry Smith   PetscFunctionReturn(0);
2654b9ad928SBarry Smith }
266fa939db7SJed Brown 
267fa939db7SJed Brown #undef __FUNCT__
268fa939db7SJed Brown #define __FUNCT__ "PCView_PBJacobi"
269fa939db7SJed Brown static PetscErrorCode PCView_PBJacobi(PC pc,PetscViewer viewer)
270fa939db7SJed Brown {
271fa939db7SJed Brown   PetscErrorCode ierr;
272fa939db7SJed Brown   PC_PBJacobi    *jac = (PC_PBJacobi*)pc->data;
273fa939db7SJed Brown   PetscBool      iascii;
274fa939db7SJed Brown 
275fa939db7SJed Brown   PetscFunctionBegin;
276251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
277fa939db7SJed Brown   if (iascii) {
278fa939db7SJed Brown     ierr = PetscViewerASCIIPrintf(viewer,"  point-block Jacobi: block size %D\n",jac->bs);CHKERRQ(ierr);
27911aeaf0aSBarry Smith   }
280fa939db7SJed Brown   PetscFunctionReturn(0);
281fa939db7SJed Brown }
282fa939db7SJed Brown 
2834b9ad928SBarry Smith /* -------------------------------------------------------------------------- */
28437a17b4dSBarry Smith /*MC
285*422a814eSBarry Smith      PCPBJACOBI - Point block Jacobi preconditioner
286*422a814eSBarry Smith 
287*422a814eSBarry Smith 
288*422a814eSBarry Smith    Notes: See PCJACOBI for point Jacobi preconditioning
289*422a814eSBarry Smith 
290*422a814eSBarry Smith    This works for AIJ and BAIJ matrices and uses the blocksize provided to the matrix
291*422a814eSBarry Smith 
292*422a814eSBarry Smith    Uses dense LU factorization with partial pivoting to invert the blocks; if a zero pivot
293*422a814eSBarry Smith    is detected a PETSc error is generated.
294*422a814eSBarry Smith 
295*422a814eSBarry Smith    Developer Notes: This should support the PCSetErrorIfFailure() flag set to PETSC_TRUE to allow
296*422a814eSBarry Smith    the factorization to continue even after a zero pivot is found resulting in a Nan and hence
297*422a814eSBarry Smith    terminating KSP with a KSP_DIVERGED_NANORIF allowing
298*422a814eSBarry Smith    a nonlinear solver/ODE integrator to recover without stopping the program as currently happens.
299*422a814eSBarry Smith 
300*422a814eSBarry Smith    Developer Note: Perhaps should provide an option that allows generation of a valid preconditioner
301*422a814eSBarry Smith    even if a block is singular as the PCJACOBI does.
30237a17b4dSBarry Smith 
30337a17b4dSBarry Smith    Level: beginner
30437a17b4dSBarry Smith 
30537a17b4dSBarry Smith   Concepts: point block Jacobi
30637a17b4dSBarry Smith 
30737a17b4dSBarry Smith 
308*422a814eSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC, PCJACOBI
30937a17b4dSBarry Smith 
31037a17b4dSBarry Smith M*/
31137a17b4dSBarry Smith 
3124b9ad928SBarry Smith #undef __FUNCT__
3134b9ad928SBarry Smith #define __FUNCT__ "PCCreate_PBJacobi"
3148cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PBJacobi(PC pc)
3154b9ad928SBarry Smith {
3164b9ad928SBarry Smith   PC_PBJacobi    *jac;
317dfbe8321SBarry Smith   PetscErrorCode ierr;
3184b9ad928SBarry Smith 
3194b9ad928SBarry Smith   PetscFunctionBegin;
3204b9ad928SBarry Smith   /*
3214b9ad928SBarry Smith      Creates the private data structure for this preconditioner and
3224b9ad928SBarry Smith      attach it to the PC object.
3234b9ad928SBarry Smith   */
324b00a9115SJed Brown   ierr     = PetscNewLog(pc,&jac);CHKERRQ(ierr);
3254b9ad928SBarry Smith   pc->data = (void*)jac;
3264b9ad928SBarry Smith 
3274b9ad928SBarry Smith   /*
3284b9ad928SBarry Smith      Initialize the pointers to vectors to ZERO; these will be used to store
3294b9ad928SBarry Smith      diagonal entries of the matrix for fast preconditioner application.
3304b9ad928SBarry Smith   */
3314b9ad928SBarry Smith   jac->diag = 0;
3324b9ad928SBarry Smith 
3334b9ad928SBarry Smith   /*
3344b9ad928SBarry Smith       Set the pointers for the functions that are provided above.
3354b9ad928SBarry Smith       Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
3364b9ad928SBarry Smith       are called, they will automatically call these functions.  Note we
3374b9ad928SBarry Smith       choose not to provide a couple of these functions since they are
3384b9ad928SBarry Smith       not needed.
3394b9ad928SBarry Smith   */
3404b9ad928SBarry Smith   pc->ops->apply               = 0; /*set depending on the block size */
3414b9ad928SBarry Smith   pc->ops->applytranspose      = 0;
3424b9ad928SBarry Smith   pc->ops->setup               = PCSetUp_PBJacobi;
3434b9ad928SBarry Smith   pc->ops->destroy             = PCDestroy_PBJacobi;
3444b9ad928SBarry Smith   pc->ops->setfromoptions      = 0;
345fa939db7SJed Brown   pc->ops->view                = PCView_PBJacobi;
3464b9ad928SBarry Smith   pc->ops->applyrichardson     = 0;
3474b9ad928SBarry Smith   pc->ops->applysymmetricleft  = 0;
3484b9ad928SBarry Smith   pc->ops->applysymmetricright = 0;
3494b9ad928SBarry Smith   PetscFunctionReturn(0);
3504b9ad928SBarry Smith }
3514b9ad928SBarry Smith 
3524b9ad928SBarry Smith 
353