1 2 PetscScalar db2[] = {0.7071067811865476,0.7071067811865476}; 3 4 //dec low high 5 PetscScalar db4[] = {-0.12940952255092145,0.22414386804185735,0.836516303737469,0.48296291314469025}; 6 //rec low high 7 //PetscScalar db4[] = {0.48296291314469025,0.836516303737469,0.22414386804185735,-0.12940952255092145}; 8 9 PetscScalar db8[] = {-0.010597401784997278, 10 0.032883011666982945, 11 0.030841381835986965, 12 -0.18703481171888114, 13 -0.02798376941698385, 14 0.6308807679295904, 15 0.7148465705525415, 16 0.23037781330885523}; 17 18 //PetscScalar db8[] = {0.23037781330885523, 19 //0.7148465705525415, 20 //0.6308807679295904, 21 //-0.02798376941698385, 22 //-0.18703481171888114, 23 //0.030841381835986965, 24 //0.032883011666982945, 25 //-0.010597401784997278}; 26 27 PetscScalar db16[] = {-0.00011747678400228192, 28 0.0006754494059985568, 29 -0.0003917403729959771, 30 -0.00487035299301066, 31 0.008746094047015655, 32 0.013981027917015516, 33 -0.04408825393106472, 34 -0.01736930100202211, 35 0.128747426620186, 36 0.00047248457399797254, 37 -0.2840155429624281, 38 -0.015829105256023893, 39 0.5853546836548691, 40 0.6756307362980128, 41 0.3128715909144659, 42 0.05441584224308161}; 43 44 //PetscScalar db16[] = {0.05441584224308161, 45 //0.3128715909144659, 46 //0.6756307362980128, 47 //0.5853546836548691, 48 //-0.015829105256023893, 49 //-0.2840155429624281, 50 //0.00047248457399797254, 51 //0.128747426620186, 52 //-0.01736930100202211, 53 //-0.04408825393106472, 54 //0.013981027917015516, 55 //0.008746094047015655, 56 //-0.00487035299301066, 57 //-0.0003917403729959771, 58 //0.0006754494059985568, 59 //-0.00011747678400228192}; 60 61 PetscScalar biorth22[] = {0.0, 62 -0.1767766952966369, 63 0.3535533905932738, 64 1.0606601717798214, 65 0.3535533905932738, 66 -0.1767766952966369}; 67 68 //PetscScalar biorth22[] = {0.0, 69 //0.3535533905932738, 70 //0.7071067811865476, 71 //0.3535533905932738, 72 //0.0, 73 //0.0}; 74 75 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}; 76 77 static PetscErrorCode PCDeflationCreateSpaceWave(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt M,PetscInt N,PetscInt ncoeffs,PetscScalar *coeffs,PetscBool trunc,Mat *H) 78 { 79 PetscErrorCode ierr; 80 Mat defl; 81 PetscInt i,j,k,ilo,ihi,*Iidx; 82 83 PetscFunctionBegin; 84 ierr = PetscMalloc1(ncoeffs,&Iidx);CHKERRQ(ierr); 85 86 /* TODO pass A instead of PC? */ 87 ierr = MatCreate(comm,&defl);CHKERRQ(ierr); 88 ierr = MatSetSizes(defl,m,n,M,N);CHKERRQ(ierr); 89 ierr = MatSetUp(defl);CHKERRQ(ierr); 90 ierr = MatSeqAIJSetPreallocation(defl,ncoeffs,NULL);CHKERRQ(ierr); 91 ierr = MatMPIAIJSetPreallocation(defl,ncoeffs,NULL,ncoeffs,NULL);CHKERRQ(ierr); 92 ierr = MatSetOption(defl,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 93 ierr = MatSetOption(defl,MAT_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 94 95 /* Alg 735 Taswell: fvecmat */ 96 k = ncoeffs -2; 97 if (trunc) k = k/2; 98 99 ierr = MatGetOwnershipRange(defl,&ilo,&ihi);CHKERRQ(ierr); 100 for (i=0; i<ncoeffs; i++) { 101 Iidx[i] = i+ilo*2 -k; 102 if (Iidx[i] >= N) Iidx[i] = PETSC_MIN_INT; 103 } 104 for (i=ilo; i<ihi; i++) { 105 ierr = MatSetValues(defl,1,&i,ncoeffs,Iidx,coeffs,INSERT_VALUES);CHKERRQ(ierr); 106 for (j=0; j<ncoeffs; j++) { 107 Iidx[j] += 2; 108 if (Iidx[j] >= N) Iidx[j] = PETSC_MIN_INT; 109 } 110 } 111 112 ierr = MatAssemblyBegin(defl,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 113 ierr = MatAssemblyEnd(defl,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 114 115 ierr = PetscFree(Iidx);CHKERRQ(ierr); 116 *H = defl; 117 PetscFunctionReturn(0); 118 } 119 120 PetscErrorCode PCDeflationGetSpaceHaar(PC pc,Mat *W,PetscInt size) 121 { 122 PetscErrorCode ierr; 123 Mat A,defl; 124 PetscInt i,j,len,ilo,ihi,*Iidx,m,M; 125 PetscScalar *col,val; 126 127 PetscFunctionBegin; 128 /* Haar basis wavelet, level=size */ 129 len = pow(2,size); 130 ierr = PetscMalloc1(len,&col);CHKERRQ(ierr); 131 ierr = PetscMalloc1(len,&Iidx);CHKERRQ(ierr); 132 val = 1./pow(2,size/2.); 133 for (i=0; i<len; i++) col[i] = val; 134 135 /* TODO pass A instead of PC? */ 136 ierr = PCGetOperators(pc,&A,NULL);CHKERRQ(ierr); /* NOTE: Get Pmat instead? */ 137 ierr = MatGetLocalSize(A,&m,NULL);CHKERRQ(ierr); 138 ierr = MatGetSize(A,&M,NULL);CHKERRQ(ierr); 139 ierr = MatCreate(PetscObjectComm((PetscObject)A),&defl);CHKERRQ(ierr); 140 ierr = MatSetSizes(defl,m,PETSC_DECIDE,M,ceil(M/(float)len));CHKERRQ(ierr); 141 ierr = MatSetUp(defl);CHKERRQ(ierr); 142 ierr = MatSeqAIJSetPreallocation(defl,size,NULL);CHKERRQ(ierr); 143 ierr = MatMPIAIJSetPreallocation(defl,size,NULL,size,NULL);CHKERRQ(ierr); 144 ierr = MatSetOption(defl,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 145 146 ierr = MatGetOwnershipRangeColumn(defl,&ilo,&ihi);CHKERRQ(ierr); 147 for (i=0; i<len; i++) Iidx[i] = i+ilo*len; 148 if (M%len && ihi == (int)ceil(M/(float)len)) ihi -= 1; 149 for (i=ilo; i<ihi; i++) { 150 ierr = MatSetValues(defl,len,Iidx,1,&i,col,INSERT_VALUES);CHKERRQ(ierr); 151 for (j=0; j<len; j++) Iidx[j] += len; 152 } 153 if (M%len && ihi+1 == ceil(M/(float)len)) { 154 len = M%len; 155 val = 1./pow(pow(2,len),0.5); 156 for (i=0; i<len; i++) col[i] = val; 157 ierr = MatSetValues(defl,len,Iidx,1,&ihi,col,INSERT_VALUES);CHKERRQ(ierr); 158 } 159 160 ierr = MatAssemblyBegin(defl,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 161 ierr = MatAssemblyEnd(defl,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 162 163 ierr = PetscFree(col);CHKERRQ(ierr); 164 ierr = PetscFree(Iidx);CHKERRQ(ierr); 165 *W = defl; 166 PetscFunctionReturn(0); 167 } 168 169 PetscErrorCode PCDeflationGetSpaceWave(PC pc,Mat *W,PetscInt size,PetscInt ncoeffs,PetscScalar *coeffs,PetscBool trunc) 170 { 171 PetscErrorCode ierr; 172 Mat A,*H,defl; 173 PetscInt i,m,M,Mdefl,Ndefl; 174 MPI_Comm comm; 175 176 PetscFunctionBegin; 177 ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 178 ierr = PetscMalloc1(size,&H);CHKERRQ(ierr); 179 ierr = PCGetOperators(pc,&A,NULL);CHKERRQ(ierr); /* NOTE: Get Pmat instead? */ 180 ierr = MatGetLocalSize(A,&m,NULL);CHKERRQ(ierr); 181 ierr = MatGetSize(A,&M,NULL);CHKERRQ(ierr); 182 Mdefl = M; 183 Ndefl = M; 184 for (i=0; i<size; i++) { 185 if (Mdefl%2) { 186 if (trunc) { 187 Mdefl = (PetscInt)PetscCeilReal(Mdefl/2.); 188 } else { 189 Mdefl = (PetscInt)PetscFloorReal((ncoeffs+Mdefl-1)/2.); 190 } 191 } else { 192 Mdefl = Mdefl/2; 193 } 194 ierr = PCDeflationCreateSpaceWave(comm,PETSC_DECIDE,m,Mdefl,Ndefl,ncoeffs,coeffs,trunc,&H[i]);CHKERRQ(ierr); 195 ierr = MatGetLocalSize(H[i],&m,NULL);CHKERRQ(ierr); 196 Ndefl = Mdefl; 197 } 198 ierr = MatCreateComposite(comm,size,H,&defl);CHKERRQ(ierr); 199 ierr = MatCompositeSetType(defl,MAT_COMPOSITE_MULTIPLICATIVE);CHKERRQ(ierr); 200 *W = defl; 201 202 for (i=0; i<size; i++) { 203 ierr = MatDestroy(&H[i]);CHKERRQ(ierr); 204 } 205 ierr = PetscFree(H);CHKERRQ(ierr); 206 PetscFunctionReturn(0); 207 } 208 209 PetscErrorCode PCDeflationGetSpaceAggregation(PC pc,Mat *W) 210 { 211 PetscErrorCode ierr; 212 Mat A,defl; 213 PetscInt i,ilo,ihi,*Iidx,m,M; 214 PetscScalar *col; 215 MPI_Comm comm; 216 217 PetscFunctionBegin; 218 /* TODO pass A instead of PC? */ 219 ierr = PCGetOperators(pc,&A,NULL);CHKERRQ(ierr); /* NOTE: Get Pmat instead? */ 220 ierr = MatGetOwnershipRangeColumn(A,&ilo,&ihi);CHKERRQ(ierr); 221 ierr = MatGetSize(A,&M,NULL);CHKERRQ(ierr); 222 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 223 ierr = MPI_Comm_size(comm,&m);CHKERRQ(ierr); 224 ierr = MatCreate(comm,&defl);CHKERRQ(ierr); 225 ierr = MatSetSizes(defl,ihi-ilo,1,M,m);CHKERRQ(ierr); 226 ierr = MatSetUp(defl);CHKERRQ(ierr); 227 ierr = MatSeqAIJSetPreallocation(defl,1,NULL);CHKERRQ(ierr); 228 ierr = MatMPIAIJSetPreallocation(defl,1,NULL,0,NULL);CHKERRQ(ierr); 229 ierr = MatSetOption(defl,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 230 ierr = MatSetOption(defl,MAT_IGNORE_OFF_PROC_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 231 232 233 ierr = PetscMalloc1(ihi-ilo,&col);CHKERRQ(ierr); 234 ierr = PetscMalloc1(ihi-ilo,&Iidx);CHKERRQ(ierr); 235 for (i=ilo; i<ihi; i++) { 236 Iidx[i-ilo] = i; 237 col[i-ilo] = 1; 238 } 239 ierr = MPI_Comm_rank(comm,&i);CHKERRQ(ierr); 240 ierr = MatSetValues(defl,ihi-ilo,Iidx,1,&i,col,INSERT_VALUES);CHKERRQ(ierr); 241 242 ierr = MatAssemblyBegin(defl,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 243 ierr = MatAssemblyEnd(defl,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 244 245 ierr = PetscFree(col);CHKERRQ(ierr); 246 ierr = PetscFree(Iidx);CHKERRQ(ierr); 247 *W = defl; 248 PetscFunctionReturn(0); 249 } 250 251 PetscErrorCode PCDeflationComputeSpace(PC pc) 252 { 253 PetscErrorCode ierr; 254 Mat defl; 255 PetscBool transp=PETSC_TRUE; 256 PC_Deflation *def = (PC_Deflation*)pc->data; 257 258 /* TODO valid header */ 259 PetscFunctionBegin; 260 if (def->spacesize < 1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Wrong PC_DEFLATION Space size specified: %d",def->spacesize); 261 switch (def->spacetype) { 262 case PC_DEFLATION_SPACE_HAAR: 263 transp = PETSC_FALSE; 264 ierr = PCDeflationGetSpaceHaar(pc,&defl,def->spacesize);CHKERRQ(ierr);break; 265 case PC_DEFLATION_SPACE_DB2: 266 ierr = PCDeflationGetSpaceWave(pc,&defl,def->spacesize,2,db2,!def->extendsp);CHKERRQ(ierr);break; 267 case PC_DEFLATION_SPACE_DB4: 268 ierr = PCDeflationGetSpaceWave(pc,&defl,def->spacesize,4,db4,!def->extendsp);CHKERRQ(ierr);break; 269 case PC_DEFLATION_SPACE_DB8: 270 ierr = PCDeflationGetSpaceWave(pc,&defl,def->spacesize,8,db8,!def->extendsp);CHKERRQ(ierr);break; 271 case PC_DEFLATION_SPACE_DB16: 272 ierr = PCDeflationGetSpaceWave(pc,&defl,def->spacesize,16,db16,!def->extendsp);CHKERRQ(ierr);break; 273 case PC_DEFLATION_SPACE_BIORTH22: 274 ierr = PCDeflationGetSpaceWave(pc,&defl,def->spacesize,6,biorth22,!def->extendsp);CHKERRQ(ierr);break; 275 case PC_DEFLATION_SPACE_MEYER: 276 ierr = PCDeflationGetSpaceWave(pc,&defl,def->spacesize,62,meyer,!def->extendsp);CHKERRQ(ierr);break; 277 case PC_DEFLATION_SPACE_AGGREGATION: 278 transp = PETSC_FALSE; 279 ierr = PCDeflationGetSpaceAggregation(pc,&defl);CHKERRQ(ierr);break; 280 default: SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Wrong PC_DEFLATION Space Type specified"); 281 } 282 283 ierr = PCDeflationSetSpace(pc,defl,transp);CHKERRQ(ierr); 284 ierr = MatDestroy(&defl);CHKERRQ(ierr); 285 PetscFunctionReturn(0); 286 } 287 288