15170378fSJakub Kruzik #include <../src/ksp/pc/impls/deflation/deflation.h> /*I "petscksp.h" I*/ 2e53e0a0dSJakub Kruzik 3e53e0a0dSJakub Kruzik PetscScalar db2[] = {0.7071067811865476,0.7071067811865476}; 4e53e0a0dSJakub Kruzik 5e53e0a0dSJakub Kruzik PetscScalar db4[] = {-0.12940952255092145,0.22414386804185735,0.836516303737469,0.48296291314469025}; 6e53e0a0dSJakub Kruzik 7e53e0a0dSJakub Kruzik PetscScalar db8[] = {-0.010597401784997278, 8e53e0a0dSJakub Kruzik 0.032883011666982945, 9e53e0a0dSJakub Kruzik 0.030841381835986965, 10e53e0a0dSJakub Kruzik -0.18703481171888114, 11e53e0a0dSJakub Kruzik -0.02798376941698385, 12e53e0a0dSJakub Kruzik 0.6308807679295904, 13e53e0a0dSJakub Kruzik 0.7148465705525415, 14e53e0a0dSJakub Kruzik 0.23037781330885523}; 15e53e0a0dSJakub Kruzik 16e53e0a0dSJakub Kruzik PetscScalar db16[] = {-0.00011747678400228192, 17e53e0a0dSJakub Kruzik 0.0006754494059985568, 18e53e0a0dSJakub Kruzik -0.0003917403729959771, 19e53e0a0dSJakub Kruzik -0.00487035299301066, 20e53e0a0dSJakub Kruzik 0.008746094047015655, 21e53e0a0dSJakub Kruzik 0.013981027917015516, 22e53e0a0dSJakub Kruzik -0.04408825393106472, 23e53e0a0dSJakub Kruzik -0.01736930100202211, 24e53e0a0dSJakub Kruzik 0.128747426620186, 25e53e0a0dSJakub Kruzik 0.00047248457399797254, 26e53e0a0dSJakub Kruzik -0.2840155429624281, 27e53e0a0dSJakub Kruzik -0.015829105256023893, 28e53e0a0dSJakub Kruzik 0.5853546836548691, 29e53e0a0dSJakub Kruzik 0.6756307362980128, 30e53e0a0dSJakub Kruzik 0.3128715909144659, 31e53e0a0dSJakub Kruzik 0.05441584224308161}; 32e53e0a0dSJakub Kruzik 33e53e0a0dSJakub Kruzik PetscScalar biorth22[] = {0.0, 34e53e0a0dSJakub Kruzik -0.1767766952966369, 35e53e0a0dSJakub Kruzik 0.3535533905932738, 36e53e0a0dSJakub Kruzik 1.0606601717798214, 37e53e0a0dSJakub Kruzik 0.3535533905932738, 38e53e0a0dSJakub Kruzik -0.1767766952966369}; 39e53e0a0dSJakub Kruzik 4065149469SJakub Kruzik PetscScalar meyer[] = {0.0,-1.009999956941423e-12,8.519459636796214e-09,-1.111944952595278e-08,-1.0798819539621958e-08,6.066975741351135e-08,-1.0866516536735883e-07,8.200680650386481e-08,1.1783004497663934e-07,-5.506340565252278e-07,1.1307947017916706e-06,-1.489549216497156e-06,7.367572885903746e-07,3.20544191334478e-06,-1.6312699734552807e-05,6.554305930575149e-05,-0.0006011502343516092,-0.002704672124643725,0.002202534100911002,0.006045814097323304,-0.006387718318497156,-0.011061496392513451,0.015270015130934803,0.017423434103729693,-0.03213079399021176,-0.024348745906078023,0.0637390243228016,0.030655091960824263,-0.13284520043622938,-0.035087555656258346,0.44459300275757724,0.7445855923188063,0.44459300275757724,-0.035087555656258346,-0.13284520043622938,0.030655091960824263,0.0637390243228016,-0.024348745906078023,-0.03213079399021176,0.017423434103729693,0.015270015130934803,-0.011061496392513451,-0.006387718318497156,0.006045814097323304,0.002202534100911002,-0.002704672124643725,-0.0006011502343516092,6.554305930575149e-05,-1.6312699734552807e-05,3.20544191334478e-06,7.367572885903746e-07,-1.489549216497156e-06,1.1307947017916706e-06,-5.506340565252278e-07,1.1783004497663934e-07,8.200680650386481e-08,-1.0866516536735883e-07,6.066975741351135e-08,-1.0798819539621958e-08,-1.111944952595278e-08,8.519459636796214e-09,-1.009999956941423e-12}; 41e53e0a0dSJakub Kruzik 42e53e0a0dSJakub Kruzik static PetscErrorCode PCDeflationCreateSpaceWave(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,PetscInt ncoeffs,PetscScalar *coeffs,PetscBool trunc,Mat *H) 43e53e0a0dSJakub Kruzik { 44e53e0a0dSJakub Kruzik Mat defl; 45e53e0a0dSJakub Kruzik PetscInt i,j,k,ilo,ihi,*Iidx; 46e53e0a0dSJakub Kruzik 47e53e0a0dSJakub Kruzik PetscFunctionBegin; 489566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(ncoeffs,&Iidx)); 49e53e0a0dSJakub Kruzik 509566063dSJacob Faibussowitsch PetscCall(MatCreate(comm,&defl)); 519566063dSJacob Faibussowitsch PetscCall(MatSetSizes(defl,m,n,M,N)); 529566063dSJacob Faibussowitsch PetscCall(MatSetUp(defl)); 539566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(defl,ncoeffs,NULL)); 549566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(defl,ncoeffs,NULL,ncoeffs,NULL)); 559566063dSJacob Faibussowitsch PetscCall(MatSetOption(defl,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE)); 569566063dSJacob Faibussowitsch PetscCall(MatSetOption(defl,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE)); 57e53e0a0dSJakub Kruzik 58e53e0a0dSJakub Kruzik /* Alg 735 Taswell: fvecmat */ 59e53e0a0dSJakub Kruzik k = ncoeffs -2; 60e53e0a0dSJakub Kruzik if (trunc) k = k/2; 61e53e0a0dSJakub Kruzik 629566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(defl,&ilo,&ihi)); 63e53e0a0dSJakub Kruzik for (i=0; i<ncoeffs; i++) { 64e53e0a0dSJakub Kruzik Iidx[i] = i+ilo*2 -k; 65e53e0a0dSJakub Kruzik if (Iidx[i] >= N) Iidx[i] = PETSC_MIN_INT; 66e53e0a0dSJakub Kruzik } 67e53e0a0dSJakub Kruzik for (i=ilo; i<ihi; i++) { 689566063dSJacob Faibussowitsch PetscCall(MatSetValues(defl,1,&i,ncoeffs,Iidx,coeffs,INSERT_VALUES)); 69e53e0a0dSJakub Kruzik for (j=0; j<ncoeffs; j++) { 70e53e0a0dSJakub Kruzik Iidx[j] += 2; 71e53e0a0dSJakub Kruzik if (Iidx[j] >= N) Iidx[j] = PETSC_MIN_INT; 72e53e0a0dSJakub Kruzik } 73e53e0a0dSJakub Kruzik } 74e53e0a0dSJakub Kruzik 759566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(defl,MAT_FINAL_ASSEMBLY)); 769566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(defl,MAT_FINAL_ASSEMBLY)); 77e53e0a0dSJakub Kruzik 789566063dSJacob Faibussowitsch PetscCall(PetscFree(Iidx)); 79e53e0a0dSJakub Kruzik *H = defl; 80e53e0a0dSJakub Kruzik PetscFunctionReturn(0); 81e53e0a0dSJakub Kruzik } 82e53e0a0dSJakub Kruzik 83e53e0a0dSJakub Kruzik PetscErrorCode PCDeflationGetSpaceHaar(PC pc,Mat *W,PetscInt size) 84e53e0a0dSJakub Kruzik { 85e53e0a0dSJakub Kruzik Mat A,defl; 86e53e0a0dSJakub Kruzik PetscInt i,j,len,ilo,ihi,*Iidx,m,M; 879e56ec8aSJakub Kruzik PetscScalar *col,val; 88e53e0a0dSJakub Kruzik 89e53e0a0dSJakub Kruzik PetscFunctionBegin; 90e53e0a0dSJakub Kruzik /* Haar basis wavelet, level=size */ 91e53e0a0dSJakub Kruzik len = pow(2,size); 929566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(len,&col,len,&Iidx)); 93e53e0a0dSJakub Kruzik val = 1./pow(2,size/2.); 94e53e0a0dSJakub Kruzik for (i=0; i<len; i++) col[i] = val; 95e53e0a0dSJakub Kruzik 969566063dSJacob Faibussowitsch PetscCall(PCGetOperators(pc,NULL,&A)); 979566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A,&m,NULL)); 989566063dSJacob Faibussowitsch PetscCall(MatGetSize(A,&M,NULL)); 999566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&defl)); 1009566063dSJacob Faibussowitsch PetscCall(MatSetSizes(defl,m,PETSC_DECIDE,M,PetscCeilInt(M,len))); 1019566063dSJacob Faibussowitsch PetscCall(MatSetUp(defl)); 1029566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(defl,size,NULL)); 1039566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(defl,size,NULL,size,NULL)); 1049566063dSJacob Faibussowitsch PetscCall(MatSetOption(defl,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE)); 105e53e0a0dSJakub Kruzik 1069566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRangeColumn(defl,&ilo,&ihi)); 107e53e0a0dSJakub Kruzik for (i=0; i<len; i++) Iidx[i] = i+ilo*len; 108faa75363SBarry Smith if (M%len && ihi == PetscCeilInt(M,len)) ihi -= 1; 109e53e0a0dSJakub Kruzik for (i=ilo; i<ihi; i++) { 1109566063dSJacob Faibussowitsch PetscCall(MatSetValues(defl,len,Iidx,1,&i,col,INSERT_VALUES)); 111e53e0a0dSJakub Kruzik for (j=0; j<len; j++) Iidx[j] += len; 112e53e0a0dSJakub Kruzik } 113faa75363SBarry Smith if (M%len && ihi+1 == PetscCeilInt(M,len)) { 114e53e0a0dSJakub Kruzik len = M%len; 115e53e0a0dSJakub Kruzik val = 1./pow(pow(2,len),0.5); 116e53e0a0dSJakub Kruzik for (i=0; i<len; i++) col[i] = val; 1179566063dSJacob Faibussowitsch PetscCall(MatSetValues(defl,len,Iidx,1,&ihi,col,INSERT_VALUES)); 118e53e0a0dSJakub Kruzik } 119e53e0a0dSJakub Kruzik 1209566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(defl,MAT_FINAL_ASSEMBLY)); 1219566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(defl,MAT_FINAL_ASSEMBLY)); 122e53e0a0dSJakub Kruzik 1239566063dSJacob Faibussowitsch PetscCall(PetscFree2(col,Iidx)); 124e53e0a0dSJakub Kruzik *W = defl; 125e53e0a0dSJakub Kruzik PetscFunctionReturn(0); 126e53e0a0dSJakub Kruzik } 127e53e0a0dSJakub Kruzik 128e53e0a0dSJakub Kruzik PetscErrorCode PCDeflationGetSpaceWave(PC pc,Mat *W,PetscInt size,PetscInt ncoeffs,PetscScalar *coeffs,PetscBool trunc) 129e53e0a0dSJakub Kruzik { 130e53e0a0dSJakub Kruzik Mat A,*H,defl; 131e53e0a0dSJakub Kruzik PetscInt i,m,M,Mdefl,Ndefl; 132e53e0a0dSJakub Kruzik MPI_Comm comm; 133e53e0a0dSJakub Kruzik 134e53e0a0dSJakub Kruzik PetscFunctionBegin; 1359566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)pc,&comm)); 1369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size,&H)); 1379566063dSJacob Faibussowitsch PetscCall(PCGetOperators(pc,&A,NULL)); 1389566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A,&m,NULL)); 1399566063dSJacob Faibussowitsch PetscCall(MatGetSize(A,&M,NULL)); 140e53e0a0dSJakub Kruzik Mdefl = M; 141e53e0a0dSJakub Kruzik Ndefl = M; 142e53e0a0dSJakub Kruzik for (i=0; i<size; i++) { 143e53e0a0dSJakub Kruzik if (Mdefl%2) { 14420cd032fSJakub Kruzik if (trunc) Mdefl = (PetscInt)PetscCeilReal(Mdefl/2.); 14520cd032fSJakub Kruzik else Mdefl = (PetscInt)PetscFloorReal((ncoeffs+Mdefl-1)/2.); 14620cd032fSJakub Kruzik } else Mdefl = Mdefl/2; 1479566063dSJacob Faibussowitsch PetscCall(PCDeflationCreateSpaceWave(comm,PETSC_DECIDE,m,Mdefl,Ndefl,ncoeffs,coeffs,trunc,&H[i])); 1489566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(H[i],&m,NULL)); 149e53e0a0dSJakub Kruzik Ndefl = Mdefl; 150e53e0a0dSJakub Kruzik } 1519566063dSJacob Faibussowitsch PetscCall(MatCreateComposite(comm,size,H,&defl)); 1529566063dSJacob Faibussowitsch PetscCall(MatCompositeSetType(defl,MAT_COMPOSITE_MULTIPLICATIVE)); 153e53e0a0dSJakub Kruzik *W = defl; 154e53e0a0dSJakub Kruzik 155e53e0a0dSJakub Kruzik for (i=0; i<size; i++) { 1569566063dSJacob Faibussowitsch PetscCall(MatDestroy(&H[i])); 157e53e0a0dSJakub Kruzik } 1589566063dSJacob Faibussowitsch PetscCall(PetscFree(H)); 159e53e0a0dSJakub Kruzik PetscFunctionReturn(0); 160e53e0a0dSJakub Kruzik } 161e53e0a0dSJakub Kruzik 162e53e0a0dSJakub Kruzik PetscErrorCode PCDeflationGetSpaceAggregation(PC pc,Mat *W) 163e53e0a0dSJakub Kruzik { 164e53e0a0dSJakub Kruzik Mat A,defl; 1657b3faf33SJakub Kruzik PetscInt i,ilo,ihi,*Iidx,M; 1667b3faf33SJakub Kruzik PetscMPIInt m; 1679e56ec8aSJakub Kruzik PetscScalar *col; 168e53e0a0dSJakub Kruzik MPI_Comm comm; 169e53e0a0dSJakub Kruzik 170e53e0a0dSJakub Kruzik PetscFunctionBegin; 1719566063dSJacob Faibussowitsch PetscCall(PCGetOperators(pc,&A,NULL)); 1729566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRangeColumn(A,&ilo,&ihi)); 1739566063dSJacob Faibussowitsch PetscCall(MatGetSize(A,&M,NULL)); 1749566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)A,&comm)); 1759566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm,&m)); 1769566063dSJacob Faibussowitsch PetscCall(MatCreate(comm,&defl)); 1779566063dSJacob Faibussowitsch PetscCall(MatSetSizes(defl,ihi-ilo,1,M,m)); 1789566063dSJacob Faibussowitsch PetscCall(MatSetUp(defl)); 1799566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(defl,1,NULL)); 1809566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(defl,1,NULL,0,NULL)); 1819566063dSJacob Faibussowitsch PetscCall(MatSetOption(defl,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE)); 1829566063dSJacob Faibussowitsch PetscCall(MatSetOption(defl,MAT_NO_OFF_PROC_ENTRIES,PETSC_TRUE)); 183e53e0a0dSJakub Kruzik 1849566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(ihi-ilo,&col,ihi-ilo,&Iidx)); 185e53e0a0dSJakub Kruzik for (i=ilo; i<ihi; i++) { 186e53e0a0dSJakub Kruzik Iidx[i-ilo] = i; 187e53e0a0dSJakub Kruzik col[i-ilo] = 1; 188e53e0a0dSJakub Kruzik } 1899566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&m)); 1907b3faf33SJakub Kruzik i = m; 1919566063dSJacob Faibussowitsch PetscCall(MatSetValues(defl,ihi-ilo,Iidx,1,&i,col,INSERT_VALUES)); 192e53e0a0dSJakub Kruzik 1939566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(defl,MAT_FINAL_ASSEMBLY)); 1949566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(defl,MAT_FINAL_ASSEMBLY)); 195e53e0a0dSJakub Kruzik 1969566063dSJacob Faibussowitsch PetscCall(PetscFree2(col,Iidx)); 197e53e0a0dSJakub Kruzik *W = defl; 198e53e0a0dSJakub Kruzik PetscFunctionReturn(0); 199e53e0a0dSJakub Kruzik } 200e53e0a0dSJakub Kruzik 201e53e0a0dSJakub Kruzik PetscErrorCode PCDeflationComputeSpace(PC pc) 202e53e0a0dSJakub Kruzik { 203e53e0a0dSJakub Kruzik Mat defl; 204e53e0a0dSJakub Kruzik PetscBool transp=PETSC_TRUE; 205e53e0a0dSJakub Kruzik PC_Deflation *def = (PC_Deflation*)pc->data; 206e53e0a0dSJakub Kruzik 207e53e0a0dSJakub Kruzik PetscFunctionBegin; 2081fdb00f9SJakub Kruzik PetscValidHeaderSpecific(pc,PC_CLASSID,1); 209*63a3b9bcSJacob Faibussowitsch PetscCheck(def->spacesize >= 1,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Wrong PCDeflation space size specified: %" PetscInt_FMT,def->spacesize); 210e53e0a0dSJakub Kruzik switch (def->spacetype) { 211e53e0a0dSJakub Kruzik case PC_DEFLATION_SPACE_HAAR: 212e53e0a0dSJakub Kruzik transp = PETSC_FALSE; 2139566063dSJacob Faibussowitsch PetscCall(PCDeflationGetSpaceHaar(pc,&defl,def->spacesize));break; 214e53e0a0dSJakub Kruzik case PC_DEFLATION_SPACE_DB2: 2159566063dSJacob Faibussowitsch PetscCall(PCDeflationGetSpaceWave(pc,&defl,def->spacesize,2,db2,PetscNot(def->extendsp)));break; 216e53e0a0dSJakub Kruzik case PC_DEFLATION_SPACE_DB4: 2179566063dSJacob Faibussowitsch PetscCall(PCDeflationGetSpaceWave(pc,&defl,def->spacesize,4,db4,PetscNot(def->extendsp)));break; 218e53e0a0dSJakub Kruzik case PC_DEFLATION_SPACE_DB8: 2199566063dSJacob Faibussowitsch PetscCall(PCDeflationGetSpaceWave(pc,&defl,def->spacesize,8,db8,PetscNot(def->extendsp)));break; 220e53e0a0dSJakub Kruzik case PC_DEFLATION_SPACE_DB16: 2219566063dSJacob Faibussowitsch PetscCall(PCDeflationGetSpaceWave(pc,&defl,def->spacesize,16,db16,PetscNot(def->extendsp)));break; 222e53e0a0dSJakub Kruzik case PC_DEFLATION_SPACE_BIORTH22: 2239566063dSJacob Faibussowitsch PetscCall(PCDeflationGetSpaceWave(pc,&defl,def->spacesize,6,biorth22,PetscNot(def->extendsp)));break; 224e53e0a0dSJakub Kruzik case PC_DEFLATION_SPACE_MEYER: 2259566063dSJacob Faibussowitsch PetscCall(PCDeflationGetSpaceWave(pc,&defl,def->spacesize,62,meyer,PetscNot(def->extendsp)));break; 226e53e0a0dSJakub Kruzik case PC_DEFLATION_SPACE_AGGREGATION: 227e53e0a0dSJakub Kruzik transp = PETSC_FALSE; 2289566063dSJacob Faibussowitsch PetscCall(PCDeflationGetSpaceAggregation(pc,&defl));break; 2291fdb00f9SJakub Kruzik default: SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Wrong PCDeflationSpaceType specified"); 230e53e0a0dSJakub Kruzik } 231e53e0a0dSJakub Kruzik 2329566063dSJacob Faibussowitsch PetscCall(PCDeflationSetSpace(pc,defl,transp)); 2339566063dSJacob Faibussowitsch PetscCall(MatDestroy(&defl)); 234e53e0a0dSJakub Kruzik PetscFunctionReturn(0); 235e53e0a0dSJakub Kruzik } 236