1 #define PETSCKSP_DLL 2 3 /* 4 Provides an interface to pARMS. 5 Requires pARMS 3.2 or later. 6 */ 7 8 #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/ 9 10 #if defined(PETSC_USE_COMPLEX) 11 #define DBL_CMPLX 12 #else 13 #define DBL 14 #endif 15 #define USE_MPI 16 #define REAL double 17 #define HAS_BLAS 18 #define FORTRAN_UNDERSCORE 19 #include "parms_sys.h" 20 #undef FLOAT 21 #define FLOAT PetscScalar 22 #include <parms.h> 23 24 /* 25 Private context (data structure) for the preconditioner. 26 */ 27 typedef struct { 28 parms_Map map; 29 parms_Mat A; 30 parms_PC pc; 31 PCPARMSGlobalType global; 32 PCPARMSLocalType local; 33 PetscInt levels, blocksize, maxdim, maxits, lfil[7]; 34 PetscBool nonsymperm, meth[8]; 35 PetscReal solvetol, indtol, droptol[7]; 36 PetscScalar *lvec0, *lvec1; 37 } PC_PARMS; 38 39 40 static PetscErrorCode PCSetUp_PARMS(PC pc) 41 { 42 Mat pmat; 43 PC_PARMS *parms = (PC_PARMS*)pc->data; 44 const PetscInt *mapptr0; 45 PetscInt n, lsize, low, high, i, pos, ncols, length; 46 int *maptmp, *mapptr, *ia, *ja, *ja1, *im; 47 PetscScalar *aa, *aa1; 48 const PetscInt *cols; 49 PetscInt meth[8]; 50 const PetscScalar *values; 51 PetscErrorCode ierr; 52 MatInfo matinfo; 53 PetscMPIInt rank, npro; 54 55 PetscFunctionBegin; 56 /* Get preconditioner matrix from PETSc and setup pARMS structs */ 57 ierr = PCGetOperators(pc,NULL,&pmat);CHKERRQ(ierr); 58 MPI_Comm_size(PetscObjectComm((PetscObject)pmat),&npro); 59 MPI_Comm_rank(PetscObjectComm((PetscObject)pmat),&rank); 60 61 ierr = MatGetSize(pmat,&n,NULL);CHKERRQ(ierr); 62 ierr = PetscMalloc1(npro+1,&mapptr);CHKERRQ(ierr); 63 ierr = PetscMalloc1(n,&maptmp);CHKERRQ(ierr); 64 ierr = MatGetOwnershipRanges(pmat,&mapptr0);CHKERRQ(ierr); 65 low = mapptr0[rank]; 66 high = mapptr0[rank+1]; 67 lsize = high - low; 68 69 for (i=0; i<npro+1; i++) mapptr[i] = mapptr0[i]+1; 70 for (i = 0; i<n; i++) maptmp[i] = i+1; 71 72 /* if created, destroy the previous map */ 73 if (parms->map) { 74 parms_MapFree(&parms->map); 75 parms->map = NULL; 76 } 77 78 /* create pARMS map object */ 79 parms_MapCreateFromPtr(&parms->map,(int)n,maptmp,mapptr,PetscObjectComm((PetscObject)pmat),1,NONINTERLACED); 80 81 /* if created, destroy the previous pARMS matrix */ 82 if (parms->A) { 83 parms_MatFree(&parms->A); 84 parms->A = NULL; 85 } 86 87 /* create pARMS mat object */ 88 parms_MatCreate(&parms->A,parms->map); 89 90 /* setup and copy csr data structure for pARMS */ 91 ierr = PetscMalloc1(lsize+1,&ia);CHKERRQ(ierr); 92 ia[0] = 1; 93 ierr = MatGetInfo(pmat,MAT_LOCAL,&matinfo);CHKERRQ(ierr); 94 length = matinfo.nz_used; 95 ierr = PetscMalloc1(length,&ja);CHKERRQ(ierr); 96 ierr = PetscMalloc1(length,&aa);CHKERRQ(ierr); 97 98 for (i = low; i<high; i++) { 99 pos = ia[i-low]-1; 100 ierr = MatGetRow(pmat,i,&ncols,&cols,&values);CHKERRQ(ierr); 101 ia[i-low+1] = ia[i-low] + ncols; 102 103 if (ia[i-low+1] >= length) { 104 length += ncols; 105 ierr = PetscMalloc1(length,&ja1);CHKERRQ(ierr); 106 ierr = PetscMemcpy(ja1,ja,(ia[i-low]-1)*sizeof(int));CHKERRQ(ierr); 107 ierr = PetscFree(ja);CHKERRQ(ierr); 108 ja = ja1; 109 ierr = PetscMalloc1(length,&aa1);CHKERRQ(ierr); 110 ierr = PetscMemcpy(aa1,aa,(ia[i-low]-1)*sizeof(PetscScalar));CHKERRQ(ierr); 111 ierr = PetscFree(aa);CHKERRQ(ierr); 112 aa = aa1; 113 } 114 ierr = PetscMemcpy(&ja[pos],cols,ncols*sizeof(int));CHKERRQ(ierr); 115 ierr = PetscMemcpy(&aa[pos],values,ncols*sizeof(PetscScalar));CHKERRQ(ierr); 116 ierr = MatRestoreRow(pmat,i,&ncols,&cols,&values);CHKERRQ(ierr); 117 } 118 119 /* csr info is for local matrix so initialize im[] locally */ 120 ierr = PetscMalloc1(lsize,&im);CHKERRQ(ierr); 121 ierr = PetscMemcpy(im,&maptmp[mapptr[rank]-1],lsize*sizeof(int));CHKERRQ(ierr); 122 123 /* 1-based indexing */ 124 for (i=0; i<ia[lsize]-1; i++) ja[i] = ja[i]+1; 125 126 /* Now copy csr matrix to parms_mat object */ 127 parms_MatSetValues(parms->A,(int)lsize,im,ia,ja,aa,INSERT); 128 129 /* free memory */ 130 ierr = PetscFree(maptmp);CHKERRQ(ierr); 131 ierr = PetscFree(mapptr);CHKERRQ(ierr); 132 ierr = PetscFree(aa);CHKERRQ(ierr); 133 ierr = PetscFree(ja);CHKERRQ(ierr); 134 ierr = PetscFree(ia);CHKERRQ(ierr); 135 ierr = PetscFree(im);CHKERRQ(ierr); 136 137 /* setup parms matrix */ 138 parms_MatSetup(parms->A); 139 140 /* if created, destroy the previous pARMS pc */ 141 if (parms->pc) { 142 parms_PCFree(&parms->pc); 143 parms->pc = NULL; 144 } 145 146 /* Now create pARMS preconditioner object based on A */ 147 parms_PCCreate(&parms->pc,parms->A); 148 149 /* Transfer options from PC to pARMS */ 150 switch (parms->global) { 151 case 0: parms_PCSetType(parms->pc, PCRAS); break; 152 case 1: parms_PCSetType(parms->pc, PCSCHUR); break; 153 case 2: parms_PCSetType(parms->pc, PCBJ); break; 154 } 155 switch (parms->local) { 156 case 0: parms_PCSetILUType(parms->pc, PCILU0); break; 157 case 1: parms_PCSetILUType(parms->pc, PCILUK); break; 158 case 2: parms_PCSetILUType(parms->pc, PCILUT); break; 159 case 3: parms_PCSetILUType(parms->pc, PCARMS); break; 160 } 161 parms_PCSetInnerEps(parms->pc, parms->solvetol); 162 parms_PCSetNlevels(parms->pc, parms->levels); 163 parms_PCSetPermType(parms->pc, parms->nonsymperm ? 1 : 0); 164 parms_PCSetBsize(parms->pc, parms->blocksize); 165 parms_PCSetTolInd(parms->pc, parms->indtol); 166 parms_PCSetInnerKSize(parms->pc, parms->maxdim); 167 parms_PCSetInnerMaxits(parms->pc, parms->maxits); 168 for (i=0; i<8; i++) meth[i] = parms->meth[i] ? 1 : 0; 169 parms_PCSetPermScalOptions(parms->pc, &meth[0], 1); 170 parms_PCSetPermScalOptions(parms->pc, &meth[4], 0); 171 parms_PCSetFill(parms->pc, parms->lfil); 172 parms_PCSetTol(parms->pc, parms->droptol); 173 174 parms_PCSetup(parms->pc); 175 176 /* Allocate two auxiliary vector of length lsize */ 177 if (parms->lvec0) { ierr = PetscFree(parms->lvec0);CHKERRQ(ierr); } 178 ierr = PetscMalloc1(lsize, &parms->lvec0);CHKERRQ(ierr); 179 if (parms->lvec1) { ierr = PetscFree(parms->lvec1);CHKERRQ(ierr); } 180 ierr = PetscMalloc1(lsize, &parms->lvec1);CHKERRQ(ierr); 181 PetscFunctionReturn(0); 182 } 183 184 static PetscErrorCode PCView_PARMS(PC pc,PetscViewer viewer) 185 { 186 PetscErrorCode ierr; 187 PetscBool iascii; 188 PC_PARMS *parms = (PC_PARMS*)pc->data; 189 char *str; 190 double fill_fact; 191 192 PetscFunctionBegin; 193 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 194 if (iascii) { 195 parms_PCGetName(parms->pc,&str); 196 ierr = PetscViewerASCIIPrintf(viewer," global preconditioner: %s\n",str);CHKERRQ(ierr); 197 parms_PCILUGetName(parms->pc,&str); 198 ierr = PetscViewerASCIIPrintf(viewer," local preconditioner: %s\n",str);CHKERRQ(ierr); 199 parms_PCGetRatio(parms->pc,&fill_fact); 200 ierr = PetscViewerASCIIPrintf(viewer," non-zero elements/original non-zero entries: %-4.2f\n",fill_fact);CHKERRQ(ierr); 201 ierr = PetscViewerASCIIPrintf(viewer," Tolerance for local solve: %g\n",parms->solvetol);CHKERRQ(ierr); 202 ierr = PetscViewerASCIIPrintf(viewer," Number of levels: %d\n",parms->levels);CHKERRQ(ierr); 203 if (parms->nonsymperm) { 204 ierr = PetscViewerASCIIPrintf(viewer," Using nonsymmetric permutation\n");CHKERRQ(ierr); 205 } 206 ierr = PetscViewerASCIIPrintf(viewer," Block size: %d\n",parms->blocksize);CHKERRQ(ierr); 207 ierr = PetscViewerASCIIPrintf(viewer," Tolerance for independent sets: %g\n",parms->indtol);CHKERRQ(ierr); 208 ierr = PetscViewerASCIIPrintf(viewer," Inner Krylov dimension: %d\n",parms->maxdim);CHKERRQ(ierr); 209 ierr = PetscViewerASCIIPrintf(viewer," Maximum number of inner iterations: %d\n",parms->maxits);CHKERRQ(ierr); 210 if (parms->meth[0]) { 211 ierr = PetscViewerASCIIPrintf(viewer," Using nonsymmetric permutation for interlevel blocks\n");CHKERRQ(ierr); 212 } 213 if (parms->meth[1]) { 214 ierr = PetscViewerASCIIPrintf(viewer," Using column permutation for interlevel blocks\n");CHKERRQ(ierr); 215 } 216 if (parms->meth[2]) { 217 ierr = PetscViewerASCIIPrintf(viewer," Using row scaling for interlevel blocks\n");CHKERRQ(ierr); 218 } 219 if (parms->meth[3]) { 220 ierr = PetscViewerASCIIPrintf(viewer," Using column scaling for interlevel blocks\n");CHKERRQ(ierr); 221 } 222 if (parms->meth[4]) { 223 ierr = PetscViewerASCIIPrintf(viewer," Using nonsymmetric permutation for last level blocks\n");CHKERRQ(ierr); 224 } 225 if (parms->meth[5]) { 226 ierr = PetscViewerASCIIPrintf(viewer," Using column permutation for last level blocks\n");CHKERRQ(ierr); 227 } 228 if (parms->meth[6]) { 229 ierr = PetscViewerASCIIPrintf(viewer," Using row scaling for last level blocks\n");CHKERRQ(ierr); 230 } 231 if (parms->meth[7]) { 232 ierr = PetscViewerASCIIPrintf(viewer," Using column scaling for last level blocks\n");CHKERRQ(ierr); 233 } 234 ierr = PetscViewerASCIIPrintf(viewer," amount of fill-in for ilut, iluk and arms: %d\n",parms->lfil[0]);CHKERRQ(ierr); 235 ierr = PetscViewerASCIIPrintf(viewer," amount of fill-in for schur: %d\n",parms->lfil[4]);CHKERRQ(ierr); 236 ierr = PetscViewerASCIIPrintf(viewer," amount of fill-in for ILUT L and U: %d\n",parms->lfil[5]);CHKERRQ(ierr); 237 ierr = PetscViewerASCIIPrintf(viewer," drop tolerance for L, U, L^{-1}F and EU^{-1}: %g\n",parms->droptol[0]);CHKERRQ(ierr); 238 ierr = PetscViewerASCIIPrintf(viewer," drop tolerance for schur complement at each level: %g\n",parms->droptol[4]);CHKERRQ(ierr); 239 ierr = PetscViewerASCIIPrintf(viewer," drop tolerance for ILUT in last level schur complement: %g\n",parms->droptol[5]);CHKERRQ(ierr); 240 } 241 PetscFunctionReturn(0); 242 } 243 244 static PetscErrorCode PCDestroy_PARMS(PC pc) 245 { 246 PC_PARMS *parms = (PC_PARMS*)pc->data; 247 PetscErrorCode ierr; 248 249 PetscFunctionBegin; 250 if (parms->map) parms_MapFree(&parms->map); 251 if (parms->A) parms_MatFree(&parms->A); 252 if (parms->pc) parms_PCFree(&parms->pc); 253 if (parms->lvec0) { 254 ierr = PetscFree(parms->lvec0);CHKERRQ(ierr); 255 } 256 if (parms->lvec1) { 257 ierr = PetscFree(parms->lvec1);CHKERRQ(ierr); 258 } 259 ierr = PetscFree(pc->data);CHKERRQ(ierr); 260 261 ierr = PetscObjectChangeTypeName((PetscObject)pc,0);CHKERRQ(ierr); 262 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetGlobal_C",NULL);CHKERRQ(ierr); 263 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetLocal_C",NULL);CHKERRQ(ierr); 264 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetSolveTolerances_C",NULL);CHKERRQ(ierr); 265 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetSolveRestart_C",NULL);CHKERRQ(ierr); 266 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetNonsymPerm_C",NULL);CHKERRQ(ierr); 267 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetFill_C",NULL);CHKERRQ(ierr); 268 PetscFunctionReturn(0); 269 } 270 271 static PetscErrorCode PCSetFromOptions_PARMS(PetscOptionItems *PetscOptionsObject,PC pc) 272 { 273 PC_PARMS *parms = (PC_PARMS*)pc->data; 274 PetscBool flag; 275 PCPARMSGlobalType global; 276 PCPARMSLocalType local; 277 PetscErrorCode ierr; 278 279 PetscFunctionBegin; 280 ierr = PetscOptionsHead(PetscOptionsObject,"PARMS Options");CHKERRQ(ierr); 281 ierr = PetscOptionsEnum("-pc_parms_global","Global preconditioner","PCPARMSSetGlobal",PCPARMSGlobalTypes,(PetscEnum)parms->global,(PetscEnum*)&global,&flag);CHKERRQ(ierr); 282 if (flag) {ierr = PCPARMSSetGlobal(pc,global);CHKERRQ(ierr);} 283 ierr = PetscOptionsEnum("-pc_parms_local","Local preconditioner","PCPARMSSetLocal",PCPARMSLocalTypes,(PetscEnum)parms->local,(PetscEnum*)&local,&flag);CHKERRQ(ierr); 284 if (flag) {ierr = PCPARMSSetLocal(pc,local);CHKERRQ(ierr);} 285 ierr = PetscOptionsReal("-pc_parms_solve_tol","Tolerance for local solve","PCPARMSSetSolveTolerances",parms->solvetol,&parms->solvetol,NULL);CHKERRQ(ierr); 286 ierr = PetscOptionsInt("-pc_parms_levels","Number of levels","None",parms->levels,&parms->levels,NULL);CHKERRQ(ierr); 287 ierr = PetscOptionsBool("-pc_parms_nonsymmetric_perm","Use nonsymmetric permutation","PCPARMSSetNonsymPerm",parms->nonsymperm,&parms->nonsymperm,NULL);CHKERRQ(ierr); 288 ierr = PetscOptionsInt("-pc_parms_blocksize","Block size","None",parms->blocksize,&parms->blocksize,NULL);CHKERRQ(ierr); 289 ierr = PetscOptionsReal("-pc_parms_ind_tol","Tolerance for independent sets","None",parms->indtol,&parms->indtol,NULL);CHKERRQ(ierr); 290 ierr = PetscOptionsInt("-pc_parms_max_dim","Inner Krylov dimension","PCPARMSSetSolveRestart",parms->maxdim,&parms->maxdim,NULL);CHKERRQ(ierr); 291 ierr = PetscOptionsInt("-pc_parms_max_it","Maximum number of inner iterations","PCPARMSSetSolveTolerances",parms->maxits,&parms->maxits,NULL);CHKERRQ(ierr); 292 ierr = PetscOptionsBool("-pc_parms_inter_nonsymmetric_perm","nonsymmetric permutation for interlevel blocks","None",parms->meth[0],&parms->meth[0],NULL);CHKERRQ(ierr); 293 ierr = PetscOptionsBool("-pc_parms_inter_column_perm","column permutation for interlevel blocks","None",parms->meth[1],&parms->meth[1],NULL);CHKERRQ(ierr); 294 ierr = PetscOptionsBool("-pc_parms_inter_row_scaling","row scaling for interlevel blocks","None",parms->meth[2],&parms->meth[2],NULL);CHKERRQ(ierr); 295 ierr = PetscOptionsBool("-pc_parms_inter_column_scaling","column scaling for interlevel blocks","None",parms->meth[3],&parms->meth[3],NULL);CHKERRQ(ierr); 296 ierr = PetscOptionsBool("-pc_parms_last_nonsymmetric_perm","nonsymmetric permutation for last level blocks","None",parms->meth[4],&parms->meth[4],NULL);CHKERRQ(ierr); 297 ierr = PetscOptionsBool("-pc_parms_last_column_perm","column permutation for last level blocks","None",parms->meth[5],&parms->meth[5],NULL);CHKERRQ(ierr); 298 ierr = PetscOptionsBool("-pc_parms_last_row_scaling","row scaling for last level blocks","None",parms->meth[6],&parms->meth[6],NULL);CHKERRQ(ierr); 299 ierr = PetscOptionsBool("-pc_parms_last_column_scaling","column scaling for last level blocks","None",parms->meth[7],&parms->meth[7],NULL);CHKERRQ(ierr); 300 ierr = PetscOptionsInt("-pc_parms_lfil_ilu_arms","amount of fill-in for ilut, iluk and arms","PCPARMSSetFill",parms->lfil[0],&parms->lfil[0],&flag);CHKERRQ(ierr); 301 if (flag) parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = parms->lfil[0]; 302 ierr = PetscOptionsInt("-pc_parms_lfil_schur","amount of fill-in for schur","PCPARMSSetFill",parms->lfil[4],&parms->lfil[4],NULL);CHKERRQ(ierr); 303 ierr = PetscOptionsInt("-pc_parms_lfil_ilut_L_U","amount of fill-in for ILUT L and U","PCPARMSSetFill",parms->lfil[5],&parms->lfil[5],&flag);CHKERRQ(ierr); 304 if (flag) parms->lfil[6] = parms->lfil[5]; 305 ierr = PetscOptionsReal("-pc_parms_droptol_factors","drop tolerance for L, U, L^{-1}F and EU^{-1}","None",parms->droptol[0],&parms->droptol[0],NULL);CHKERRQ(ierr); 306 ierr = PetscOptionsReal("-pc_parms_droptol_schur_compl","drop tolerance for schur complement at each level","None",parms->droptol[4],&parms->droptol[4],&flag);CHKERRQ(ierr); 307 if (flag) parms->droptol[1] = parms->droptol[2] = parms->droptol[3] = parms->droptol[0]; 308 ierr = PetscOptionsReal("-pc_parms_droptol_last_schur","drop tolerance for ILUT in last level schur complement","None",parms->droptol[5],&parms->droptol[5],&flag);CHKERRQ(ierr); 309 if (flag) parms->droptol[6] = parms->droptol[5]; 310 ierr = PetscOptionsTail();CHKERRQ(ierr); 311 PetscFunctionReturn(0); 312 } 313 314 static PetscErrorCode PCApply_PARMS(PC pc,Vec b,Vec x) 315 { 316 PetscErrorCode ierr; 317 PC_PARMS *parms = (PC_PARMS*)pc->data; 318 const PetscScalar *b1; 319 PetscScalar *x1; 320 321 PetscFunctionBegin; 322 ierr = VecGetArrayRead(b,&b1);CHKERRQ(ierr); 323 ierr = VecGetArray(x,&x1);CHKERRQ(ierr); 324 parms_VecPermAux((PetscScalar*)b1,parms->lvec0,parms->map); 325 parms_PCApply(parms->pc,parms->lvec0,parms->lvec1); 326 parms_VecInvPermAux(parms->lvec1,x1,parms->map); 327 ierr = VecRestoreArrayRead(b,&b1);CHKERRQ(ierr); 328 ierr = VecRestoreArray(x,&x1);CHKERRQ(ierr); 329 PetscFunctionReturn(0); 330 } 331 332 static PetscErrorCode PCPARMSSetGlobal_PARMS(PC pc,PCPARMSGlobalType type) 333 { 334 PC_PARMS *parms = (PC_PARMS*)pc->data; 335 336 PetscFunctionBegin; 337 if (type != parms->global) { 338 parms->global = type; 339 pc->setupcalled = 0; 340 } 341 PetscFunctionReturn(0); 342 } 343 344 /*@ 345 PCPARMSSetGlobal - Sets the global preconditioner to be used in PARMS. 346 347 Collective on PC 348 349 Input Parameters: 350 + pc - the preconditioner context 351 - type - the global preconditioner type, one of 352 .vb 353 PC_PARMS_GLOBAL_RAS - Restricted additive Schwarz 354 PC_PARMS_GLOBAL_SCHUR - Schur complement 355 PC_PARMS_GLOBAL_BJ - Block Jacobi 356 .ve 357 358 Options Database Keys: 359 -pc_parms_global [ras,schur,bj] - Sets global preconditioner 360 361 Level: intermediate 362 363 Notes: 364 See the pARMS function parms_PCSetType for more information. 365 366 .seealso: PCPARMS, PCPARMSSetLocal() 367 @*/ 368 PetscErrorCode PCPARMSSetGlobal(PC pc,PCPARMSGlobalType type) 369 { 370 PetscErrorCode ierr; 371 372 PetscFunctionBegin; 373 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 374 PetscValidLogicalCollectiveEnum(pc,type,2); 375 ierr = PetscTryMethod(pc,"PCPARMSSetGlobal_C",(PC,PCPARMSGlobalType),(pc,type));CHKERRQ(ierr); 376 PetscFunctionReturn(0); 377 } 378 379 static PetscErrorCode PCPARMSSetLocal_PARMS(PC pc,PCPARMSLocalType type) 380 { 381 PC_PARMS *parms = (PC_PARMS*)pc->data; 382 383 PetscFunctionBegin; 384 if (type != parms->local) { 385 parms->local = type; 386 pc->setupcalled = 0; 387 } 388 PetscFunctionReturn(0); 389 } 390 391 /*@ 392 PCPARMSSetLocal - Sets the local preconditioner to be used in PARMS. 393 394 Collective on PC 395 396 Input Parameters: 397 + pc - the preconditioner context 398 - type - the local preconditioner type, one of 399 .vb 400 PC_PARMS_LOCAL_ILU0 - ILU0 preconditioner 401 PC_PARMS_LOCAL_ILUK - ILU(k) preconditioner 402 PC_PARMS_LOCAL_ILUT - ILUT preconditioner 403 PC_PARMS_LOCAL_ARMS - ARMS preconditioner 404 .ve 405 406 Options Database Keys: 407 -pc_parms_local [ilu0,iluk,ilut,arms] - Sets local preconditioner 408 409 Level: intermediate 410 411 Notes: 412 For the ARMS preconditioner, one can use either the symmetric ARMS or the non-symmetric 413 variant (ARMS-ddPQ) by setting the permutation type with PCPARMSSetNonsymPerm(). 414 415 See the pARMS function parms_PCILUSetType for more information. 416 417 .seealso: PCPARMS, PCPARMSSetGlobal(), PCPARMSSetNonsymPerm() 418 419 @*/ 420 PetscErrorCode PCPARMSSetLocal(PC pc,PCPARMSLocalType type) 421 { 422 PetscErrorCode ierr; 423 424 PetscFunctionBegin; 425 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 426 PetscValidLogicalCollectiveEnum(pc,type,2); 427 ierr = PetscTryMethod(pc,"PCPARMSSetLocal_C",(PC,PCPARMSLocalType),(pc,type));CHKERRQ(ierr); 428 PetscFunctionReturn(0); 429 } 430 431 static PetscErrorCode PCPARMSSetSolveTolerances_PARMS(PC pc,PetscReal tol,PetscInt maxits) 432 { 433 PC_PARMS *parms = (PC_PARMS*)pc->data; 434 435 PetscFunctionBegin; 436 if (tol != parms->solvetol) { 437 parms->solvetol = tol; 438 pc->setupcalled = 0; 439 } 440 if (maxits != parms->maxits) { 441 parms->maxits = maxits; 442 pc->setupcalled = 0; 443 } 444 PetscFunctionReturn(0); 445 } 446 447 /*@ 448 PCPARMSSetSolveTolerances - Sets the convergence tolerance and the maximum iterations for the 449 inner GMRES solver, when the Schur global preconditioner is used. 450 451 Collective on PC 452 453 Input Parameters: 454 + pc - the preconditioner context 455 . tol - the convergence tolerance 456 - maxits - the maximum number of iterations to use 457 458 Options Database Keys: 459 + -pc_parms_solve_tol - set the tolerance for local solve 460 - -pc_parms_max_it - set the maximum number of inner iterations 461 462 Level: intermediate 463 464 Notes: 465 See the pARMS functions parms_PCSetInnerEps and parms_PCSetInnerMaxits for more information. 466 467 .seealso: PCPARMS, PCPARMSSetSolveRestart() 468 @*/ 469 PetscErrorCode PCPARMSSetSolveTolerances(PC pc,PetscReal tol,PetscInt maxits) 470 { 471 PetscErrorCode ierr; 472 473 PetscFunctionBegin; 474 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 475 ierr = PetscTryMethod(pc,"PCPARMSSetSolveTolerances_C",(PC,PetscReal,PetscInt),(pc,tol,maxits));CHKERRQ(ierr); 476 PetscFunctionReturn(0); 477 } 478 479 static PetscErrorCode PCPARMSSetSolveRestart_PARMS(PC pc,PetscInt restart) 480 { 481 PC_PARMS *parms = (PC_PARMS*)pc->data; 482 483 PetscFunctionBegin; 484 if (restart != parms->maxdim) { 485 parms->maxdim = restart; 486 pc->setupcalled = 0; 487 } 488 PetscFunctionReturn(0); 489 } 490 491 /*@ 492 PCPARMSSetSolveRestart - Sets the number of iterations at which the 493 inner GMRES solver restarts. 494 495 Collective on PC 496 497 Input Parameters: 498 + pc - the preconditioner context 499 - restart - maximum dimension of the Krylov subspace 500 501 Options Database Keys: 502 . -pc_parms_max_dim - sets the inner Krylov dimension 503 504 Level: intermediate 505 506 Notes: 507 See the pARMS function parms_PCSetInnerKSize for more information. 508 509 .seealso: PCPARMS, PCPARMSSetSolveTolerances() 510 @*/ 511 PetscErrorCode PCPARMSSetSolveRestart(PC pc,PetscInt restart) 512 { 513 PetscErrorCode ierr; 514 515 PetscFunctionBegin; 516 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 517 ierr = PetscTryMethod(pc,"PCPARMSSetSolveRestart_C",(PC,PetscInt),(pc,restart));CHKERRQ(ierr); 518 PetscFunctionReturn(0); 519 } 520 521 static PetscErrorCode PCPARMSSetNonsymPerm_PARMS(PC pc,PetscBool nonsym) 522 { 523 PC_PARMS *parms = (PC_PARMS*)pc->data; 524 525 PetscFunctionBegin; 526 if ((nonsym && !parms->nonsymperm) || (!nonsym && parms->nonsymperm)) { 527 parms->nonsymperm = nonsym; 528 pc->setupcalled = 0; 529 } 530 PetscFunctionReturn(0); 531 } 532 533 /*@ 534 PCPARMSSetNonsymPerm - Sets the type of permutation for the ARMS preconditioner: the standard 535 symmetric ARMS or the non-symmetric ARMS (ARMS-ddPQ). 536 537 Collective on PC 538 539 Input Parameters: 540 + pc - the preconditioner context 541 - nonsym - PETSC_TRUE indicates the non-symmetric ARMS is used; 542 PETSC_FALSE indicates the symmetric ARMS is used 543 544 Options Database Keys: 545 . -pc_parms_nonsymmetric_perm - sets the use of nonsymmetric permutation 546 547 Level: intermediate 548 549 Notes: 550 See the pARMS function parms_PCSetPermType for more information. 551 552 .seealso: PCPARMS 553 @*/ 554 PetscErrorCode PCPARMSSetNonsymPerm(PC pc,PetscBool nonsym) 555 { 556 PetscErrorCode ierr; 557 558 PetscFunctionBegin; 559 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 560 ierr = PetscTryMethod(pc,"PCPARMSSetNonsymPerm_C",(PC,PetscBool),(pc,nonsym));CHKERRQ(ierr); 561 PetscFunctionReturn(0); 562 } 563 564 static PetscErrorCode PCPARMSSetFill_PARMS(PC pc,PetscInt lfil0,PetscInt lfil1,PetscInt lfil2) 565 { 566 PC_PARMS *parms = (PC_PARMS*)pc->data; 567 568 PetscFunctionBegin; 569 if (lfil0 != parms->lfil[0] || lfil0 != parms->lfil[1] || lfil0 != parms->lfil[2] || lfil0 != parms->lfil[3]) { 570 parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = parms->lfil[0] = lfil0; 571 pc->setupcalled = 0; 572 } 573 if (lfil1 != parms->lfil[4]) { 574 parms->lfil[4] = lfil1; 575 pc->setupcalled = 0; 576 } 577 if (lfil2 != parms->lfil[5] || lfil2 != parms->lfil[6]) { 578 parms->lfil[5] = parms->lfil[6] = lfil2; 579 pc->setupcalled = 0; 580 } 581 PetscFunctionReturn(0); 582 } 583 584 /*@ 585 PCPARMSSetFill - Sets the fill-in parameters for ILUT, ILUK and ARMS preconditioners. 586 Consider the original matrix A = [B F; E C] and the approximate version 587 M = [LB 0; E/UB I]*[UB LB\F; 0 S]. 588 589 Collective on PC 590 591 Input Parameters: 592 + pc - the preconditioner context 593 . fil0 - the level of fill-in kept in LB, UB, E/UB and LB\F 594 . fil1 - the level of fill-in kept in S 595 - fil2 - the level of fill-in kept in the L and U parts of the LU factorization of S 596 597 Options Database Keys: 598 + -pc_parms_lfil_ilu_arms - set the amount of fill-in for ilut, iluk and arms 599 . -pc_parms_lfil_schur - set the amount of fill-in for schur 600 - -pc_parms_lfil_ilut_L_U - set the amount of fill-in for ILUT L and U 601 602 Level: intermediate 603 604 Notes: 605 See the pARMS function parms_PCSetFill for more information. 606 607 .seealso: PCPARMS 608 @*/ 609 PetscErrorCode PCPARMSSetFill(PC pc,PetscInt lfil0,PetscInt lfil1,PetscInt lfil2) 610 { 611 PetscErrorCode ierr; 612 613 PetscFunctionBegin; 614 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 615 ierr = PetscTryMethod(pc,"PCPARMSSetFill_C",(PC,PetscInt,PetscInt,PetscInt),(pc,lfil0,lfil1,lfil2));CHKERRQ(ierr); 616 PetscFunctionReturn(0); 617 } 618 619 /*MC 620 PCPARMS - Allows the use of the parallel Algebraic Recursive Multilevel Solvers 621 available in the package pARMS 622 623 Options Database Keys: 624 + -pc_parms_global - one of ras, schur, bj 625 . -pc_parms_local - one of ilu0, iluk, ilut, arms 626 . -pc_parms_solve_tol - set the tolerance for local solve 627 . -pc_parms_levels - set the number of levels 628 . -pc_parms_nonsymmetric_perm - set the use of nonsymmetric permutation 629 . -pc_parms_blocksize - set the block size 630 . -pc_parms_ind_tol - set the tolerance for independent sets 631 . -pc_parms_max_dim - set the inner krylov dimension 632 . -pc_parms_max_it - set the maximum number of inner iterations 633 . -pc_parms_inter_nonsymmetric_perm - set the use of nonsymmetric permutation for interlevel blocks 634 . -pc_parms_inter_column_perm - set the use of column permutation for interlevel blocks 635 . -pc_parms_inter_row_scaling - set the use of row scaling for interlevel blocks 636 . -pc_parms_inter_column_scaling - set the use of column scaling for interlevel blocks 637 . -pc_parms_last_nonsymmetric_perm - set the use of nonsymmetric permutation for last level blocks 638 . -pc_parms_last_column_perm - set the use of column permutation for last level blocks 639 . -pc_parms_last_row_scaling - set the use of row scaling for last level blocks 640 . -pc_parms_last_column_scaling - set the use of column scaling for last level blocks 641 . -pc_parms_lfil_ilu_arms - set the amount of fill-in for ilut, iluk and arms 642 . -pc_parms_lfil_schur - set the amount of fill-in for schur 643 . -pc_parms_lfil_ilut_L_U - set the amount of fill-in for ILUT L and U 644 . -pc_parms_droptol_factors - set the drop tolerance for L, U, L^{-1}F and EU^{-1} 645 . -pc_parms_droptol_schur_compl - set the drop tolerance for schur complement at each level 646 - -pc_parms_droptol_last_schur - set the drop tolerance for ILUT in last level schur complement 647 648 IMPORTANT: 649 Unless configured appropriately, this preconditioner performs an inexact solve 650 as part of the preconditioner application. Therefore, it must be used in combination 651 with flexible variants of iterative solvers, such as KSPFGMRES or KSPCGR. 652 653 Level: intermediate 654 655 .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC 656 M*/ 657 658 PETSC_EXTERN PetscErrorCode PCCreate_PARMS(PC pc) 659 { 660 PC_PARMS *parms; 661 PetscErrorCode ierr; 662 663 PetscFunctionBegin; 664 ierr = PetscNewLog(pc,&parms);CHKERRQ(ierr); 665 666 parms->map = 0; 667 parms->A = 0; 668 parms->pc = 0; 669 parms->global = PC_PARMS_GLOBAL_RAS; 670 parms->local = PC_PARMS_LOCAL_ARMS; 671 parms->levels = 10; 672 parms->nonsymperm = PETSC_TRUE; 673 parms->blocksize = 250; 674 parms->maxdim = 0; 675 parms->maxits = 0; 676 parms->meth[0] = PETSC_FALSE; 677 parms->meth[1] = PETSC_FALSE; 678 parms->meth[2] = PETSC_FALSE; 679 parms->meth[3] = PETSC_FALSE; 680 parms->meth[4] = PETSC_FALSE; 681 parms->meth[5] = PETSC_FALSE; 682 parms->meth[6] = PETSC_FALSE; 683 parms->meth[7] = PETSC_FALSE; 684 parms->solvetol = 0.01; 685 parms->indtol = 0.4; 686 parms->lfil[0] = parms->lfil[1] = parms->lfil[2] = parms->lfil[3] = 20; 687 parms->lfil[4] = parms->lfil[5] = parms->lfil[6] = 20; 688 parms->droptol[0] = parms->droptol[1] = parms->droptol[2] = parms->droptol[3] = 0.00001; 689 parms->droptol[4] = 0.001; 690 parms->droptol[5] = parms->droptol[6] = 0.001; 691 692 pc->data = parms; 693 pc->ops->destroy = PCDestroy_PARMS; 694 pc->ops->setfromoptions = PCSetFromOptions_PARMS; 695 pc->ops->setup = PCSetUp_PARMS; 696 pc->ops->apply = PCApply_PARMS; 697 pc->ops->view = PCView_PARMS; 698 699 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetGlobal_C",PCPARMSSetGlobal_PARMS);CHKERRQ(ierr); 700 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetLocal_C",PCPARMSSetLocal_PARMS);CHKERRQ(ierr); 701 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetSolveTolerances_C",PCPARMSSetSolveTolerances_PARMS);CHKERRQ(ierr); 702 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetSolveRestart_C",PCPARMSSetSolveRestart_PARMS);CHKERRQ(ierr); 703 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetNonsymPerm_C",PCPARMSSetNonsymPerm_PARMS);CHKERRQ(ierr); 704 ierr = PetscObjectComposeFunction((PetscObject)pc,"PCPARMSSetFill_C",PCPARMSSetFill_PARMS);CHKERRQ(ierr); 705 PetscFunctionReturn(0); 706 } 707