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); 223*d7806518SHong Zhang if (A->errortype) pc->failedreason = (PCFailedReason)A->errortype; 224*d7806518SHong Zhang 22533d57670SJed Brown ierr = MatGetBlockSize(A,&jac->bs);CHKERRQ(ierr); 22633d57670SJed Brown jac->mbs = A->rmap->n/jac->bs; 227521d7252SBarry Smith switch (jac->bs) { 228bbead8a2SBarry Smith case 1: 229bbead8a2SBarry Smith pc->ops->apply = PCApply_PBJacobi_1; 230bbead8a2SBarry Smith break; 2314b9ad928SBarry Smith case 2: 2324b9ad928SBarry Smith pc->ops->apply = PCApply_PBJacobi_2; 2334b9ad928SBarry Smith break; 2344b9ad928SBarry Smith case 3: 2354b9ad928SBarry Smith pc->ops->apply = PCApply_PBJacobi_3; 2364b9ad928SBarry Smith break; 2374b9ad928SBarry Smith case 4: 2384b9ad928SBarry Smith pc->ops->apply = PCApply_PBJacobi_4; 2394b9ad928SBarry Smith break; 2404b9ad928SBarry Smith case 5: 2414b9ad928SBarry Smith pc->ops->apply = PCApply_PBJacobi_5; 2424b9ad928SBarry Smith break; 2430e1b4bd6SMark F. Adams case 6: 2440e1b4bd6SMark F. Adams pc->ops->apply = PCApply_PBJacobi_6; 2450e1b4bd6SMark F. Adams break; 2460a4ca348SMatthew G Knepley case 7: 2470a4ca348SMatthew G Knepley pc->ops->apply = PCApply_PBJacobi_7; 2480a4ca348SMatthew G Knepley break; 2494b9ad928SBarry Smith default: 250ce94432eSBarry Smith SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"not supported for block size %D",jac->bs); 2514b9ad928SBarry Smith } 2524b9ad928SBarry Smith PetscFunctionReturn(0); 2534b9ad928SBarry Smith } 2544b9ad928SBarry Smith /* -------------------------------------------------------------------------- */ 2554b9ad928SBarry Smith #undef __FUNCT__ 2564b9ad928SBarry Smith #define __FUNCT__ "PCDestroy_PBJacobi" 2576849ba73SBarry Smith static PetscErrorCode PCDestroy_PBJacobi(PC pc) 2584b9ad928SBarry Smith { 259dfbe8321SBarry Smith PetscErrorCode ierr; 2604b9ad928SBarry Smith 2614b9ad928SBarry Smith PetscFunctionBegin; 2624b9ad928SBarry Smith /* 2634b9ad928SBarry Smith Free the private data structure that was hanging off the PC 2644b9ad928SBarry Smith */ 265c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 2664b9ad928SBarry Smith PetscFunctionReturn(0); 2674b9ad928SBarry Smith } 268fa939db7SJed Brown 269fa939db7SJed Brown #undef __FUNCT__ 270fa939db7SJed Brown #define __FUNCT__ "PCView_PBJacobi" 271fa939db7SJed Brown static PetscErrorCode PCView_PBJacobi(PC pc,PetscViewer viewer) 272fa939db7SJed Brown { 273fa939db7SJed Brown PetscErrorCode ierr; 274fa939db7SJed Brown PC_PBJacobi *jac = (PC_PBJacobi*)pc->data; 275fa939db7SJed Brown PetscBool iascii; 276fa939db7SJed Brown 277fa939db7SJed Brown PetscFunctionBegin; 278251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 279fa939db7SJed Brown if (iascii) { 280fa939db7SJed Brown ierr = PetscViewerASCIIPrintf(viewer," point-block Jacobi: block size %D\n",jac->bs);CHKERRQ(ierr); 28111aeaf0aSBarry Smith } 282fa939db7SJed Brown PetscFunctionReturn(0); 283fa939db7SJed Brown } 284fa939db7SJed Brown 2854b9ad928SBarry Smith /* -------------------------------------------------------------------------- */ 28637a17b4dSBarry Smith /*MC 287422a814eSBarry Smith PCPBJACOBI - Point block Jacobi preconditioner 288422a814eSBarry Smith 289422a814eSBarry Smith 290422a814eSBarry Smith Notes: See PCJACOBI for point Jacobi preconditioning 291422a814eSBarry Smith 292422a814eSBarry Smith This works for AIJ and BAIJ matrices and uses the blocksize provided to the matrix 293422a814eSBarry Smith 294422a814eSBarry Smith Uses dense LU factorization with partial pivoting to invert the blocks; if a zero pivot 295422a814eSBarry Smith is detected a PETSc error is generated. 296422a814eSBarry Smith 297422a814eSBarry Smith Developer Notes: This should support the PCSetErrorIfFailure() flag set to PETSC_TRUE to allow 298422a814eSBarry Smith the factorization to continue even after a zero pivot is found resulting in a Nan and hence 299422a814eSBarry Smith terminating KSP with a KSP_DIVERGED_NANORIF allowing 300422a814eSBarry Smith a nonlinear solver/ODE integrator to recover without stopping the program as currently happens. 301422a814eSBarry Smith 302422a814eSBarry Smith Developer Note: Perhaps should provide an option that allows generation of a valid preconditioner 303422a814eSBarry Smith even if a block is singular as the PCJACOBI does. 30437a17b4dSBarry Smith 30537a17b4dSBarry Smith Level: beginner 30637a17b4dSBarry Smith 30737a17b4dSBarry Smith Concepts: point block Jacobi 30837a17b4dSBarry Smith 30937a17b4dSBarry Smith 310422a814eSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, PCJACOBI 31137a17b4dSBarry Smith 31237a17b4dSBarry Smith M*/ 31337a17b4dSBarry Smith 3144b9ad928SBarry Smith #undef __FUNCT__ 3154b9ad928SBarry Smith #define __FUNCT__ "PCCreate_PBJacobi" 3168cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_PBJacobi(PC pc) 3174b9ad928SBarry Smith { 3184b9ad928SBarry Smith PC_PBJacobi *jac; 319dfbe8321SBarry Smith PetscErrorCode ierr; 3204b9ad928SBarry Smith 3214b9ad928SBarry Smith PetscFunctionBegin; 3224b9ad928SBarry Smith /* 3234b9ad928SBarry Smith Creates the private data structure for this preconditioner and 3244b9ad928SBarry Smith attach it to the PC object. 3254b9ad928SBarry Smith */ 326b00a9115SJed Brown ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr); 3274b9ad928SBarry Smith pc->data = (void*)jac; 3284b9ad928SBarry Smith 3294b9ad928SBarry Smith /* 3304b9ad928SBarry Smith Initialize the pointers to vectors to ZERO; these will be used to store 3314b9ad928SBarry Smith diagonal entries of the matrix for fast preconditioner application. 3324b9ad928SBarry Smith */ 3334b9ad928SBarry Smith jac->diag = 0; 3344b9ad928SBarry Smith 3354b9ad928SBarry Smith /* 3364b9ad928SBarry Smith Set the pointers for the functions that are provided above. 3374b9ad928SBarry Smith Now when the user-level routines (such as PCApply(), PCDestroy(), etc.) 3384b9ad928SBarry Smith are called, they will automatically call these functions. Note we 3394b9ad928SBarry Smith choose not to provide a couple of these functions since they are 3404b9ad928SBarry Smith not needed. 3414b9ad928SBarry Smith */ 3424b9ad928SBarry Smith pc->ops->apply = 0; /*set depending on the block size */ 3434b9ad928SBarry Smith pc->ops->applytranspose = 0; 3444b9ad928SBarry Smith pc->ops->setup = PCSetUp_PBJacobi; 3454b9ad928SBarry Smith pc->ops->destroy = PCDestroy_PBJacobi; 3464b9ad928SBarry Smith pc->ops->setfromoptions = 0; 347fa939db7SJed Brown pc->ops->view = PCView_PBJacobi; 3484b9ad928SBarry Smith pc->ops->applyrichardson = 0; 3494b9ad928SBarry Smith pc->ops->applysymmetricleft = 0; 3504b9ad928SBarry Smith pc->ops->applysymmetricright = 0; 3514b9ad928SBarry Smith PetscFunctionReturn(0); 3524b9ad928SBarry Smith } 3534b9ad928SBarry Smith 3544b9ad928SBarry Smith 355