xref: /petsc/src/ksp/pc/impls/pbjacobi/pbjacobi.c (revision 8cd12025f7ee175d04aa4745ff674ccb5a11d965)
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 
174b9ad928SBarry Smith 
18bbead8a2SBarry Smith static PetscErrorCode PCApply_PBJacobi_1(PC pc,Vec x,Vec y)
19bbead8a2SBarry Smith {
20bbead8a2SBarry Smith   PC_PBJacobi       *jac = (PC_PBJacobi*)pc->data;
21bbead8a2SBarry Smith   PetscErrorCode    ierr;
22bbead8a2SBarry Smith   PetscInt          i,m = jac->mbs;
23bbead8a2SBarry Smith   const MatScalar   *diag = jac->diag;
24bbead8a2SBarry Smith   const PetscScalar *xx;
25bbead8a2SBarry Smith   PetscScalar       *yy;
26bbead8a2SBarry Smith 
27bbead8a2SBarry Smith   PetscFunctionBegin;
28bbead8a2SBarry Smith   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
29bbead8a2SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
302fa5cd67SKarl Rupp   for (i=0; i<m; i++) yy[i] = diag[i]*xx[i];
31bbead8a2SBarry Smith   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
32bbead8a2SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
3379cd6d07SHong Zhang   ierr = PetscLogFlops(m);CHKERRQ(ierr);
34bbead8a2SBarry Smith   PetscFunctionReturn(0);
35bbead8a2SBarry Smith }
36bbead8a2SBarry Smith 
376849ba73SBarry Smith static PetscErrorCode PCApply_PBJacobi_2(PC pc,Vec x,Vec y)
384b9ad928SBarry Smith {
394b9ad928SBarry Smith   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
40dfbe8321SBarry Smith   PetscErrorCode  ierr;
41c1ac3661SBarry Smith   PetscInt        i,m = jac->mbs;
4285f4f44aSBarry Smith   const MatScalar *diag = jac->diag;
430e666e78SToby Isaac   PetscScalar     x0,x1,*yy;
440e666e78SToby Isaac   const PetscScalar *xx;
454b9ad928SBarry Smith 
464b9ad928SBarry Smith   PetscFunctionBegin;
470e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
484b9ad928SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
494b9ad928SBarry Smith   for (i=0; i<m; i++) {
504b9ad928SBarry Smith     x0        = xx[2*i]; x1 = xx[2*i+1];
514b9ad928SBarry Smith     yy[2*i]   = diag[0]*x0 + diag[2]*x1;
524b9ad928SBarry Smith     yy[2*i+1] = diag[1]*x0 + diag[3]*x1;
534b9ad928SBarry Smith     diag     += 4;
544b9ad928SBarry Smith   }
550e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
564b9ad928SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
57dc0b31edSSatish Balay   ierr = PetscLogFlops(6.0*m);CHKERRQ(ierr);
584b9ad928SBarry Smith   PetscFunctionReturn(0);
594b9ad928SBarry Smith }
606849ba73SBarry Smith static PetscErrorCode PCApply_PBJacobi_3(PC pc,Vec x,Vec y)
614b9ad928SBarry Smith {
624b9ad928SBarry Smith   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
63dfbe8321SBarry Smith   PetscErrorCode  ierr;
64c1ac3661SBarry Smith   PetscInt        i,m = jac->mbs;
6585f4f44aSBarry Smith   const MatScalar *diag = jac->diag;
660e666e78SToby Isaac   PetscScalar     x0,x1,x2,*yy;
670e666e78SToby Isaac   const PetscScalar *xx;
684b9ad928SBarry Smith 
694b9ad928SBarry Smith   PetscFunctionBegin;
700e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
714b9ad928SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
724b9ad928SBarry Smith   for (i=0; i<m; i++) {
734b9ad928SBarry Smith     x0 = xx[3*i]; x1 = xx[3*i+1]; x2 = xx[3*i+2];
742fa5cd67SKarl Rupp 
754b9ad928SBarry Smith     yy[3*i]   = diag[0]*x0 + diag[3]*x1 + diag[6]*x2;
764b9ad928SBarry Smith     yy[3*i+1] = diag[1]*x0 + diag[4]*x1 + diag[7]*x2;
774b9ad928SBarry Smith     yy[3*i+2] = diag[2]*x0 + diag[5]*x1 + diag[8]*x2;
784b9ad928SBarry Smith     diag     += 9;
794b9ad928SBarry Smith   }
800e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
814b9ad928SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
82dc0b31edSSatish Balay   ierr = PetscLogFlops(15.0*m);CHKERRQ(ierr);
834b9ad928SBarry Smith   PetscFunctionReturn(0);
844b9ad928SBarry Smith }
856849ba73SBarry Smith static PetscErrorCode PCApply_PBJacobi_4(PC pc,Vec x,Vec y)
864b9ad928SBarry Smith {
874b9ad928SBarry Smith   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
88dfbe8321SBarry Smith   PetscErrorCode  ierr;
89c1ac3661SBarry Smith   PetscInt        i,m = jac->mbs;
9085f4f44aSBarry Smith   const MatScalar *diag = jac->diag;
910e666e78SToby Isaac   PetscScalar     x0,x1,x2,x3,*yy;
920e666e78SToby Isaac   const PetscScalar *xx;
934b9ad928SBarry Smith 
944b9ad928SBarry Smith   PetscFunctionBegin;
950e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
964b9ad928SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
974b9ad928SBarry Smith   for (i=0; i<m; i++) {
984b9ad928SBarry Smith     x0 = xx[4*i]; x1 = xx[4*i+1]; x2 = xx[4*i+2]; x3 = xx[4*i+3];
992fa5cd67SKarl Rupp 
1004b9ad928SBarry Smith     yy[4*i]   = diag[0]*x0 + diag[4]*x1 + diag[8]*x2  + diag[12]*x3;
1014b9ad928SBarry Smith     yy[4*i+1] = diag[1]*x0 + diag[5]*x1 + diag[9]*x2  + diag[13]*x3;
1024b9ad928SBarry Smith     yy[4*i+2] = diag[2]*x0 + diag[6]*x1 + diag[10]*x2 + diag[14]*x3;
1034b9ad928SBarry Smith     yy[4*i+3] = diag[3]*x0 + diag[7]*x1 + diag[11]*x2 + diag[15]*x3;
1044b9ad928SBarry Smith     diag     += 16;
1054b9ad928SBarry Smith   }
1060e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1074b9ad928SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
108dc0b31edSSatish Balay   ierr = PetscLogFlops(28.0*m);CHKERRQ(ierr);
1094b9ad928SBarry Smith   PetscFunctionReturn(0);
1104b9ad928SBarry Smith }
1116849ba73SBarry Smith static PetscErrorCode PCApply_PBJacobi_5(PC pc,Vec x,Vec y)
1124b9ad928SBarry Smith {
1134b9ad928SBarry Smith   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
114dfbe8321SBarry Smith   PetscErrorCode  ierr;
115c1ac3661SBarry Smith   PetscInt        i,m = jac->mbs;
11685f4f44aSBarry Smith   const MatScalar *diag = jac->diag;
1170e666e78SToby Isaac   PetscScalar     x0,x1,x2,x3,x4,*yy;
1180e666e78SToby Isaac   const PetscScalar *xx;
1194b9ad928SBarry Smith 
1204b9ad928SBarry Smith   PetscFunctionBegin;
1210e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1224b9ad928SBarry Smith   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1234b9ad928SBarry Smith   for (i=0; i<m; i++) {
1244b9ad928SBarry 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];
1252fa5cd67SKarl Rupp 
1264b9ad928SBarry Smith     yy[5*i]   = diag[0]*x0 + diag[5]*x1 + diag[10]*x2  + diag[15]*x3 + diag[20]*x4;
1274b9ad928SBarry Smith     yy[5*i+1] = diag[1]*x0 + diag[6]*x1 + diag[11]*x2  + diag[16]*x3 + diag[21]*x4;
1284b9ad928SBarry Smith     yy[5*i+2] = diag[2]*x0 + diag[7]*x1 + diag[12]*x2 + diag[17]*x3 + diag[22]*x4;
1294b9ad928SBarry Smith     yy[5*i+3] = diag[3]*x0 + diag[8]*x1 + diag[13]*x2 + diag[18]*x3 + diag[23]*x4;
1304b9ad928SBarry Smith     yy[5*i+4] = diag[4]*x0 + diag[9]*x1 + diag[14]*x2 + diag[19]*x3 + diag[24]*x4;
1314b9ad928SBarry Smith     diag     += 25;
1324b9ad928SBarry Smith   }
1330e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1344b9ad928SBarry Smith   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
135dc0b31edSSatish Balay   ierr = PetscLogFlops(45.0*m);CHKERRQ(ierr);
1364b9ad928SBarry Smith   PetscFunctionReturn(0);
1374b9ad928SBarry Smith }
1380e1b4bd6SMark F. Adams static PetscErrorCode PCApply_PBJacobi_6(PC pc,Vec x,Vec y)
1390e1b4bd6SMark F. Adams {
1400e1b4bd6SMark F. Adams   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
1410e1b4bd6SMark F. Adams   PetscErrorCode  ierr;
1420e1b4bd6SMark F. Adams   PetscInt        i,m = jac->mbs;
1430e1b4bd6SMark F. Adams   const MatScalar *diag = jac->diag;
1440e666e78SToby Isaac   PetscScalar     x0,x1,x2,x3,x4,x5,*yy;
1450e666e78SToby Isaac   const PetscScalar *xx;
1460e1b4bd6SMark F. Adams 
1470e1b4bd6SMark F. Adams   PetscFunctionBegin;
1480e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1490e1b4bd6SMark F. Adams   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1500e1b4bd6SMark F. Adams   for (i=0; i<m; i++) {
1510e1b4bd6SMark 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];
1522fa5cd67SKarl Rupp 
1530e1b4bd6SMark F. Adams     yy[6*i]   = diag[0]*x0 + diag[6]*x1  + diag[12]*x2  + diag[18]*x3 + diag[24]*x4 + diag[30]*x5;
1540e1b4bd6SMark F. Adams     yy[6*i+1] = diag[1]*x0 + diag[7]*x1  + diag[13]*x2  + diag[19]*x3 + diag[25]*x4 + diag[31]*x5;
1550e1b4bd6SMark F. Adams     yy[6*i+2] = diag[2]*x0 + diag[8]*x1  + diag[14]*x2  + diag[20]*x3 + diag[26]*x4 + diag[32]*x5;
1560e1b4bd6SMark F. Adams     yy[6*i+3] = diag[3]*x0 + diag[9]*x1  + diag[15]*x2  + diag[21]*x3 + diag[27]*x4 + diag[33]*x5;
1570e1b4bd6SMark F. Adams     yy[6*i+4] = diag[4]*x0 + diag[10]*x1 + diag[16]*x2  + diag[22]*x3 + diag[28]*x4 + diag[34]*x5;
1580e1b4bd6SMark F. Adams     yy[6*i+5] = diag[5]*x0 + diag[11]*x1 + diag[17]*x2  + diag[23]*x3 + diag[29]*x4 + diag[35]*x5;
1590e1b4bd6SMark F. Adams     diag     += 36;
1600e1b4bd6SMark F. Adams   }
1610e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1620e1b4bd6SMark F. Adams   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
1630e1b4bd6SMark F. Adams   ierr = PetscLogFlops(66.0*m);CHKERRQ(ierr);
1640e1b4bd6SMark F. Adams   PetscFunctionReturn(0);
1650e1b4bd6SMark F. Adams }
1660a4ca348SMatthew G Knepley static PetscErrorCode PCApply_PBJacobi_7(PC pc,Vec x,Vec y)
1670a4ca348SMatthew G Knepley {
1680a4ca348SMatthew G Knepley   PC_PBJacobi     *jac = (PC_PBJacobi*)pc->data;
1690a4ca348SMatthew G Knepley   PetscErrorCode  ierr;
1700a4ca348SMatthew G Knepley   PetscInt        i,m = jac->mbs;
1710a4ca348SMatthew G Knepley   const MatScalar *diag = jac->diag;
1720e666e78SToby Isaac   PetscScalar     x0,x1,x2,x3,x4,x5,x6,*yy;
1730e666e78SToby Isaac   const PetscScalar *xx;
1740a4ca348SMatthew G Knepley 
1750a4ca348SMatthew G Knepley   PetscFunctionBegin;
1760e666e78SToby Isaac   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1770a4ca348SMatthew G Knepley   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
1780a4ca348SMatthew G Knepley   for (i=0; i<m; i++) {
1790a4ca348SMatthew 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];
1802fa5cd67SKarl Rupp 
1810a4ca348SMatthew 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;
1820a4ca348SMatthew 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;
1830a4ca348SMatthew 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;
1840a4ca348SMatthew 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;
1850a4ca348SMatthew 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;
1860a4ca348SMatthew 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;
1870a4ca348SMatthew 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;
1880a4ca348SMatthew G Knepley     diag     += 49;
1890a4ca348SMatthew G Knepley   }
1900e666e78SToby Isaac   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1910a4ca348SMatthew G Knepley   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
192054ddcb3SPierre Jolivet   ierr = PetscLogFlops(91.0*m);CHKERRQ(ierr); /* 2*bs2 - bs */
1930a4ca348SMatthew G Knepley   PetscFunctionReturn(0);
1940a4ca348SMatthew G Knepley }
195f79daf70SMark Lohry static PetscErrorCode PCApply_PBJacobi_N(PC pc,Vec x,Vec y)
196f79daf70SMark Lohry {
197f79daf70SMark Lohry   PC_PBJacobi       *jac = (PC_PBJacobi*)pc->data;
198f79daf70SMark Lohry   PetscErrorCode    ierr;
199f79daf70SMark Lohry   PetscInt          i,ib,jb;
200f79daf70SMark Lohry   const PetscInt    m = jac->mbs;
201f79daf70SMark Lohry   const PetscInt    bs = jac->bs;
202f79daf70SMark Lohry   const MatScalar   *diag = jac->diag;
203f79daf70SMark Lohry   PetscScalar       *yy;
204f79daf70SMark Lohry   const PetscScalar *xx;
205f79daf70SMark Lohry 
206f79daf70SMark Lohry   PetscFunctionBegin;
207f79daf70SMark Lohry   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
208f79daf70SMark Lohry   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
209f79daf70SMark Lohry   for (i=0; i<m; i++) {
210f79daf70SMark Lohry     for (ib=0; ib<bs; ib++){
211f79daf70SMark Lohry       PetscScalar rowsum = 0;
212f79daf70SMark Lohry       for (jb=0; jb<bs; jb++){
213f79daf70SMark Lohry         rowsum += diag[ib+jb*bs] * xx[bs*i+jb];
214f79daf70SMark Lohry       }
215f79daf70SMark Lohry       yy[bs*i+ib] = rowsum;
216f79daf70SMark Lohry     }
217f79daf70SMark Lohry     diag += bs*bs;
218f79daf70SMark Lohry   }
219f79daf70SMark Lohry   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
220f79daf70SMark Lohry   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
221054ddcb3SPierre Jolivet   ierr = PetscLogFlops((2.0*bs*bs-bs)*m);CHKERRQ(ierr); /* 2*bs2 - bs */
222f79daf70SMark Lohry   PetscFunctionReturn(0);
223f79daf70SMark Lohry }
224faff7d23SJed Brown 
225faff7d23SJed Brown static PetscErrorCode PCApply_PBJacobi_N(PC pc,Vec x,Vec y)
226faff7d23SJed Brown {
227faff7d23SJed Brown   PC_PBJacobi       *jac = (PC_PBJacobi*)pc->data;
228faff7d23SJed Brown   PetscErrorCode    ierr;
229faff7d23SJed Brown   PetscInt          i,j,k,m = jac->mbs,bs=jac->bs;
230faff7d23SJed Brown   const MatScalar   *diag = jac->diag;
231faff7d23SJed Brown   const PetscScalar *xx;
232faff7d23SJed Brown   PetscScalar       *yy;
233faff7d23SJed Brown 
234faff7d23SJed Brown   PetscFunctionBegin;
235faff7d23SJed Brown   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
236faff7d23SJed Brown   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
237faff7d23SJed Brown   for (i=0; i<m; i++) {
238faff7d23SJed Brown     for (j=0; j<bs; j++) yy[i*bs+j] = 0.;
239faff7d23SJed Brown     for (j=0; j<bs; j++) {
240faff7d23SJed Brown       for (k=0; k<bs; k++) {
241faff7d23SJed Brown         yy[i*bs+k] += diag[k+bs*j]*xx[i*bs+j];
242faff7d23SJed Brown       }
243faff7d23SJed Brown     }
244faff7d23SJed Brown     diag += bs*bs;
245faff7d23SJed Brown   }
246faff7d23SJed Brown   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
247faff7d23SJed Brown   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
248faff7d23SJed Brown   ierr = PetscLogFlops(m*bs*(2*bs-1));CHKERRQ(ierr);
249faff7d23SJed Brown   PetscFunctionReturn(0);
250faff7d23SJed Brown }
251faff7d23SJed Brown 
252*8cd12025SJed Brown static PetscErrorCode PCApplyTranspose_PBJacobi_N(PC pc,Vec x,Vec y)
253*8cd12025SJed Brown {
254*8cd12025SJed Brown   PC_PBJacobi       *jac = (PC_PBJacobi*)pc->data;
255*8cd12025SJed Brown   PetscErrorCode    ierr;
256*8cd12025SJed Brown   PetscInt          i,j,k,m = jac->mbs,bs=jac->bs;
257*8cd12025SJed Brown   const MatScalar   *diag = jac->diag;
258*8cd12025SJed Brown   const PetscScalar *xx;
259*8cd12025SJed Brown   PetscScalar       *yy;
260*8cd12025SJed Brown 
261*8cd12025SJed Brown   PetscFunctionBegin;
262*8cd12025SJed Brown   ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
263*8cd12025SJed Brown   ierr = VecGetArray(y,&yy);CHKERRQ(ierr);
264*8cd12025SJed Brown   for (i=0; i<m; i++) {
265*8cd12025SJed Brown     for (j=0; j<bs; j++) yy[i*bs+j] = 0.;
266*8cd12025SJed Brown     for (j=0; j<bs; j++) {
267*8cd12025SJed Brown       for (k=0; k<bs; k++) {
268*8cd12025SJed Brown         yy[i*bs+k] += diag[k*bs+j]*xx[i*bs+j];
269*8cd12025SJed Brown       }
270*8cd12025SJed Brown     }
271*8cd12025SJed Brown     diag += bs*bs;
272*8cd12025SJed Brown   }
273*8cd12025SJed Brown   ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
274*8cd12025SJed Brown   ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr);
275*8cd12025SJed Brown   ierr = PetscLogFlops(m*bs*(2*bs-1));CHKERRQ(ierr);
276*8cd12025SJed Brown   PetscFunctionReturn(0);
277*8cd12025SJed Brown }
278*8cd12025SJed Brown 
2794b9ad928SBarry Smith /* -------------------------------------------------------------------------- */
2806849ba73SBarry Smith static PetscErrorCode PCSetUp_PBJacobi(PC pc)
2814b9ad928SBarry Smith {
2824b9ad928SBarry Smith   PC_PBJacobi    *jac = (PC_PBJacobi*)pc->data;
283dfbe8321SBarry Smith   PetscErrorCode ierr;
2844b9ad928SBarry Smith   Mat            A = pc->pmat;
28500e125f8SBarry Smith   MatFactorError err;
286539c167fSBarry Smith   PetscInt       nlocal;
2874b9ad928SBarry Smith 
2884b9ad928SBarry Smith   PetscFunctionBegin;
289bbead8a2SBarry Smith   ierr = MatInvertBlockDiagonal(A,&jac->diag);CHKERRQ(ierr);
29000e125f8SBarry Smith   ierr = MatFactorGetError(A,&err);CHKERRQ(ierr);
29100e125f8SBarry Smith   if (err) pc->failedreason = (PCFailedReason)err;
292d7806518SHong Zhang 
29333d57670SJed Brown   ierr = MatGetBlockSize(A,&jac->bs);CHKERRQ(ierr);
294539c167fSBarry Smith   ierr = MatGetLocalSize(A,&nlocal,NULL);CHKERRQ(ierr);
295539c167fSBarry Smith   jac->mbs = nlocal/jac->bs;
296521d7252SBarry Smith   switch (jac->bs) {
297bbead8a2SBarry Smith   case 1:
298bbead8a2SBarry Smith     pc->ops->apply = PCApply_PBJacobi_1;
299bbead8a2SBarry Smith     break;
3004b9ad928SBarry Smith   case 2:
3014b9ad928SBarry Smith     pc->ops->apply = PCApply_PBJacobi_2;
3024b9ad928SBarry Smith     break;
3034b9ad928SBarry Smith   case 3:
3044b9ad928SBarry Smith     pc->ops->apply = PCApply_PBJacobi_3;
3054b9ad928SBarry Smith     break;
3064b9ad928SBarry Smith   case 4:
3074b9ad928SBarry Smith     pc->ops->apply = PCApply_PBJacobi_4;
3084b9ad928SBarry Smith     break;
3094b9ad928SBarry Smith   case 5:
3104b9ad928SBarry Smith     pc->ops->apply = PCApply_PBJacobi_5;
3114b9ad928SBarry Smith     break;
3120e1b4bd6SMark F. Adams   case 6:
3130e1b4bd6SMark F. Adams     pc->ops->apply = PCApply_PBJacobi_6;
3140e1b4bd6SMark F. Adams     break;
3150a4ca348SMatthew G Knepley   case 7:
3160a4ca348SMatthew G Knepley     pc->ops->apply = PCApply_PBJacobi_7;
3170a4ca348SMatthew G Knepley     break;
3184b9ad928SBarry Smith   default:
319f79daf70SMark Lohry     pc->ops->apply = PCApply_PBJacobi_N;
320f79daf70SMark Lohry     break;
3214b9ad928SBarry Smith   }
322*8cd12025SJed Brown   pc->ops->applytranspose = PCApplyTranspose_PBJacobi_N;
3234b9ad928SBarry Smith   PetscFunctionReturn(0);
3244b9ad928SBarry Smith }
3254b9ad928SBarry Smith /* -------------------------------------------------------------------------- */
3266849ba73SBarry Smith static PetscErrorCode PCDestroy_PBJacobi(PC pc)
3274b9ad928SBarry Smith {
328dfbe8321SBarry Smith   PetscErrorCode ierr;
3294b9ad928SBarry Smith 
3304b9ad928SBarry Smith   PetscFunctionBegin;
3314b9ad928SBarry Smith   /*
3324b9ad928SBarry Smith       Free the private data structure that was hanging off the PC
3334b9ad928SBarry Smith   */
334c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
3354b9ad928SBarry Smith   PetscFunctionReturn(0);
3364b9ad928SBarry Smith }
337fa939db7SJed Brown 
338fa939db7SJed Brown static PetscErrorCode PCView_PBJacobi(PC pc,PetscViewer viewer)
339fa939db7SJed Brown {
340fa939db7SJed Brown   PetscErrorCode ierr;
341fa939db7SJed Brown   PC_PBJacobi    *jac = (PC_PBJacobi*)pc->data;
342fa939db7SJed Brown   PetscBool      iascii;
343fa939db7SJed Brown 
344fa939db7SJed Brown   PetscFunctionBegin;
345251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
346fa939db7SJed Brown   if (iascii) {
347efd4aadfSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  point-block size %D\n",jac->bs);CHKERRQ(ierr);
34811aeaf0aSBarry Smith   }
349fa939db7SJed Brown   PetscFunctionReturn(0);
350fa939db7SJed Brown }
351fa939db7SJed Brown 
3524b9ad928SBarry Smith /* -------------------------------------------------------------------------- */
35337a17b4dSBarry Smith /*MC
354422a814eSBarry Smith      PCPBJACOBI - Point block Jacobi preconditioner
355422a814eSBarry Smith 
356422a814eSBarry Smith 
35795452b02SPatrick Sanan    Notes:
35895452b02SPatrick Sanan     See PCJACOBI for point Jacobi preconditioning
359422a814eSBarry Smith 
360422a814eSBarry Smith    This works for AIJ and BAIJ matrices and uses the blocksize provided to the matrix
361422a814eSBarry Smith 
362422a814eSBarry Smith    Uses dense LU factorization with partial pivoting to invert the blocks; if a zero pivot
363422a814eSBarry Smith    is detected a PETSc error is generated.
364422a814eSBarry Smith 
36595452b02SPatrick Sanan    Developer Notes:
36695452b02SPatrick Sanan     This should support the PCSetErrorIfFailure() flag set to PETSC_TRUE to allow
367422a814eSBarry Smith    the factorization to continue even after a zero pivot is found resulting in a Nan and hence
368422a814eSBarry Smith    terminating KSP with a KSP_DIVERGED_NANORIF allowing
369422a814eSBarry Smith    a nonlinear solver/ODE integrator to recover without stopping the program as currently happens.
370422a814eSBarry Smith 
371422a814eSBarry Smith    Developer Note: Perhaps should provide an option that allows generation of a valid preconditioner
372422a814eSBarry Smith    even if a block is singular as the PCJACOBI does.
37337a17b4dSBarry Smith 
37437a17b4dSBarry Smith    Level: beginner
37537a17b4dSBarry Smith 
37637a17b4dSBarry Smith 
377422a814eSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC, PCJACOBI
37837a17b4dSBarry Smith 
37937a17b4dSBarry Smith M*/
38037a17b4dSBarry Smith 
3818cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PBJacobi(PC pc)
3824b9ad928SBarry Smith {
3834b9ad928SBarry Smith   PC_PBJacobi    *jac;
384dfbe8321SBarry Smith   PetscErrorCode ierr;
3854b9ad928SBarry Smith 
3864b9ad928SBarry Smith   PetscFunctionBegin;
3874b9ad928SBarry Smith   /*
3884b9ad928SBarry Smith      Creates the private data structure for this preconditioner and
3894b9ad928SBarry Smith      attach it to the PC object.
3904b9ad928SBarry Smith   */
391b00a9115SJed Brown   ierr     = PetscNewLog(pc,&jac);CHKERRQ(ierr);
3924b9ad928SBarry Smith   pc->data = (void*)jac;
3934b9ad928SBarry Smith 
3944b9ad928SBarry Smith   /*
3954b9ad928SBarry Smith      Initialize the pointers to vectors to ZERO; these will be used to store
3964b9ad928SBarry Smith      diagonal entries of the matrix for fast preconditioner application.
3974b9ad928SBarry Smith   */
3984b9ad928SBarry Smith   jac->diag = 0;
3994b9ad928SBarry Smith 
4004b9ad928SBarry Smith   /*
4014b9ad928SBarry Smith       Set the pointers for the functions that are provided above.
4024b9ad928SBarry Smith       Now when the user-level routines (such as PCApply(), PCDestroy(), etc.)
4034b9ad928SBarry Smith       are called, they will automatically call these functions.  Note we
4044b9ad928SBarry Smith       choose not to provide a couple of these functions since they are
4054b9ad928SBarry Smith       not needed.
4064b9ad928SBarry Smith   */
4074b9ad928SBarry Smith   pc->ops->apply               = 0; /*set depending on the block size */
4084b9ad928SBarry Smith   pc->ops->applytranspose      = 0;
4094b9ad928SBarry Smith   pc->ops->setup               = PCSetUp_PBJacobi;
4104b9ad928SBarry Smith   pc->ops->destroy             = PCDestroy_PBJacobi;
4114b9ad928SBarry Smith   pc->ops->setfromoptions      = 0;
412fa939db7SJed Brown   pc->ops->view                = PCView_PBJacobi;
4134b9ad928SBarry Smith   pc->ops->applyrichardson     = 0;
4144b9ad928SBarry Smith   pc->ops->applysymmetricleft  = 0;
4154b9ad928SBarry Smith   pc->ops->applysymmetricright = 0;
4164b9ad928SBarry Smith   PetscFunctionReturn(0);
4174b9ad928SBarry Smith }
4184b9ad928SBarry Smith 
4194b9ad928SBarry Smith 
420