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 } 224*faff7d23SJed Brown 225*faff7d23SJed Brown static PetscErrorCode PCApply_PBJacobi_N(PC pc,Vec x,Vec y) 226*faff7d23SJed Brown { 227*faff7d23SJed Brown PC_PBJacobi *jac = (PC_PBJacobi*)pc->data; 228*faff7d23SJed Brown PetscErrorCode ierr; 229*faff7d23SJed Brown PetscInt i,j,k,m = jac->mbs,bs=jac->bs; 230*faff7d23SJed Brown const MatScalar *diag = jac->diag; 231*faff7d23SJed Brown const PetscScalar *xx; 232*faff7d23SJed Brown PetscScalar *yy; 233*faff7d23SJed Brown 234*faff7d23SJed Brown PetscFunctionBegin; 235*faff7d23SJed Brown ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 236*faff7d23SJed Brown ierr = VecGetArray(y,&yy);CHKERRQ(ierr); 237*faff7d23SJed Brown for (i=0; i<m; i++) { 238*faff7d23SJed Brown for (j=0; j<bs; j++) yy[i*bs+j] = 0.; 239*faff7d23SJed Brown for (j=0; j<bs; j++) { 240*faff7d23SJed Brown for (k=0; k<bs; k++) { 241*faff7d23SJed Brown yy[i*bs+k] += diag[k+bs*j]*xx[i*bs+j]; 242*faff7d23SJed Brown } 243*faff7d23SJed Brown } 244*faff7d23SJed Brown diag += bs*bs; 245*faff7d23SJed Brown } 246*faff7d23SJed Brown ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 247*faff7d23SJed Brown ierr = VecRestoreArray(y,&yy);CHKERRQ(ierr); 248*faff7d23SJed Brown ierr = PetscLogFlops(m*bs*(2*bs-1));CHKERRQ(ierr); 249*faff7d23SJed Brown PetscFunctionReturn(0); 250*faff7d23SJed Brown } 251*faff7d23SJed Brown 2524b9ad928SBarry Smith /* -------------------------------------------------------------------------- */ 2536849ba73SBarry Smith static PetscErrorCode PCSetUp_PBJacobi(PC pc) 2544b9ad928SBarry Smith { 2554b9ad928SBarry Smith PC_PBJacobi *jac = (PC_PBJacobi*)pc->data; 256dfbe8321SBarry Smith PetscErrorCode ierr; 2574b9ad928SBarry Smith Mat A = pc->pmat; 25800e125f8SBarry Smith MatFactorError err; 259539c167fSBarry Smith PetscInt nlocal; 2604b9ad928SBarry Smith 2614b9ad928SBarry Smith PetscFunctionBegin; 262bbead8a2SBarry Smith ierr = MatInvertBlockDiagonal(A,&jac->diag);CHKERRQ(ierr); 26300e125f8SBarry Smith ierr = MatFactorGetError(A,&err);CHKERRQ(ierr); 26400e125f8SBarry Smith if (err) pc->failedreason = (PCFailedReason)err; 265d7806518SHong Zhang 26633d57670SJed Brown ierr = MatGetBlockSize(A,&jac->bs);CHKERRQ(ierr); 267539c167fSBarry Smith ierr = MatGetLocalSize(A,&nlocal,NULL);CHKERRQ(ierr); 268539c167fSBarry Smith jac->mbs = nlocal/jac->bs; 269521d7252SBarry Smith switch (jac->bs) { 270bbead8a2SBarry Smith case 1: 271bbead8a2SBarry Smith pc->ops->apply = PCApply_PBJacobi_1; 272bbead8a2SBarry Smith break; 2734b9ad928SBarry Smith case 2: 2744b9ad928SBarry Smith pc->ops->apply = PCApply_PBJacobi_2; 2754b9ad928SBarry Smith break; 2764b9ad928SBarry Smith case 3: 2774b9ad928SBarry Smith pc->ops->apply = PCApply_PBJacobi_3; 2784b9ad928SBarry Smith break; 2794b9ad928SBarry Smith case 4: 2804b9ad928SBarry Smith pc->ops->apply = PCApply_PBJacobi_4; 2814b9ad928SBarry Smith break; 2824b9ad928SBarry Smith case 5: 2834b9ad928SBarry Smith pc->ops->apply = PCApply_PBJacobi_5; 2844b9ad928SBarry Smith break; 2850e1b4bd6SMark F. Adams case 6: 2860e1b4bd6SMark F. Adams pc->ops->apply = PCApply_PBJacobi_6; 2870e1b4bd6SMark F. Adams break; 2880a4ca348SMatthew G Knepley case 7: 2890a4ca348SMatthew G Knepley pc->ops->apply = PCApply_PBJacobi_7; 2900a4ca348SMatthew G Knepley break; 2914b9ad928SBarry Smith default: 292f79daf70SMark Lohry pc->ops->apply = PCApply_PBJacobi_N; 293f79daf70SMark Lohry break; 2944b9ad928SBarry Smith } 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 328422a814eSBarry Smith 32995452b02SPatrick Sanan Notes: 33095452b02SPatrick Sanan See PCJACOBI for point Jacobi preconditioning 331422a814eSBarry Smith 332422a814eSBarry Smith This works for AIJ and BAIJ matrices and uses the blocksize provided to the matrix 333422a814eSBarry Smith 334422a814eSBarry Smith Uses dense LU factorization with partial pivoting to invert the blocks; if a zero pivot 335422a814eSBarry Smith is detected a PETSc error is generated. 336422a814eSBarry Smith 33795452b02SPatrick Sanan Developer Notes: 33895452b02SPatrick Sanan This should support the PCSetErrorIfFailure() flag set to PETSC_TRUE to allow 339422a814eSBarry Smith the factorization to continue even after a zero pivot is found resulting in a Nan and hence 340422a814eSBarry Smith terminating KSP with a KSP_DIVERGED_NANORIF allowing 341422a814eSBarry Smith a nonlinear solver/ODE integrator to recover without stopping the program as currently happens. 342422a814eSBarry Smith 343422a814eSBarry Smith Developer Note: Perhaps should provide an option that allows generation of a valid preconditioner 344422a814eSBarry Smith even if a block is singular as the PCJACOBI does. 34537a17b4dSBarry Smith 34637a17b4dSBarry Smith Level: beginner 34737a17b4dSBarry Smith 34837a17b4dSBarry Smith 349422a814eSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, PCJACOBI 35037a17b4dSBarry Smith 35137a17b4dSBarry Smith M*/ 35237a17b4dSBarry Smith 3538cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PBJacobi(PC pc) 3544b9ad928SBarry Smith { 3554b9ad928SBarry Smith PC_PBJacobi *jac; 356dfbe8321SBarry Smith PetscErrorCode ierr; 3574b9ad928SBarry Smith 3584b9ad928SBarry Smith PetscFunctionBegin; 3594b9ad928SBarry Smith /* 3604b9ad928SBarry Smith Creates the private data structure for this preconditioner and 3614b9ad928SBarry Smith attach it to the PC object. 3624b9ad928SBarry Smith */ 363b00a9115SJed Brown ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr); 3644b9ad928SBarry Smith pc->data = (void*)jac; 3654b9ad928SBarry Smith 3664b9ad928SBarry Smith /* 3674b9ad928SBarry Smith Initialize the pointers to vectors to ZERO; these will be used to store 3684b9ad928SBarry Smith diagonal entries of the matrix for fast preconditioner application. 3694b9ad928SBarry Smith */ 3704b9ad928SBarry Smith jac->diag = 0; 3714b9ad928SBarry Smith 3724b9ad928SBarry Smith /* 3734b9ad928SBarry Smith Set the pointers for the functions that are provided above. 3744b9ad928SBarry Smith Now when the user-level routines (such as PCApply(), PCDestroy(), etc.) 3754b9ad928SBarry Smith are called, they will automatically call these functions. Note we 3764b9ad928SBarry Smith choose not to provide a couple of these functions since they are 3774b9ad928SBarry Smith not needed. 3784b9ad928SBarry Smith */ 3794b9ad928SBarry Smith pc->ops->apply = 0; /*set depending on the block size */ 3804b9ad928SBarry Smith pc->ops->applytranspose = 0; 3814b9ad928SBarry Smith pc->ops->setup = PCSetUp_PBJacobi; 3824b9ad928SBarry Smith pc->ops->destroy = PCDestroy_PBJacobi; 3834b9ad928SBarry Smith pc->ops->setfromoptions = 0; 384fa939db7SJed Brown pc->ops->view = PCView_PBJacobi; 3854b9ad928SBarry Smith pc->ops->applyrichardson = 0; 3864b9ad928SBarry Smith pc->ops->applysymmetricleft = 0; 3874b9ad928SBarry Smith pc->ops->applysymmetricright = 0; 3884b9ad928SBarry Smith PetscFunctionReturn(0); 3894b9ad928SBarry Smith } 3904b9ad928SBarry Smith 3914b9ad928SBarry Smith 392