|
System Preprocessors
|
00001 /*! \page pc The preconditioner 00002 00003 Choosing a preconditioner changes a linear system into a preconditioned 00004 system. However, this is not a transformation of any coefficient matrix, 00005 so this preprocessor is handled a bit differently from the previous ones. 00006 */ 00007 00008 #include <stdlib.h> 00009 #include <stdio.h> 00010 #include "syspro.h" 00011 #include "syspro_impl.h" 00012 #include "sysprolinear.h" 00013 #include "sysprotransform.h" 00014 #include "linear_impl.h" 00015 #include "linpc.h" 00016 #include "linksp.h" 00017 #include "petsc.h" 00018 #include "petscmat.h" 00019 #include "petscpc.h" 00020 #include "petscksp.h" 00021 #include "anamod.h" 00022 00023 #define PetscObjectStateDecrease(obj) ((obj)->state--,0) 00024 00025 #define PREPROCESSOR "pc" 00026 00027 #undef __FUNCT__ 00028 #define __FUNCT__ "setup_pc_choices" 00029 static PetscErrorCode setup_pc_choices() 00030 { 00031 SalsaTransform pc; SalsaTransformObject cur; 00032 PetscErrorCode ierr; 00033 00034 PetscFunctionBegin; 00035 00036 ierr = TransformGetByName(PREPROCESSOR,&pc); CHKERRQ(ierr); 00037 00038 /* 00039 * Set up various properties of PCs; these can be used 00040 * later to disable KSP choices 00041 */ 00042 /* symmetric substitutions */ 00043 ierr = SysProDefineIntAnnotation(PREPROCESSOR,"notrans"); CHKERRQ(ierr); 00044 /* requires transpose */ 00045 ierr = SysProDefineIntAnnotation(PREPROCESSOR,"noparallel"); CHKERRQ(ierr); 00046 /* is direct solve */ 00047 ierr = SysProDefineIntAnnotation(PREPROCESSOR,"directsolve"); CHKERRQ(ierr); 00048 /* marked as breaking down */ 00049 ierr = SysProDefineIntAnnotation(PREPROCESSOR,"marked"); CHKERRQ(ierr); 00050 00051 #if defined(PETSC_HAVE_BLOCKSOLVE) 00052 /* 00053 * BlockSolve 95 00054 */ 00055 ierr = NewTransformObject(PREPROCESSOR,PCBS95,&cur); CHKERRQ(ierr); 00056 ierr = TransformObjectSetExplanation(cur,"BlockSolve 95"); CHKERRQ(ierr); 00057 ierr = TransformObjectIntAnnotate(cur,"notrans",1); CHKERRQ(ierr); 00058 #endif 00059 00060 #if defined(PETSC_HAVE_HYPRE) 00061 /* 00062 * Hypre methods: boomeramg and pilut 00063 */ 00064 ierr = NewTransformObject(PREPROCESSOR,PCBOOMERAMG,&cur); CHKERRQ(ierr); 00065 ierr = TransformObjectSetExplanation(cur,"Hypre BoomerAMG"); CHKERRQ(ierr); 00066 ierr = TransformObjectIntAnnotate(cur,"notrans",1); CHKERRQ(ierr); 00067 00068 ierr = NewTransformObject(PREPROCESSOR,PCPILUT,&cur); CHKERRQ(ierr); 00069 ierr = TransformObjectSetExplanation(cur,"Hypre pILUt"); CHKERRQ(ierr); 00070 ierr = TransformObjectIntAnnotate(cur,"notrans",1); CHKERRQ(ierr); 00071 00072 ierr = NewTransformObject(PREPROCESSOR,PCEUCLID,&cur); CHKERRQ(ierr); 00073 ierr = TransformObjectSetExplanation(cur,"Hypre Euclid"); CHKERRQ(ierr); 00074 ierr = TransformObjectIntAnnotate(cur,"notrans",1); CHKERRQ(ierr); 00075 ierr = TransformObjectDefineOption(cur,"fill"); CHKERRQ(ierr); 00076 ierr = TransformObjectAddOption(cur,1); CHKERRQ(ierr); 00077 00078 ierr = NewTransformObject(PREPROCESSOR,PCPARASAILS,&cur); CHKERRQ(ierr); 00079 ierr = TransformObjectSetExplanation(cur,"Hypre ParaSails"); CHKERRQ(ierr); 00080 ierr = TransformObjectIntAnnotate(cur,"notrans",1); CHKERRQ(ierr); 00081 ierr = TransformObjectDefineOption(cur,"fill"); CHKERRQ(ierr); 00082 ierr = TransformObjectAddOption(cur,1); CHKERRQ(ierr); 00083 ierr = TransformObjectAddOption(cur,2); CHKERRQ(ierr); 00084 ierr = TransformObjectAddOption(cur,3); CHKERRQ(ierr); 00085 #endif 00086 00087 /* 00088 * ILU sequential 00089 */ 00090 ierr = NewTransformObject(PREPROCESSOR,PCILU,&cur); CHKERRQ(ierr); 00091 ierr = TransformObjectSetExplanation(cur,"Incomplete LU"); CHKERRQ(ierr); 00092 ierr = TransformObjectIntAnnotate(cur,"noparallel",1); CHKERRQ(ierr); 00093 ierr = TransformObjectDefineOption(cur,"fill"); CHKERRQ(ierr); 00094 ierr = TransformObjectAddOption(cur,1); CHKERRQ(ierr); 00095 ierr = TransformObjectAddOption(cur,2); CHKERRQ(ierr); 00096 ierr = TransformObjectAddOption(cur,3); CHKERRQ(ierr); 00097 /* shifted version */ 00098 ierr = NewTransformObject(PREPROCESSOR,PCSILU,&cur); CHKERRQ(ierr); 00099 ierr = TransformObjectSetExplanation(cur,"shifted Incomplete LU"); CHKERRQ(ierr); 00100 ierr = TransformObjectIntAnnotate(cur,"noparallel",1); CHKERRQ(ierr); 00101 ierr = TransformObjectDefineOption(cur,"fill"); CHKERRQ(ierr); 00102 ierr = TransformObjectAddOption(cur,1); CHKERRQ(ierr); 00103 ierr = TransformObjectAddOption(cur,2); CHKERRQ(ierr); 00104 ierr = TransformObjectAddOption(cur,3); CHKERRQ(ierr); 00105 00106 #if 0 00107 #if defined(PETSC_HAVE_SPAI) 00108 /* 00109 * SPAI 00110 */ 00111 ierr = NewTransformObject(PREPROCESSOR,PCSPAI,&cur); CHKERRQ(ierr); 00112 ierr = TransformObjectSetExplanation(cur,"Sparse Approximate Inverse"); CHKERRQ(ierr); 00113 ierr = TransformObjectIntAnnotate(cur,"notrans",1); CHKERRQ(ierr); 00114 ierr = TransformObjectIntAnnotate(cur,"noparallel",1); CHKERRQ(ierr); 00115 ierr = TransformObjectDefineOption(cur,"blocksize"); CHKERRQ(ierr); 00116 ierr = TransformObjectAddOption(cur,1); CHKERRQ(ierr); 00117 ierr = TransformObjectAddOption(cur,2); CHKERRQ(ierr); 00118 ierr = TransformObjectAddOption(cur,3); CHKERRQ(ierr); 00119 #endif 00120 #endif 00121 00122 /* 00123 * Additive Schwarz 00124 */ 00125 ierr = NewTransformObject 00126 (PREPROCESSOR,PCASM,&cur); CHKERRQ(ierr); 00127 ierr = TransformObjectSetExplanation(cur,"Additive Schwarz method"); CHKERRQ(ierr); 00128 ierr = TransformObjectDefineOption(cur,"local-method"); CHKERRQ(ierr); 00129 /* 00130 ierr = TransformCurrentItemDefineOption(cur,"local method: -1: LU; $\\geq1$ fill levels$+1$; $\\leq-1$: negative of local CG iterations$+1$","local method"); CHKERRQ(ierr); 00131 */ 00132 ierr = TransformObjectAddOption(cur,1); CHKERRQ(ierr); 00133 ierr = TransformObjectAddOptionExplanation(cur,1,"ILU(0)"); CHKERRQ(ierr); 00134 ierr = TransformObjectAddOption(cur,2); CHKERRQ(ierr); 00135 ierr = TransformObjectAddOptionExplanation(cur,2,"ILU(1)"); CHKERRQ(ierr); 00136 ierr = TransformObjectAddOption(cur,3); CHKERRQ(ierr); 00137 ierr = TransformObjectAddOptionExplanation(cur,3,"ILU(2)"); CHKERRQ(ierr); 00138 ierr = TransformObjectAddOption(cur,-1); CHKERRQ(ierr); 00139 ierr = TransformObjectAddOptionExplanation(cur,-1,"LU"); CHKERRQ(ierr); 00140 /* 00141 ierr = TransformObjectAddOption(cur,-7); CHKERRQ(ierr); 00142 ierr = TransformObjectAddOptionExplanation 00143 (cur,"6 iterations GMRES"); CHKERRQ(ierr); 00144 */ 00145 00146 /* 00147 * Restricted Additive Schwarz 00148 */ 00149 ierr = NewTransformObject(PREPROCESSOR,PCRASM,&cur); CHKERRQ(ierr); 00150 ierr = TransformObjectSetExplanation(cur,"Restrictied Additive Schwarz method"); CHKERRQ(ierr); 00151 ierr = TransformObjectDefineOption(cur,"local-method"); CHKERRQ(ierr); 00152 ierr = TransformObjectAddOption(cur,1); CHKERRQ(ierr); 00153 ierr = TransformObjectAddOptionExplanation(cur,1,"ILU(0)"); CHKERRQ(ierr); 00154 ierr = TransformObjectAddOption(cur,2); CHKERRQ(ierr); 00155 ierr = TransformObjectAddOptionExplanation(cur,2,"ILU(1)"); CHKERRQ(ierr); 00156 ierr = TransformObjectAddOption(cur,3); CHKERRQ(ierr); 00157 ierr = TransformObjectAddOptionExplanation(cur,3,"ILU(2)"); CHKERRQ(ierr); 00158 ierr = TransformObjectAddOption(cur,-1); CHKERRQ(ierr); 00159 ierr = TransformObjectAddOptionExplanation(cur,-1,"LU"); CHKERRQ(ierr); 00160 /* 00161 ierr = TransformObjectAddOption(cur,-7); CHKERRQ(ierr); 00162 ierr = TransformObjectAddOptionExplanation 00163 (cur,"6 iterations GMRES"); CHKERRQ(ierr); 00164 */ 00165 00166 /* 00167 * Block Jacobi 00168 */ 00169 ierr = NewTransformObject(PREPROCESSOR,PCBJACOBI,&cur); CHKERRQ(ierr); 00170 ierr = TransformObjectSetExplanation(cur,"Block Jacobi"); CHKERRQ(ierr); 00171 ierr = TransformObjectDefineOption(cur,"local-method"); CHKERRQ(ierr); 00172 ierr = TransformObjectIntAnnotate(cur,"notrans",1); CHKERRQ(ierr); 00173 ierr = TransformObjectAddOption(cur,1); CHKERRQ(ierr); 00174 ierr = TransformObjectAddOption(cur,2); CHKERRQ(ierr); 00175 ierr = TransformObjectAddOption(cur,3); CHKERRQ(ierr); 00176 ierr = TransformObjectAddOption(cur,-1); CHKERRQ(ierr); 00177 /* 00178 ierr = TransformObjectAddOption(cur,-7); CHKERRQ(ierr); 00179 */ 00180 00181 ierr = NewTransformObject(PREPROCESSOR,PCJACOBI,&cur); CHKERRQ(ierr); 00182 ierr = TransformObjectSetExplanation(cur,"Point Jacobi"); CHKERRQ(ierr); 00183 ierr = NewTransformObject(PREPROCESSOR,PCNONE,&cur); CHKERRQ(ierr); 00184 ierr = TransformObjectSetExplanation(cur,"None"); CHKERRQ(ierr); 00185 00186 /* 00187 * Direct methods 00188 */ 00189 ierr = NewTransformObject(PREPROCESSOR,PCLU,&cur); CHKERRQ(ierr); 00190 ierr = TransformObjectSetExplanation(cur,"Petsc LU"); CHKERRQ(ierr); 00191 ierr = TransformObjectIntAnnotate(cur,"directsolve",1); CHKERRQ(ierr); 00192 #if defined(PETSC_HAVE_MUMPS) 00193 ierr = NewTransformObject(PREPROCESSOR,PCMUMPS,&cur); CHKERRQ(ierr); 00194 ierr = TransformObjectSetExplanation(cur,"Mumps LU"); CHKERRQ(ierr); 00195 ierr = TransformObjectIntAnnotate(cur,"directsolve",1); CHKERRQ(ierr); 00196 #endif 00197 #if defined(PETSC_HAVE_SPOOLES) 00198 ierr = NewTransformObject(PREPROCESSOR,PCSPOOLES,&cur); CHKERRQ(ierr); 00199 ierr = TransformObjectSetExplanation(cur,"Spooles LU"); CHKERRQ(ierr); 00200 ierr = TransformObjectIntAnnotate(cur,"directsolve",1); CHKERRQ(ierr); 00201 #endif 00202 #if defined(PETSC_HAVE_SUPERLU_DIST) 00203 ierr = NewTransformObject(PREPROCESSOR,PCSUPERLU,&cur); CHKERRQ(ierr); 00204 ierr = TransformObjectSetExplanation(cur,"SuperLU LU"); CHKERRQ(ierr); 00205 ierr = TransformObjectIntAnnotate(cur,"directsolve",1); CHKERRQ(ierr); 00206 #endif 00207 #if defined(PETSC_HAVE_UMFPACK) 00208 ierr = NewTransformObject(PREPROCESSOR,PCUMFPACK,&cur); CHKERRQ(ierr); 00209 ierr = TransformObjectSetExplanation(cur,"Umfpack LU"); CHKERRQ(ierr); 00210 ierr = TransformObjectIntAnnotate(cur,"directsolve",1); CHKERRQ(ierr); 00211 #endif 00212 00213 PetscFunctionReturn(0); 00214 } 00215 00216 #undef __FUNCT__ 00217 #define __FUNCT__ "disable_pcs" 00218 static PetscErrorCode disable_pcs 00219 (NumericalProblem theproblem,SalsaTransform pc) 00220 { 00221 SalsaTransformObject curpc; int ds; 00222 PetscBool flg; PetscErrorCode ierr; 00223 PetscFunctionBegin; 00224 00225 ierr = SysProRetrieveQuantity 00226 (theproblem,"variance","diagonal-sign",(void*)&ds,PETSC_NULL, 00227 &flg); CHKERRQ(ierr); 00228 ierr = TransformObjectGetByName("pc","euclid",&curpc); CHKERRQ(ierr); 00229 if (0) { 00230 ierr = TransformObjectMark(curpc); CHKERRQ(ierr);} 00231 00232 PetscFunctionReturn(0); 00233 } 00234 00235 #undef __FUNCT__ 00236 #define __FUNCT__ "pcoptionshandling" 00237 /*! Disable certain preconditioners based on commandline options. 00238 00239 At the moment this is only disabling of direct solvers if the 00240 user asks for iterative only. 00241 */ 00242 static PetscErrorCode pcoptionshandling() 00243 { 00244 char **names; int nnames,iname; PetscBool onlyiterative,onlydirect; 00245 PetscErrorCode ierr; 00246 PetscFunctionBegin; 00247 ierr = PetscOptionsHasName 00248 (PETSC_NULL,"-syspro_pc_iterative",&onlyiterative); CHKERRQ(ierr); 00249 ierr = PetscOptionsHasName 00250 (PETSC_NULL,"-syspro_pc_direct",&onlydirect); CHKERRQ(ierr); 00251 if (onlyiterative || onlydirect) { 00252 ierr = RetrieveAllPreprocessorValues 00253 (PREPROCESSOR,(const char***)&names,&nnames); CHKERRQ(ierr); 00254 for (iname=0; iname<nnames; iname++) { 00255 SalsaTransformObject to; int isdirect; PetscBool flg; 00256 ierr = TransformObjectGetByName 00257 (PREPROCESSOR,names[iname],&to); CHKERRQ(ierr); 00258 ierr = TransformObjectGetIntAnnotation 00259 (to,"directsolve",&isdirect,&flg); CHKERRQ(ierr); 00260 if ( (flg && isdirect && onlyiterative) || 00261 ( onlydirect && ( !flg || !isdirect) ) 00262 ){ 00263 ierr = TransformObjectMark(to); CHKERRQ(ierr); 00264 } 00265 } 00266 } 00267 PetscFunctionReturn(0); 00268 } 00269 00270 #undef __FUNCT__ 00271 #define __FUNCT__ "create_solver" 00272 /*! Create a solver and 00273 install a monitor that dynamically increases the maximum 00274 number of iterations. 00275 */ 00276 static PetscErrorCode create_solver(NumericalProblem prob,void **ctx) 00277 { 00278 KSP solver; PetscErrorCode ierr; 00279 PetscFunctionBegin; 00280 00281 ierr = KSPCreate(prob->comm,&solver); CHKERRQ(ierr); 00282 /*ierr = SysProLinearInstallCustomKSPMonitor(solver); CHKERRQ(ierr);*/ 00283 *(KSP*)ctx = solver; 00284 #if 0 00285 { 00286 PC pc; 00287 ierr = PCCreate(prob->comm,&pc); CHKERRQ(ierr); 00288 *(PC*)ctx = pc; 00289 } 00290 #endif 00291 PetscFunctionReturn(0); 00292 } 00293 00294 #undef __FUNCT__ 00295 #define __FUNCT__ "destroy_solver" 00296 static PetscErrorCode destroy_solver(void *ctx) 00297 { 00298 KSP solver; PetscErrorCode ierr; 00299 PetscFunctionBegin; 00300 00301 solver = (KSP)ctx; 00302 ierr = KSPDestroy(&solver); CHKERRQ(ierr); 00303 #if 0 00304 { 00305 PC pc; 00306 pc = (PC)ctx; 00307 ierr = PCDestroy(pc); CHKERRQ(ierr); 00308 } 00309 #endif 00310 PetscFunctionReturn(0); 00311 } 00312 00313 #undef __FUNCT__ 00314 #define __FUNCT__ "setup_pc" 00315 static PetscErrorCode setup_pc 00316 (const char *type,int pcv,PetscBool overwrite, 00317 NumericalProblem inproblem,NumericalProblem *outproblem, 00318 void *gctx,void **ctx,PetscBool *success) 00319 { 00320 LinearSystem newproblem,problem = (LinearSystem)inproblem; 00321 KSP solver; PC pc; Mat A,B,Buse; 00322 PetscErrorCode ierr; 00323 00324 PetscFunctionBegin; 00325 /* 00326 * handling the problem data is trivial 00327 */ 00328 ierr = LinearSystemDuplicatePointers(problem,&newproblem); CHKERRQ(ierr); 00329 00330 ierr = LinearSystemGetParts 00331 (problem,&A,&B,PETSC_NULL,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); 00332 ierr = set_preconditioner_base_matrix((PCType)type,B,&Buse); CHKERRQ(ierr); 00333 ierr = LinearSystemSetParts 00334 (newproblem,PETSC_NULL,Buse,PETSC_NULL,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); 00335 /* ierr = PurgeAttachedArrays(A); CHKERRQ(ierr);*/ 00336 ierr = PetscObjectStateIncrease((PetscObject)A); CHKERRQ(ierr); 00337 00338 *outproblem = (NumericalProblem)newproblem; 00339 00340 /* 00341 * the fun part is setting up the Petsc PC 00342 */ 00343 solver = (KSP)gctx; 00344 ierr = KSPSetOperators(solver,A,Buse); CHKERRQ(ierr); 00345 ierr = KSPGetPC(solver,&pc); CHKERRQ(ierr); 00346 #if 0 00347 pc = (PC)gctx; 00348 ierr = PCSetOperators(pc,A,Buse,SAME_NONZERO_PATTERN); CHKERRQ(ierr); 00349 #endif 00350 ierr = SetPetscOptionsForPC(pc,(PCType)type,pcv,6); CHKERRQ(ierr); 00351 { 00352 PetscLogDouble t1,t2,*tstore; PetscErrorCode ierr_save1,ierr_save2; 00353 ierr = PetscTime(&t1); CHKERRQ(ierr); 00354 ierr = PCSetFromOptions(pc); CHKERRQ(ierr); 00355 ierr = PetscPushErrorHandler(&PetscReturnErrorHandler,NULL); CHKERRQ(ierr); 00356 ierr = PCSetUp(pc); ierr_save1 = ierr; 00357 ierr = PCSetUpOnBlocks(pc); ierr_save2 = ierr; 00358 ierr = PetscTime(&t2); CHKERRQ(ierr); 00359 ierr = PetscPopErrorHandler(); CHKERRQ(ierr); 00360 *success = TRUTH(!ierr_save1 && !ierr_save2); 00361 ierr = PreprocessorGetContext("solution",(void**)&tstore); CHKERRQ(ierr); 00362 *tstore = t2-t1; 00363 } 00364 00365 PetscFunctionReturn(0); 00366 } 00367 00368 #undef __FUNCT__ 00369 #define __FUNCT__ "unset_pc" 00370 static PetscErrorCode unset_pc 00371 (const char *type,PetscBool overwrite,void *gctx,void *ctx, 00372 NumericalProblem thisproblem,NumericalProblem upproblem, 00373 NumericalSolution old,NumericalSolution nnew) 00374 { 00375 LinearSystem problem = (LinearSystem)thisproblem; 00376 Mat A; 00377 PetscErrorCode ierr; 00378 00379 PetscFunctionBegin; 00380 ierr = LinearSystemGetParts 00381 (problem,&A,PETSC_NULL,PETSC_NULL,PETSC_NULL,PETSC_NULL); CHKERRQ(ierr); 00382 /* ierr = PurgeAttachedArrays(A); CHKERRQ(ierr);*/ 00383 ierr = PetscObjectStateDecrease((PetscObject)A); CHKERRQ(ierr); 00384 00385 ierr = LinearSolutionCopy 00386 ((LinearSolution)old,(LinearSolution)nnew); CHKERRQ(ierr); 00387 /*ierr = LinearSolutionDelete((LinearSolution)old); CHKERRQ(ierr);*/ 00388 //ierr = DeleteLinearSystem((LinearSystem)thisproblem); CHKERRQ(ierr); 00389 PetscFunctionReturn(0); 00390 } 00391 00392 #undef __FUNCT__ 00393 #define __FUNCT__ "DeclarePCPreprocessor" 00394 PetscErrorCode DeclarePCPreprocessor(void) 00395 { 00396 SystemPreprocessor pp; PetscErrorCode ierr; 00397 PetscFunctionBegin; 00398 ierr = DeclarePreprocessor 00399 (PREPROCESSOR, 00400 &setup_pc_choices,&disable_pcs,0,0, 00401 &create_solver,&destroy_solver, 00402 &setup_pc,&unset_pc); CHKERRQ(ierr); 00403 ierr = PreprocessorSetPreservedCategories 00404 (PREPROCESSOR,"laplace"); CHKERRQ(ierr); 00405 ierr = SystemPreprocessorGetByName(PREPROCESSOR,&pp); CHKERRQ(ierr); 00406 pp->optionshandling = &pcoptionshandling; 00407 PetscFunctionReturn(0); 00408 }
1.7.6.1