1 2 #include <private/snesimpl.h> /*I "petscsnes.h" I*/ 3 4 PetscBool SNESRegisterAllCalled = PETSC_FALSE; 5 PetscFList SNESList = PETSC_NULL; 6 7 /* Logging support */ 8 PetscClassId SNES_CLASSID; 9 PetscLogEvent SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval; 10 11 #undef __FUNCT__ 12 #define __FUNCT__ "SNESSetErrorIfNotConverged" 13 /*@ 14 SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 15 16 Logically Collective on SNES 17 18 Input Parameters: 19 + snes - iterative context obtained from SNESCreate() 20 - flg - PETSC_TRUE indicates you want the error generated 21 22 Options database keys: 23 . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 24 25 Level: intermediate 26 27 Notes: 28 Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 29 to determine if it has converged. 30 31 .keywords: SNES, set, initial guess, nonzero 32 33 .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 34 @*/ 35 PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 36 { 37 PetscFunctionBegin; 38 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39 PetscValidLogicalCollectiveBool(snes,flg,2); 40 snes->errorifnotconverged = flg; 41 PetscFunctionReturn(0); 42 } 43 44 #undef __FUNCT__ 45 #define __FUNCT__ "SNESGetErrorIfNotConverged" 46 /*@ 47 SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 48 49 Not Collective 50 51 Input Parameter: 52 . snes - iterative context obtained from SNESCreate() 53 54 Output Parameter: 55 . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 56 57 Level: intermediate 58 59 .keywords: SNES, set, initial guess, nonzero 60 61 .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 62 @*/ 63 PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 64 { 65 PetscFunctionBegin; 66 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 67 PetscValidPointer(flag,2); 68 *flag = snes->errorifnotconverged; 69 PetscFunctionReturn(0); 70 } 71 72 #undef __FUNCT__ 73 #define __FUNCT__ "SNESSetFunctionDomainError" 74 /*@ 75 SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 76 in the functions domain. For example, negative pressure. 77 78 Logically Collective on SNES 79 80 Input Parameters: 81 . SNES - the SNES context 82 83 Level: advanced 84 85 .keywords: SNES, view 86 87 .seealso: SNESCreate(), SNESSetFunction() 88 @*/ 89 PetscErrorCode SNESSetFunctionDomainError(SNES snes) 90 { 91 PetscFunctionBegin; 92 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 93 snes->domainerror = PETSC_TRUE; 94 PetscFunctionReturn(0); 95 } 96 97 #undef __FUNCT__ 98 #define __FUNCT__ "SNESView" 99 /*@C 100 SNESView - Prints the SNES data structure. 101 102 Collective on SNES 103 104 Input Parameters: 105 + SNES - the SNES context 106 - viewer - visualization context 107 108 Options Database Key: 109 . -snes_view - Calls SNESView() at end of SNESSolve() 110 111 Notes: 112 The available visualization contexts include 113 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 114 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 115 output where only the first processor opens 116 the file. All other processors send their 117 data to the first processor to print. 118 119 The user can open an alternative visualization context with 120 PetscViewerASCIIOpen() - output to a specified file. 121 122 Level: beginner 123 124 .keywords: SNES, view 125 126 .seealso: PetscViewerASCIIOpen() 127 @*/ 128 PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 129 { 130 SNESKSPEW *kctx; 131 PetscErrorCode ierr; 132 KSP ksp; 133 PetscBool iascii,isstring; 134 135 PetscFunctionBegin; 136 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 137 if (!viewer) { 138 ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 139 } 140 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 141 PetscCheckSameComm(snes,1,viewer,2); 142 143 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 144 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 145 if (iascii) { 146 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 147 if (snes->ops->view) { 148 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 149 ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 150 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 151 } 152 ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 153 ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 154 snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr); 155 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 156 ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 157 if (snes->ksp_ewconv) { 158 kctx = (SNESKSPEW *)snes->kspconvctx; 159 if (kctx) { 160 ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 161 ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 162 ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 163 } 164 } 165 if (snes->lagpreconditioner == -1) { 166 ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 167 } else if (snes->lagpreconditioner > 1) { 168 ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 169 } 170 if (snes->lagjacobian == -1) { 171 ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 172 } else if (snes->lagjacobian > 1) { 173 ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D Newton iterations\n",snes->lagjacobian);CHKERRQ(ierr); 174 } 175 } else if (isstring) { 176 const char *type; 177 ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 178 ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 179 } 180 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 181 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 182 ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 183 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 184 PetscFunctionReturn(0); 185 } 186 187 /* 188 We retain a list of functions that also take SNES command 189 line options. These are called at the end SNESSetFromOptions() 190 */ 191 #define MAXSETFROMOPTIONS 5 192 static PetscInt numberofsetfromoptions; 193 static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 194 195 #undef __FUNCT__ 196 #define __FUNCT__ "SNESAddOptionsChecker" 197 /*@C 198 SNESAddOptionsChecker - Adds an additional function to check for SNES options. 199 200 Not Collective 201 202 Input Parameter: 203 . snescheck - function that checks for options 204 205 Level: developer 206 207 .seealso: SNESSetFromOptions() 208 @*/ 209 PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 210 { 211 PetscFunctionBegin; 212 if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 213 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 214 } 215 othersetfromoptions[numberofsetfromoptions++] = snescheck; 216 PetscFunctionReturn(0); 217 } 218 219 extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 220 221 #undef __FUNCT__ 222 #define __FUNCT__ "SNESSetUpMatrixFree_Private" 223 static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 224 { 225 Mat J; 226 KSP ksp; 227 PC pc; 228 PetscBool match; 229 PetscErrorCode ierr; 230 231 PetscFunctionBegin; 232 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 233 234 if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 235 Mat A = snes->jacobian, B = snes->jacobian_pre; 236 ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 237 } 238 239 if (version == 1) { 240 ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 241 ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 242 ierr = MatSetFromOptions(J);CHKERRQ(ierr); 243 } else if (version == 2) { 244 if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 245 #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL_LONG_DOUBLE) 246 ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 247 #else 248 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 249 #endif 250 } else { 251 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 252 } 253 254 ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 255 if (hasOperator) { 256 /* This version replaces the user provided Jacobian matrix with a 257 matrix-free version but still employs the user-provided preconditioner matrix. */ 258 ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 259 } else { 260 /* This version replaces both the user-provided Jacobian and the user- 261 provided preconditioner matrix with the default matrix free version. */ 262 ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 263 /* Force no preconditioner */ 264 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 265 ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 266 ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 267 if (!match) { 268 ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 269 ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 270 } 271 } 272 ierr = MatDestroy(&J);CHKERRQ(ierr); 273 274 PetscFunctionReturn(0); 275 } 276 277 #undef __FUNCT__ 278 #define __FUNCT__ "SNESSetFromOptions" 279 /*@ 280 SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 281 282 Collective on SNES 283 284 Input Parameter: 285 . snes - the SNES context 286 287 Options Database Keys: 288 + -snes_type <type> - ls, tr, umls, umtr, test 289 . -snes_stol - convergence tolerance in terms of the norm 290 of the change in the solution between steps 291 . -snes_atol <abstol> - absolute tolerance of residual norm 292 . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 293 . -snes_max_it <max_it> - maximum number of iterations 294 . -snes_max_funcs <max_funcs> - maximum number of function evaluations 295 . -snes_max_fail <max_fail> - maximum number of failures 296 . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 297 . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 298 . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 299 . -snes_trtol <trtol> - trust region tolerance 300 . -snes_no_convergence_test - skip convergence test in nonlinear 301 solver; hence iterations will continue until max_it 302 or some other criterion is reached. Saves expense 303 of convergence test 304 . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 305 filename given prints to stdout 306 . -snes_monitor_solution - plots solution at each iteration 307 . -snes_monitor_residual - plots residual (not its norm) at each iteration 308 . -snes_monitor_solution_update - plots update to solution at each iteration 309 . -snes_monitor_draw - plots residual norm at each iteration 310 . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 311 . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 312 - -snes_converged_reason - print the reason for convergence/divergence after each solve 313 314 Options Database for Eisenstat-Walker method: 315 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 316 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 317 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 318 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 319 . -snes_ksp_ew_gamma <gamma> - Sets gamma 320 . -snes_ksp_ew_alpha <alpha> - Sets alpha 321 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 322 - -snes_ksp_ew_threshold <threshold> - Sets threshold 323 324 Notes: 325 To see all options, run your program with the -help option or consult 326 the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 327 328 Level: beginner 329 330 .keywords: SNES, nonlinear, set, options, database 331 332 .seealso: SNESSetOptionsPrefix() 333 @*/ 334 PetscErrorCode SNESSetFromOptions(SNES snes) 335 { 336 PetscBool flg,mf,mf_operator; 337 PetscInt i,indx,lag,mf_version; 338 MatStructure matflag; 339 const char *deft = SNESLS; 340 const char *convtests[] = {"default","skip"}; 341 SNESKSPEW *kctx = NULL; 342 char type[256], monfilename[PETSC_MAX_PATH_LEN]; 343 PetscViewerASCIIMonitor monviewer; 344 PetscErrorCode ierr; 345 346 PetscFunctionBegin; 347 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 348 349 if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 350 ierr = PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");CHKERRQ(ierr); 351 if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 352 ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 353 if (flg) { 354 ierr = SNESSetType(snes,type);CHKERRQ(ierr); 355 } else if (!((PetscObject)snes)->type_name) { 356 ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 357 } 358 /* not used here, but called so will go into help messaage */ 359 ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 360 361 ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr); 362 ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 363 364 ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 365 ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 366 ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 367 ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 368 ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 369 ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 370 371 ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 372 if (flg) { 373 ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 374 } 375 ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 376 if (flg) { 377 ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 378 } 379 380 ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 381 if (flg) { 382 switch (indx) { 383 case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 384 case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 385 } 386 } 387 388 ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 389 390 kctx = (SNESKSPEW *)snes->kspconvctx; 391 392 ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 393 394 ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 395 ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 396 ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 397 ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 398 ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 399 ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 400 ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 401 402 flg = PETSC_FALSE; 403 ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 404 if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 405 406 ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 407 if (flg) { 408 ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr); 409 ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr); 410 } 411 412 ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 413 if (flg) { 414 ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 415 } 416 417 ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 418 if (flg) { 419 ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr); 420 ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 421 } 422 423 ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 424 if (flg) { 425 ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr); 426 ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr); 427 } 428 429 flg = PETSC_FALSE; 430 ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 431 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 432 flg = PETSC_FALSE; 433 ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 434 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 435 flg = PETSC_FALSE; 436 ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 437 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 438 flg = PETSC_FALSE; 439 ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 440 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 441 flg = PETSC_FALSE; 442 ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 443 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 444 445 flg = PETSC_FALSE; 446 ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 447 if (flg) { 448 ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr); 449 ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 450 } 451 452 mf = mf_operator = PETSC_FALSE; 453 flg = PETSC_FALSE; 454 ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 455 if (flg && mf_operator) mf = PETSC_TRUE; 456 flg = PETSC_FALSE; 457 ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 458 if (!flg && mf_operator) mf = PETSC_TRUE; 459 mf_version = 1; 460 ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 461 462 for(i = 0; i < numberofsetfromoptions; i++) { 463 ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 464 } 465 466 if (snes->ops->setfromoptions) { 467 ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 468 } 469 470 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 471 ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 472 ierr = PetscOptionsEnd();CHKERRQ(ierr); 473 474 if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 475 476 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 477 ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 478 ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 479 ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 480 481 PetscFunctionReturn(0); 482 } 483 484 485 #undef __FUNCT__ 486 #define __FUNCT__ "SNESSetApplicationContext" 487 /*@ 488 SNESSetApplicationContext - Sets the optional user-defined context for 489 the nonlinear solvers. 490 491 Logically Collective on SNES 492 493 Input Parameters: 494 + snes - the SNES context 495 - usrP - optional user context 496 497 Level: intermediate 498 499 .keywords: SNES, nonlinear, set, application, context 500 501 .seealso: SNESGetApplicationContext() 502 @*/ 503 PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 504 { 505 PetscFunctionBegin; 506 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 507 snes->user = usrP; 508 PetscFunctionReturn(0); 509 } 510 511 #undef __FUNCT__ 512 #define __FUNCT__ "SNESGetApplicationContext" 513 /*@C 514 SNESGetApplicationContext - Gets the user-defined context for the 515 nonlinear solvers. 516 517 Not Collective 518 519 Input Parameter: 520 . snes - SNES context 521 522 Output Parameter: 523 . usrP - user context 524 525 Level: intermediate 526 527 .keywords: SNES, nonlinear, get, application, context 528 529 .seealso: SNESSetApplicationContext() 530 @*/ 531 PetscErrorCode SNESGetApplicationContext(SNES snes,void **usrP) 532 { 533 PetscFunctionBegin; 534 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 535 *usrP = snes->user; 536 PetscFunctionReturn(0); 537 } 538 539 #undef __FUNCT__ 540 #define __FUNCT__ "SNESGetIterationNumber" 541 /*@ 542 SNESGetIterationNumber - Gets the number of nonlinear iterations completed 543 at this time. 544 545 Not Collective 546 547 Input Parameter: 548 . snes - SNES context 549 550 Output Parameter: 551 . iter - iteration number 552 553 Notes: 554 For example, during the computation of iteration 2 this would return 1. 555 556 This is useful for using lagged Jacobians (where one does not recompute the 557 Jacobian at each SNES iteration). For example, the code 558 .vb 559 ierr = SNESGetIterationNumber(snes,&it); 560 if (!(it % 2)) { 561 [compute Jacobian here] 562 } 563 .ve 564 can be used in your ComputeJacobian() function to cause the Jacobian to be 565 recomputed every second SNES iteration. 566 567 Level: intermediate 568 569 .keywords: SNES, nonlinear, get, iteration, number, 570 571 .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 572 @*/ 573 PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 574 { 575 PetscFunctionBegin; 576 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 577 PetscValidIntPointer(iter,2); 578 *iter = snes->iter; 579 PetscFunctionReturn(0); 580 } 581 582 #undef __FUNCT__ 583 #define __FUNCT__ "SNESGetFunctionNorm" 584 /*@ 585 SNESGetFunctionNorm - Gets the norm of the current function that was set 586 with SNESSSetFunction(). 587 588 Collective on SNES 589 590 Input Parameter: 591 . snes - SNES context 592 593 Output Parameter: 594 . fnorm - 2-norm of function 595 596 Level: intermediate 597 598 .keywords: SNES, nonlinear, get, function, norm 599 600 .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 601 @*/ 602 PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 603 { 604 PetscFunctionBegin; 605 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 606 PetscValidScalarPointer(fnorm,2); 607 *fnorm = snes->norm; 608 PetscFunctionReturn(0); 609 } 610 611 #undef __FUNCT__ 612 #define __FUNCT__ "SNESGetNonlinearStepFailures" 613 /*@ 614 SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 615 attempted by the nonlinear solver. 616 617 Not Collective 618 619 Input Parameter: 620 . snes - SNES context 621 622 Output Parameter: 623 . nfails - number of unsuccessful steps attempted 624 625 Notes: 626 This counter is reset to zero for each successive call to SNESSolve(). 627 628 Level: intermediate 629 630 .keywords: SNES, nonlinear, get, number, unsuccessful, steps 631 632 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 633 SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 634 @*/ 635 PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 636 { 637 PetscFunctionBegin; 638 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 639 PetscValidIntPointer(nfails,2); 640 *nfails = snes->numFailures; 641 PetscFunctionReturn(0); 642 } 643 644 #undef __FUNCT__ 645 #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 646 /*@ 647 SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 648 attempted by the nonlinear solver before it gives up. 649 650 Not Collective 651 652 Input Parameters: 653 + snes - SNES context 654 - maxFails - maximum of unsuccessful steps 655 656 Level: intermediate 657 658 .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 659 660 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 661 SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 662 @*/ 663 PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 664 { 665 PetscFunctionBegin; 666 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 667 snes->maxFailures = maxFails; 668 PetscFunctionReturn(0); 669 } 670 671 #undef __FUNCT__ 672 #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 673 /*@ 674 SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 675 attempted by the nonlinear solver before it gives up. 676 677 Not Collective 678 679 Input Parameter: 680 . snes - SNES context 681 682 Output Parameter: 683 . maxFails - maximum of unsuccessful steps 684 685 Level: intermediate 686 687 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 688 689 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 690 SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 691 692 @*/ 693 PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 694 { 695 PetscFunctionBegin; 696 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 697 PetscValidIntPointer(maxFails,2); 698 *maxFails = snes->maxFailures; 699 PetscFunctionReturn(0); 700 } 701 702 #undef __FUNCT__ 703 #define __FUNCT__ "SNESGetNumberFunctionEvals" 704 /*@ 705 SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 706 done by SNES. 707 708 Not Collective 709 710 Input Parameter: 711 . snes - SNES context 712 713 Output Parameter: 714 . nfuncs - number of evaluations 715 716 Level: intermediate 717 718 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 719 720 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 721 @*/ 722 PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 723 { 724 PetscFunctionBegin; 725 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 726 PetscValidIntPointer(nfuncs,2); 727 *nfuncs = snes->nfuncs; 728 PetscFunctionReturn(0); 729 } 730 731 #undef __FUNCT__ 732 #define __FUNCT__ "SNESGetLinearSolveFailures" 733 /*@ 734 SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 735 linear solvers. 736 737 Not Collective 738 739 Input Parameter: 740 . snes - SNES context 741 742 Output Parameter: 743 . nfails - number of failed solves 744 745 Notes: 746 This counter is reset to zero for each successive call to SNESSolve(). 747 748 Level: intermediate 749 750 .keywords: SNES, nonlinear, get, number, unsuccessful, steps 751 752 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 753 @*/ 754 PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 755 { 756 PetscFunctionBegin; 757 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 758 PetscValidIntPointer(nfails,2); 759 *nfails = snes->numLinearSolveFailures; 760 PetscFunctionReturn(0); 761 } 762 763 #undef __FUNCT__ 764 #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 765 /*@ 766 SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 767 allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 768 769 Logically Collective on SNES 770 771 Input Parameters: 772 + snes - SNES context 773 - maxFails - maximum allowed linear solve failures 774 775 Level: intermediate 776 777 Notes: By default this is 0; that is SNES returns on the first failed linear solve 778 779 .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 780 781 .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 782 @*/ 783 PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 784 { 785 PetscFunctionBegin; 786 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 787 PetscValidLogicalCollectiveInt(snes,maxFails,2); 788 snes->maxLinearSolveFailures = maxFails; 789 PetscFunctionReturn(0); 790 } 791 792 #undef __FUNCT__ 793 #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 794 /*@ 795 SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 796 are allowed before SNES terminates 797 798 Not Collective 799 800 Input Parameter: 801 . snes - SNES context 802 803 Output Parameter: 804 . maxFails - maximum of unsuccessful solves allowed 805 806 Level: intermediate 807 808 Notes: By default this is 1; that is SNES returns on the first failed linear solve 809 810 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 811 812 .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 813 @*/ 814 PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 815 { 816 PetscFunctionBegin; 817 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 818 PetscValidIntPointer(maxFails,2); 819 *maxFails = snes->maxLinearSolveFailures; 820 PetscFunctionReturn(0); 821 } 822 823 #undef __FUNCT__ 824 #define __FUNCT__ "SNESGetLinearSolveIterations" 825 /*@ 826 SNESGetLinearSolveIterations - Gets the total number of linear iterations 827 used by the nonlinear solver. 828 829 Not Collective 830 831 Input Parameter: 832 . snes - SNES context 833 834 Output Parameter: 835 . lits - number of linear iterations 836 837 Notes: 838 This counter is reset to zero for each successive call to SNESSolve(). 839 840 Level: intermediate 841 842 .keywords: SNES, nonlinear, get, number, linear, iterations 843 844 .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 845 @*/ 846 PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 847 { 848 PetscFunctionBegin; 849 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 850 PetscValidIntPointer(lits,2); 851 *lits = snes->linear_its; 852 PetscFunctionReturn(0); 853 } 854 855 #undef __FUNCT__ 856 #define __FUNCT__ "SNESGetKSP" 857 /*@ 858 SNESGetKSP - Returns the KSP context for a SNES solver. 859 860 Not Collective, but if SNES object is parallel, then KSP object is parallel 861 862 Input Parameter: 863 . snes - the SNES context 864 865 Output Parameter: 866 . ksp - the KSP context 867 868 Notes: 869 The user can then directly manipulate the KSP context to set various 870 options, etc. Likewise, the user can then extract and manipulate the 871 PC contexts as well. 872 873 Level: beginner 874 875 .keywords: SNES, nonlinear, get, KSP, context 876 877 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 878 @*/ 879 PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 880 { 881 PetscErrorCode ierr; 882 883 PetscFunctionBegin; 884 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 885 PetscValidPointer(ksp,2); 886 887 if (!snes->ksp) { 888 ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 889 ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 890 ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 891 } 892 *ksp = snes->ksp; 893 PetscFunctionReturn(0); 894 } 895 896 #undef __FUNCT__ 897 #define __FUNCT__ "SNESSetKSP" 898 /*@ 899 SNESSetKSP - Sets a KSP context for the SNES object to use 900 901 Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 902 903 Input Parameters: 904 + snes - the SNES context 905 - ksp - the KSP context 906 907 Notes: 908 The SNES object already has its KSP object, you can obtain with SNESGetKSP() 909 so this routine is rarely needed. 910 911 The KSP object that is already in the SNES object has its reference count 912 decreased by one. 913 914 Level: developer 915 916 .keywords: SNES, nonlinear, get, KSP, context 917 918 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 919 @*/ 920 PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 921 { 922 PetscErrorCode ierr; 923 924 PetscFunctionBegin; 925 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 926 PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 927 PetscCheckSameComm(snes,1,ksp,2); 928 ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 929 if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 930 snes->ksp = ksp; 931 PetscFunctionReturn(0); 932 } 933 934 #if 0 935 #undef __FUNCT__ 936 #define __FUNCT__ "SNESPublish_Petsc" 937 static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 938 { 939 PetscFunctionBegin; 940 PetscFunctionReturn(0); 941 } 942 #endif 943 944 /* -----------------------------------------------------------*/ 945 #undef __FUNCT__ 946 #define __FUNCT__ "SNESCreate" 947 /*@ 948 SNESCreate - Creates a nonlinear solver context. 949 950 Collective on MPI_Comm 951 952 Input Parameters: 953 . comm - MPI communicator 954 955 Output Parameter: 956 . outsnes - the new SNES context 957 958 Options Database Keys: 959 + -snes_mf - Activates default matrix-free Jacobian-vector products, 960 and no preconditioning matrix 961 . -snes_mf_operator - Activates default matrix-free Jacobian-vector 962 products, and a user-provided preconditioning matrix 963 as set by SNESSetJacobian() 964 - -snes_fd - Uses (slow!) finite differences to compute Jacobian 965 966 Level: beginner 967 968 .keywords: SNES, nonlinear, create, context 969 970 .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 971 972 @*/ 973 PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 974 { 975 PetscErrorCode ierr; 976 SNES snes; 977 SNESKSPEW *kctx; 978 979 PetscFunctionBegin; 980 PetscValidPointer(outsnes,2); 981 *outsnes = PETSC_NULL; 982 #ifndef PETSC_USE_DYNAMIC_LIBRARIES 983 ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 984 #endif 985 986 ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 987 988 snes->ops->converged = SNESDefaultConverged; 989 snes->max_its = 50; 990 snes->max_funcs = 10000; 991 snes->norm = 0.0; 992 snes->rtol = 1.e-8; 993 snes->ttol = 0.0; 994 snes->abstol = 1.e-50; 995 snes->xtol = 1.e-8; 996 snes->deltatol = 1.e-12; 997 snes->nfuncs = 0; 998 snes->numFailures = 0; 999 snes->maxFailures = 1; 1000 snes->linear_its = 0; 1001 snes->lagjacobian = 1; 1002 snes->lagpreconditioner = 1; 1003 snes->numbermonitors = 0; 1004 snes->data = 0; 1005 snes->setupcalled = PETSC_FALSE; 1006 snes->ksp_ewconv = PETSC_FALSE; 1007 snes->nwork = 0; 1008 snes->work = 0; 1009 snes->nvwork = 0; 1010 snes->vwork = 0; 1011 snes->conv_hist_len = 0; 1012 snes->conv_hist_max = 0; 1013 snes->conv_hist = PETSC_NULL; 1014 snes->conv_hist_its = PETSC_NULL; 1015 snes->conv_hist_reset = PETSC_TRUE; 1016 snes->reason = SNES_CONVERGED_ITERATING; 1017 1018 snes->numLinearSolveFailures = 0; 1019 snes->maxLinearSolveFailures = 1; 1020 1021 /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 1022 ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 1023 snes->kspconvctx = (void*)kctx; 1024 kctx->version = 2; 1025 kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 1026 this was too large for some test cases */ 1027 kctx->rtol_last = 0.0; 1028 kctx->rtol_max = .9; 1029 kctx->gamma = 1.0; 1030 kctx->alpha = .5*(1.0 + sqrt(5.0)); 1031 kctx->alpha2 = kctx->alpha; 1032 kctx->threshold = .1; 1033 kctx->lresid_last = 0.0; 1034 kctx->norm_last = 0.0; 1035 1036 *outsnes = snes; 1037 PetscFunctionReturn(0); 1038 } 1039 1040 #undef __FUNCT__ 1041 #define __FUNCT__ "SNESSetFunction" 1042 /*@C 1043 SNESSetFunction - Sets the function evaluation routine and function 1044 vector for use by the SNES routines in solving systems of nonlinear 1045 equations. 1046 1047 Logically Collective on SNES 1048 1049 Input Parameters: 1050 + snes - the SNES context 1051 . r - vector to store function value 1052 . func - function evaluation routine 1053 - ctx - [optional] user-defined context for private data for the 1054 function evaluation routine (may be PETSC_NULL) 1055 1056 Calling sequence of func: 1057 $ func (SNES snes,Vec x,Vec f,void *ctx); 1058 1059 . f - function vector 1060 - ctx - optional user-defined function context 1061 1062 Notes: 1063 The Newton-like methods typically solve linear systems of the form 1064 $ f'(x) x = -f(x), 1065 where f'(x) denotes the Jacobian matrix and f(x) is the function. 1066 1067 Level: beginner 1068 1069 .keywords: SNES, nonlinear, set, function 1070 1071 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1072 @*/ 1073 PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 1074 { 1075 PetscErrorCode ierr; 1076 PetscFunctionBegin; 1077 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1078 if (r) { 1079 PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1080 PetscCheckSameComm(snes,1,r,2); 1081 ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 1082 ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 1083 snes->vec_func = r; 1084 } else if (!snes->vec_func && snes->dm) { 1085 ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1086 } 1087 if (func) snes->ops->computefunction = func; 1088 if (ctx) snes->funP = ctx; 1089 PetscFunctionReturn(0); 1090 } 1091 1092 /* --------------------------------------------------------------- */ 1093 #undef __FUNCT__ 1094 #define __FUNCT__ "SNESGetRhs" 1095 /*@C 1096 SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 1097 it assumes a zero right hand side. 1098 1099 Logically Collective on SNES 1100 1101 Input Parameter: 1102 . snes - the SNES context 1103 1104 Output Parameter: 1105 . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 1106 1107 Level: intermediate 1108 1109 .keywords: SNES, nonlinear, get, function, right hand side 1110 1111 .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 1112 @*/ 1113 PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 1114 { 1115 PetscFunctionBegin; 1116 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1117 PetscValidPointer(rhs,2); 1118 *rhs = snes->vec_rhs; 1119 PetscFunctionReturn(0); 1120 } 1121 1122 #undef __FUNCT__ 1123 #define __FUNCT__ "SNESComputeFunction" 1124 /*@ 1125 SNESComputeFunction - Calls the function that has been set with 1126 SNESSetFunction(). 1127 1128 Collective on SNES 1129 1130 Input Parameters: 1131 + snes - the SNES context 1132 - x - input vector 1133 1134 Output Parameter: 1135 . y - function vector, as set by SNESSetFunction() 1136 1137 Notes: 1138 SNESComputeFunction() is typically used within nonlinear solvers 1139 implementations, so most users would not generally call this routine 1140 themselves. 1141 1142 Level: developer 1143 1144 .keywords: SNES, nonlinear, compute, function 1145 1146 .seealso: SNESSetFunction(), SNESGetFunction() 1147 @*/ 1148 PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 1149 { 1150 PetscErrorCode ierr; 1151 1152 PetscFunctionBegin; 1153 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1154 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1155 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1156 PetscCheckSameComm(snes,1,x,2); 1157 PetscCheckSameComm(snes,1,y,3); 1158 1159 ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1160 if (snes->ops->computefunction) { 1161 PetscStackPush("SNES user function"); 1162 ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr); 1163 PetscStackPop; 1164 } else if (snes->vec_rhs) { 1165 ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1166 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve()."); 1167 if (snes->vec_rhs) { 1168 ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 1169 } 1170 snes->nfuncs++; 1171 ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1172 PetscFunctionReturn(0); 1173 } 1174 1175 #undef __FUNCT__ 1176 #define __FUNCT__ "SNESComputeJacobian" 1177 /*@ 1178 SNESComputeJacobian - Computes the Jacobian matrix that has been 1179 set with SNESSetJacobian(). 1180 1181 Collective on SNES and Mat 1182 1183 Input Parameters: 1184 + snes - the SNES context 1185 - x - input vector 1186 1187 Output Parameters: 1188 + A - Jacobian matrix 1189 . B - optional preconditioning matrix 1190 - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1191 1192 Options Database Keys: 1193 + -snes_lag_preconditioner <lag> 1194 - -snes_lag_jacobian <lag> 1195 1196 Notes: 1197 Most users should not need to explicitly call this routine, as it 1198 is used internally within the nonlinear solvers. 1199 1200 See KSPSetOperators() for important information about setting the 1201 flag parameter. 1202 1203 Level: developer 1204 1205 .keywords: SNES, compute, Jacobian, matrix 1206 1207 .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 1208 @*/ 1209 PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 1210 { 1211 PetscErrorCode ierr; 1212 PetscBool flag; 1213 1214 PetscFunctionBegin; 1215 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1216 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 1217 PetscValidPointer(flg,5); 1218 PetscCheckSameComm(snes,1,X,2); 1219 if (!snes->ops->computejacobian) PetscFunctionReturn(0); 1220 1221 /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1222 1223 if (snes->lagjacobian == -2) { 1224 snes->lagjacobian = -1; 1225 ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1226 } else if (snes->lagjacobian == -1) { 1227 *flg = SAME_PRECONDITIONER; 1228 ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1229 ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1230 if (flag) { 1231 ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1232 ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1233 } 1234 PetscFunctionReturn(0); 1235 } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1236 *flg = SAME_PRECONDITIONER; 1237 ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1238 ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1239 if (flag) { 1240 ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1241 ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1242 } 1243 PetscFunctionReturn(0); 1244 } 1245 1246 *flg = DIFFERENT_NONZERO_PATTERN; 1247 ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1248 PetscStackPush("SNES user Jacobian function"); 1249 ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr); 1250 PetscStackPop; 1251 ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1252 1253 if (snes->lagpreconditioner == -2) { 1254 ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 1255 snes->lagpreconditioner = -1; 1256 } else if (snes->lagpreconditioner == -1) { 1257 *flg = SAME_PRECONDITIONER; 1258 ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1259 } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1260 *flg = SAME_PRECONDITIONER; 1261 ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1262 } 1263 1264 /* make sure user returned a correct Jacobian and preconditioner */ 1265 /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 1266 PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1267 PetscFunctionReturn(0); 1268 } 1269 1270 #undef __FUNCT__ 1271 #define __FUNCT__ "SNESSetJacobian" 1272 /*@C 1273 SNESSetJacobian - Sets the function to compute Jacobian as well as the 1274 location to store the matrix. 1275 1276 Logically Collective on SNES and Mat 1277 1278 Input Parameters: 1279 + snes - the SNES context 1280 . A - Jacobian matrix 1281 . B - preconditioner matrix (usually same as the Jacobian) 1282 . func - Jacobian evaluation routine 1283 - ctx - [optional] user-defined context for private data for the 1284 Jacobian evaluation routine (may be PETSC_NULL) 1285 1286 Calling sequence of func: 1287 $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 1288 1289 + x - input vector 1290 . A - Jacobian matrix 1291 . B - preconditioner matrix, usually the same as A 1292 . flag - flag indicating information about the preconditioner matrix 1293 structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 1294 - ctx - [optional] user-defined Jacobian context 1295 1296 Notes: 1297 See KSPSetOperators() for important information about setting the flag 1298 output parameter in the routine func(). Be sure to read this information! 1299 1300 The routine func() takes Mat * as the matrix arguments rather than Mat. 1301 This allows the Jacobian evaluation routine to replace A and/or B with a 1302 completely new new matrix structure (not just different matrix elements) 1303 when appropriate, for instance, if the nonzero structure is changing 1304 throughout the global iterations. 1305 1306 If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 1307 each matrix. 1308 1309 If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 1310 must be a MatFDColoring. 1311 1312 Level: beginner 1313 1314 .keywords: SNES, nonlinear, set, Jacobian, matrix 1315 1316 .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 1317 @*/ 1318 PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 1319 { 1320 PetscErrorCode ierr; 1321 1322 PetscFunctionBegin; 1323 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1324 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 1325 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 1326 if (A) PetscCheckSameComm(snes,1,A,2); 1327 if (B) PetscCheckSameComm(snes,1,B,3); 1328 if (func) snes->ops->computejacobian = func; 1329 if (ctx) snes->jacP = ctx; 1330 if (A) { 1331 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 1332 ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 1333 snes->jacobian = A; 1334 } 1335 if (B) { 1336 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 1337 ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 1338 snes->jacobian_pre = B; 1339 } 1340 PetscFunctionReturn(0); 1341 } 1342 1343 #undef __FUNCT__ 1344 #define __FUNCT__ "SNESGetJacobian" 1345 /*@C 1346 SNESGetJacobian - Returns the Jacobian matrix and optionally the user 1347 provided context for evaluating the Jacobian. 1348 1349 Not Collective, but Mat object will be parallel if SNES object is 1350 1351 Input Parameter: 1352 . snes - the nonlinear solver context 1353 1354 Output Parameters: 1355 + A - location to stash Jacobian matrix (or PETSC_NULL) 1356 . B - location to stash preconditioner matrix (or PETSC_NULL) 1357 . func - location to put Jacobian function (or PETSC_NULL) 1358 - ctx - location to stash Jacobian ctx (or PETSC_NULL) 1359 1360 Level: advanced 1361 1362 .seealso: SNESSetJacobian(), SNESComputeJacobian() 1363 @*/ 1364 PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 1365 { 1366 PetscFunctionBegin; 1367 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1368 if (A) *A = snes->jacobian; 1369 if (B) *B = snes->jacobian_pre; 1370 if (func) *func = snes->ops->computejacobian; 1371 if (ctx) *ctx = snes->jacP; 1372 PetscFunctionReturn(0); 1373 } 1374 1375 /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 1376 1377 #undef __FUNCT__ 1378 #define __FUNCT__ "SNESSetUp" 1379 /*@ 1380 SNESSetUp - Sets up the internal data structures for the later use 1381 of a nonlinear solver. 1382 1383 Collective on SNES 1384 1385 Input Parameters: 1386 . snes - the SNES context 1387 1388 Notes: 1389 For basic use of the SNES solvers the user need not explicitly call 1390 SNESSetUp(), since these actions will automatically occur during 1391 the call to SNESSolve(). However, if one wishes to control this 1392 phase separately, SNESSetUp() should be called after SNESCreate() 1393 and optional routines of the form SNESSetXXX(), but before SNESSolve(). 1394 1395 Level: advanced 1396 1397 .keywords: SNES, nonlinear, setup 1398 1399 .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 1400 @*/ 1401 PetscErrorCode SNESSetUp(SNES snes) 1402 { 1403 PetscErrorCode ierr; 1404 1405 PetscFunctionBegin; 1406 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1407 if (snes->setupcalled) PetscFunctionReturn(0); 1408 1409 if (!((PetscObject)snes)->type_name) { 1410 ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 1411 } 1412 1413 if (!snes->vec_func && !snes->vec_rhs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first"); 1414 if (!snes->ops->computefunction && !snes->vec_rhs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first"); 1415 if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 1416 if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 1417 1418 if (!snes->vec_func && snes->vec_rhs) { 1419 ierr = VecDuplicate(snes->vec_rhs, &snes->vec_func);CHKERRQ(ierr); 1420 } 1421 if (!snes->vec_sol_update /* && snes->vec_sol */) { 1422 ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 1423 ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 1424 } 1425 1426 if (!snes->ops->computejacobian && snes->dm) { 1427 Mat J; 1428 ISColoring coloring; 1429 MatFDColoring fd; 1430 1431 ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1432 ierr = DMGetColoring(snes->dm,IS_COLORING_GHOSTED,MATAIJ,&coloring);CHKERRQ(ierr); 1433 ierr = MatFDColoringCreate(J,coloring,&fd);CHKERRQ(ierr); 1434 ierr = MatFDColoringSetFunction(fd,(PetscErrorCode (*)(void))snes->ops->computefunction,snes->funP);CHKERRQ(ierr); 1435 ierr = SNESSetJacobian(snes,J,J,SNESDefaultComputeJacobianColor,fd);CHKERRQ(ierr); 1436 ierr = ISColoringDestroy(&coloring);CHKERRQ(ierr); 1437 } 1438 if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 1439 1440 if (snes->ops->setup) { 1441 ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 1442 } 1443 1444 snes->setupcalled = PETSC_TRUE; 1445 PetscFunctionReturn(0); 1446 } 1447 1448 #undef __FUNCT__ 1449 #define __FUNCT__ "SNESReset" 1450 /*@ 1451 SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 1452 1453 Collective on SNES 1454 1455 Input Parameter: 1456 . snes - iterative context obtained from SNESCreate() 1457 1458 Level: beginner 1459 1460 .keywords: SNES, destroy 1461 1462 .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 1463 @*/ 1464 PetscErrorCode SNESReset(SNES snes) 1465 { 1466 PetscErrorCode ierr; 1467 1468 PetscFunctionBegin; 1469 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1470 if (snes->ops->reset) { 1471 ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 1472 } 1473 if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 1474 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 1475 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 1476 ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 1477 ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 1478 ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 1479 ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 1480 if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 1481 if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);} 1482 snes->nwork = snes->nvwork = 0; 1483 snes->setupcalled = PETSC_FALSE; 1484 PetscFunctionReturn(0); 1485 } 1486 1487 #undef __FUNCT__ 1488 #define __FUNCT__ "SNESDestroy" 1489 /*@ 1490 SNESDestroy - Destroys the nonlinear solver context that was created 1491 with SNESCreate(). 1492 1493 Collective on SNES 1494 1495 Input Parameter: 1496 . snes - the SNES context 1497 1498 Level: beginner 1499 1500 .keywords: SNES, nonlinear, destroy 1501 1502 .seealso: SNESCreate(), SNESSolve() 1503 @*/ 1504 PetscErrorCode SNESDestroy(SNES *snes) 1505 { 1506 PetscErrorCode ierr; 1507 1508 PetscFunctionBegin; 1509 if (!*snes) PetscFunctionReturn(0); 1510 PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 1511 if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 1512 1513 ierr = SNESReset((*snes));CHKERRQ(ierr); 1514 1515 /* if memory was published with AMS then destroy it */ 1516 ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 1517 if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 1518 1519 ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 1520 ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 1521 1522 ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 1523 if ((*snes)->ops->convergeddestroy) { 1524 ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 1525 } 1526 if ((*snes)->conv_malloc) { 1527 ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 1528 ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 1529 } 1530 ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 1531 ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 1532 PetscFunctionReturn(0); 1533 } 1534 1535 /* ----------- Routines to set solver parameters ---------- */ 1536 1537 #undef __FUNCT__ 1538 #define __FUNCT__ "SNESSetLagPreconditioner" 1539 /*@ 1540 SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 1541 1542 Logically Collective on SNES 1543 1544 Input Parameters: 1545 + snes - the SNES context 1546 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1547 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1548 1549 Options Database Keys: 1550 . -snes_lag_preconditioner <lag> 1551 1552 Notes: 1553 The default is 1 1554 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1555 If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 1556 1557 Level: intermediate 1558 1559 .keywords: SNES, nonlinear, set, convergence, tolerances 1560 1561 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1562 1563 @*/ 1564 PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 1565 { 1566 PetscFunctionBegin; 1567 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1568 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1569 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1570 PetscValidLogicalCollectiveInt(snes,lag,2); 1571 snes->lagpreconditioner = lag; 1572 PetscFunctionReturn(0); 1573 } 1574 1575 #undef __FUNCT__ 1576 #define __FUNCT__ "SNESGetLagPreconditioner" 1577 /*@ 1578 SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 1579 1580 Not Collective 1581 1582 Input Parameter: 1583 . snes - the SNES context 1584 1585 Output Parameter: 1586 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1587 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1588 1589 Options Database Keys: 1590 . -snes_lag_preconditioner <lag> 1591 1592 Notes: 1593 The default is 1 1594 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1595 1596 Level: intermediate 1597 1598 .keywords: SNES, nonlinear, set, convergence, tolerances 1599 1600 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 1601 1602 @*/ 1603 PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 1604 { 1605 PetscFunctionBegin; 1606 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1607 *lag = snes->lagpreconditioner; 1608 PetscFunctionReturn(0); 1609 } 1610 1611 #undef __FUNCT__ 1612 #define __FUNCT__ "SNESSetLagJacobian" 1613 /*@ 1614 SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 1615 often the preconditioner is rebuilt. 1616 1617 Logically Collective on SNES 1618 1619 Input Parameters: 1620 + snes - the SNES context 1621 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1622 the Jacobian is built etc. -2 means rebuild at next chance but then never again 1623 1624 Options Database Keys: 1625 . -snes_lag_jacobian <lag> 1626 1627 Notes: 1628 The default is 1 1629 The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1630 If -1 is used before the very first nonlinear solve the CODE WILL FAIL! because no Jacobian is used, use -2 to indicate you want it recomputed 1631 at the next Newton step but never again (unless it is reset to another value) 1632 1633 Level: intermediate 1634 1635 .keywords: SNES, nonlinear, set, convergence, tolerances 1636 1637 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 1638 1639 @*/ 1640 PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 1641 { 1642 PetscFunctionBegin; 1643 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1644 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1645 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1646 PetscValidLogicalCollectiveInt(snes,lag,2); 1647 snes->lagjacobian = lag; 1648 PetscFunctionReturn(0); 1649 } 1650 1651 #undef __FUNCT__ 1652 #define __FUNCT__ "SNESGetLagJacobian" 1653 /*@ 1654 SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 1655 1656 Not Collective 1657 1658 Input Parameter: 1659 . snes - the SNES context 1660 1661 Output Parameter: 1662 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1663 the Jacobian is built etc. 1664 1665 Options Database Keys: 1666 . -snes_lag_jacobian <lag> 1667 1668 Notes: 1669 The default is 1 1670 The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1671 1672 Level: intermediate 1673 1674 .keywords: SNES, nonlinear, set, convergence, tolerances 1675 1676 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 1677 1678 @*/ 1679 PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 1680 { 1681 PetscFunctionBegin; 1682 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1683 *lag = snes->lagjacobian; 1684 PetscFunctionReturn(0); 1685 } 1686 1687 #undef __FUNCT__ 1688 #define __FUNCT__ "SNESSetTolerances" 1689 /*@ 1690 SNESSetTolerances - Sets various parameters used in convergence tests. 1691 1692 Logically Collective on SNES 1693 1694 Input Parameters: 1695 + snes - the SNES context 1696 . abstol - absolute convergence tolerance 1697 . rtol - relative convergence tolerance 1698 . stol - convergence tolerance in terms of the norm 1699 of the change in the solution between steps 1700 . maxit - maximum number of iterations 1701 - maxf - maximum number of function evaluations 1702 1703 Options Database Keys: 1704 + -snes_atol <abstol> - Sets abstol 1705 . -snes_rtol <rtol> - Sets rtol 1706 . -snes_stol <stol> - Sets stol 1707 . -snes_max_it <maxit> - Sets maxit 1708 - -snes_max_funcs <maxf> - Sets maxf 1709 1710 Notes: 1711 The default maximum number of iterations is 50. 1712 The default maximum number of function evaluations is 1000. 1713 1714 Level: intermediate 1715 1716 .keywords: SNES, nonlinear, set, convergence, tolerances 1717 1718 .seealso: SNESSetTrustRegionTolerance() 1719 @*/ 1720 PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 1721 { 1722 PetscFunctionBegin; 1723 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1724 PetscValidLogicalCollectiveReal(snes,abstol,2); 1725 PetscValidLogicalCollectiveReal(snes,rtol,3); 1726 PetscValidLogicalCollectiveReal(snes,stol,4); 1727 PetscValidLogicalCollectiveInt(snes,maxit,5); 1728 PetscValidLogicalCollectiveInt(snes,maxf,6); 1729 1730 if (abstol != PETSC_DEFAULT) snes->abstol = abstol; 1731 if (rtol != PETSC_DEFAULT) snes->rtol = rtol; 1732 if (stol != PETSC_DEFAULT) snes->xtol = stol; 1733 if (maxit != PETSC_DEFAULT) snes->max_its = maxit; 1734 if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf; 1735 PetscFunctionReturn(0); 1736 } 1737 1738 #undef __FUNCT__ 1739 #define __FUNCT__ "SNESGetTolerances" 1740 /*@ 1741 SNESGetTolerances - Gets various parameters used in convergence tests. 1742 1743 Not Collective 1744 1745 Input Parameters: 1746 + snes - the SNES context 1747 . atol - absolute convergence tolerance 1748 . rtol - relative convergence tolerance 1749 . stol - convergence tolerance in terms of the norm 1750 of the change in the solution between steps 1751 . maxit - maximum number of iterations 1752 - maxf - maximum number of function evaluations 1753 1754 Notes: 1755 The user can specify PETSC_NULL for any parameter that is not needed. 1756 1757 Level: intermediate 1758 1759 .keywords: SNES, nonlinear, get, convergence, tolerances 1760 1761 .seealso: SNESSetTolerances() 1762 @*/ 1763 PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 1764 { 1765 PetscFunctionBegin; 1766 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1767 if (atol) *atol = snes->abstol; 1768 if (rtol) *rtol = snes->rtol; 1769 if (stol) *stol = snes->xtol; 1770 if (maxit) *maxit = snes->max_its; 1771 if (maxf) *maxf = snes->max_funcs; 1772 PetscFunctionReturn(0); 1773 } 1774 1775 #undef __FUNCT__ 1776 #define __FUNCT__ "SNESSetTrustRegionTolerance" 1777 /*@ 1778 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 1779 1780 Logically Collective on SNES 1781 1782 Input Parameters: 1783 + snes - the SNES context 1784 - tol - tolerance 1785 1786 Options Database Key: 1787 . -snes_trtol <tol> - Sets tol 1788 1789 Level: intermediate 1790 1791 .keywords: SNES, nonlinear, set, trust region, tolerance 1792 1793 .seealso: SNESSetTolerances() 1794 @*/ 1795 PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 1796 { 1797 PetscFunctionBegin; 1798 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1799 PetscValidLogicalCollectiveReal(snes,tol,2); 1800 snes->deltatol = tol; 1801 PetscFunctionReturn(0); 1802 } 1803 1804 /* 1805 Duplicate the lg monitors for SNES from KSP; for some reason with 1806 dynamic libraries things don't work under Sun4 if we just use 1807 macros instead of functions 1808 */ 1809 #undef __FUNCT__ 1810 #define __FUNCT__ "SNESMonitorLG" 1811 PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 1812 { 1813 PetscErrorCode ierr; 1814 1815 PetscFunctionBegin; 1816 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1817 ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 1818 PetscFunctionReturn(0); 1819 } 1820 1821 #undef __FUNCT__ 1822 #define __FUNCT__ "SNESMonitorLGCreate" 1823 PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 1824 { 1825 PetscErrorCode ierr; 1826 1827 PetscFunctionBegin; 1828 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 1829 PetscFunctionReturn(0); 1830 } 1831 1832 #undef __FUNCT__ 1833 #define __FUNCT__ "SNESMonitorLGDestroy" 1834 PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 1835 { 1836 PetscErrorCode ierr; 1837 1838 PetscFunctionBegin; 1839 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 1840 PetscFunctionReturn(0); 1841 } 1842 1843 extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 1844 #undef __FUNCT__ 1845 #define __FUNCT__ "SNESMonitorLGRange" 1846 PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 1847 { 1848 PetscDrawLG lg; 1849 PetscErrorCode ierr; 1850 PetscReal x,y,per; 1851 PetscViewer v = (PetscViewer)monctx; 1852 static PetscReal prev; /* should be in the context */ 1853 PetscDraw draw; 1854 PetscFunctionBegin; 1855 if (!monctx) { 1856 MPI_Comm comm; 1857 1858 ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 1859 v = PETSC_VIEWER_DRAW_(comm); 1860 } 1861 ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 1862 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1863 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 1864 ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 1865 x = (PetscReal) n; 1866 if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 1867 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1868 if (n < 20 || !(n % 5)) { 1869 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1870 } 1871 1872 ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 1873 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1874 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 1875 ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 1876 ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 1877 x = (PetscReal) n; 1878 y = 100.0*per; 1879 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1880 if (n < 20 || !(n % 5)) { 1881 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1882 } 1883 1884 ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 1885 if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1886 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 1887 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 1888 x = (PetscReal) n; 1889 y = (prev - rnorm)/prev; 1890 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1891 if (n < 20 || !(n % 5)) { 1892 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1893 } 1894 1895 ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 1896 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1897 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 1898 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 1899 x = (PetscReal) n; 1900 y = (prev - rnorm)/(prev*per); 1901 if (n > 2) { /*skip initial crazy value */ 1902 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1903 } 1904 if (n < 20 || !(n % 5)) { 1905 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1906 } 1907 prev = rnorm; 1908 PetscFunctionReturn(0); 1909 } 1910 1911 #undef __FUNCT__ 1912 #define __FUNCT__ "SNESMonitorLGRangeCreate" 1913 PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 1914 { 1915 PetscErrorCode ierr; 1916 1917 PetscFunctionBegin; 1918 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 1919 PetscFunctionReturn(0); 1920 } 1921 1922 #undef __FUNCT__ 1923 #define __FUNCT__ "SNESMonitorLGRangeDestroy" 1924 PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 1925 { 1926 PetscErrorCode ierr; 1927 1928 PetscFunctionBegin; 1929 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 1930 PetscFunctionReturn(0); 1931 } 1932 1933 #undef __FUNCT__ 1934 #define __FUNCT__ "SNESMonitor" 1935 /* 1936 Runs the user provided monitor routines, if they exists. 1937 */ 1938 PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 1939 { 1940 PetscErrorCode ierr; 1941 PetscInt i,n = snes->numbermonitors; 1942 1943 PetscFunctionBegin; 1944 for (i=0; i<n; i++) { 1945 ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 1946 } 1947 PetscFunctionReturn(0); 1948 } 1949 1950 /* ------------ Routines to set performance monitoring options ----------- */ 1951 1952 #undef __FUNCT__ 1953 #define __FUNCT__ "SNESMonitorSet" 1954 /*@C 1955 SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 1956 iteration of the nonlinear solver to display the iteration's 1957 progress. 1958 1959 Logically Collective on SNES 1960 1961 Input Parameters: 1962 + snes - the SNES context 1963 . func - monitoring routine 1964 . mctx - [optional] user-defined context for private data for the 1965 monitor routine (use PETSC_NULL if no context is desired) 1966 - monitordestroy - [optional] routine that frees monitor context 1967 (may be PETSC_NULL) 1968 1969 Calling sequence of func: 1970 $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 1971 1972 + snes - the SNES context 1973 . its - iteration number 1974 . norm - 2-norm function value (may be estimated) 1975 - mctx - [optional] monitoring context 1976 1977 Options Database Keys: 1978 + -snes_monitor - sets SNESMonitorDefault() 1979 . -snes_monitor_draw - sets line graph monitor, 1980 uses SNESMonitorLGCreate() 1981 _ -snes_monitor_cancel - cancels all monitors that have 1982 been hardwired into a code by 1983 calls to SNESMonitorSet(), but 1984 does not cancel those set via 1985 the options database. 1986 1987 Notes: 1988 Several different monitoring routines may be set by calling 1989 SNESMonitorSet() multiple times; all will be called in the 1990 order in which they were set. 1991 1992 Fortran notes: Only a single monitor function can be set for each SNES object 1993 1994 Level: intermediate 1995 1996 .keywords: SNES, nonlinear, set, monitor 1997 1998 .seealso: SNESMonitorDefault(), SNESMonitorCancel() 1999 @*/ 2000 PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 2001 { 2002 PetscInt i; 2003 2004 PetscFunctionBegin; 2005 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2006 if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2007 for (i=0; i<snes->numbermonitors;i++) { 2008 if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) PetscFunctionReturn(0); 2009 2010 /* check if both default monitors that share common ASCII viewer */ 2011 if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) { 2012 if (mctx && snes->monitorcontext[i]) { 2013 PetscErrorCode ierr; 2014 PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx; 2015 PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i]; 2016 if (viewer1->viewer == viewer2->viewer) { 2017 ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2018 PetscFunctionReturn(0); 2019 } 2020 } 2021 } 2022 } 2023 snes->monitor[snes->numbermonitors] = monitor; 2024 snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2025 snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 2026 PetscFunctionReturn(0); 2027 } 2028 2029 #undef __FUNCT__ 2030 #define __FUNCT__ "SNESMonitorCancel" 2031 /*@C 2032 SNESMonitorCancel - Clears all the monitor functions for a SNES object. 2033 2034 Logically Collective on SNES 2035 2036 Input Parameters: 2037 . snes - the SNES context 2038 2039 Options Database Key: 2040 . -snes_monitor_cancel - cancels all monitors that have been hardwired 2041 into a code by calls to SNESMonitorSet(), but does not cancel those 2042 set via the options database 2043 2044 Notes: 2045 There is no way to clear one specific monitor from a SNES object. 2046 2047 Level: intermediate 2048 2049 .keywords: SNES, nonlinear, set, monitor 2050 2051 .seealso: SNESMonitorDefault(), SNESMonitorSet() 2052 @*/ 2053 PetscErrorCode SNESMonitorCancel(SNES snes) 2054 { 2055 PetscErrorCode ierr; 2056 PetscInt i; 2057 2058 PetscFunctionBegin; 2059 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2060 for (i=0; i<snes->numbermonitors; i++) { 2061 if (snes->monitordestroy[i]) { 2062 ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2063 } 2064 } 2065 snes->numbermonitors = 0; 2066 PetscFunctionReturn(0); 2067 } 2068 2069 #undef __FUNCT__ 2070 #define __FUNCT__ "SNESSetConvergenceTest" 2071 /*@C 2072 SNESSetConvergenceTest - Sets the function that is to be used 2073 to test for convergence of the nonlinear iterative solution. 2074 2075 Logically Collective on SNES 2076 2077 Input Parameters: 2078 + snes - the SNES context 2079 . func - routine to test for convergence 2080 . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 2081 - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 2082 2083 Calling sequence of func: 2084 $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2085 2086 + snes - the SNES context 2087 . it - current iteration (0 is the first and is before any Newton step) 2088 . cctx - [optional] convergence context 2089 . reason - reason for convergence/divergence 2090 . xnorm - 2-norm of current iterate 2091 . gnorm - 2-norm of current step 2092 - f - 2-norm of function 2093 2094 Level: advanced 2095 2096 .keywords: SNES, nonlinear, set, convergence, test 2097 2098 .seealso: SNESDefaultConverged(), SNESSkipConverged() 2099 @*/ 2100 PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 2101 { 2102 PetscErrorCode ierr; 2103 2104 PetscFunctionBegin; 2105 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2106 if (!func) func = SNESSkipConverged; 2107 if (snes->ops->convergeddestroy) { 2108 ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 2109 } 2110 snes->ops->converged = func; 2111 snes->ops->convergeddestroy = destroy; 2112 snes->cnvP = cctx; 2113 PetscFunctionReturn(0); 2114 } 2115 2116 #undef __FUNCT__ 2117 #define __FUNCT__ "SNESGetConvergedReason" 2118 /*@ 2119 SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2120 2121 Not Collective 2122 2123 Input Parameter: 2124 . snes - the SNES context 2125 2126 Output Parameter: 2127 . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2128 manual pages for the individual convergence tests for complete lists 2129 2130 Level: intermediate 2131 2132 Notes: Can only be called after the call the SNESSolve() is complete. 2133 2134 .keywords: SNES, nonlinear, set, convergence, test 2135 2136 .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2137 @*/ 2138 PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2139 { 2140 PetscFunctionBegin; 2141 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2142 PetscValidPointer(reason,2); 2143 *reason = snes->reason; 2144 PetscFunctionReturn(0); 2145 } 2146 2147 #undef __FUNCT__ 2148 #define __FUNCT__ "SNESSetConvergenceHistory" 2149 /*@ 2150 SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2151 2152 Logically Collective on SNES 2153 2154 Input Parameters: 2155 + snes - iterative context obtained from SNESCreate() 2156 . a - array to hold history, this array will contain the function norms computed at each step 2157 . its - integer array holds the number of linear iterations for each solve. 2158 . na - size of a and its 2159 - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2160 else it continues storing new values for new nonlinear solves after the old ones 2161 2162 Notes: 2163 If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2164 default array of length 10000 is allocated. 2165 2166 This routine is useful, e.g., when running a code for purposes 2167 of accurate performance monitoring, when no I/O should be done 2168 during the section of code that is being timed. 2169 2170 Level: intermediate 2171 2172 .keywords: SNES, set, convergence, history 2173 2174 .seealso: SNESGetConvergenceHistory() 2175 2176 @*/ 2177 PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2178 { 2179 PetscErrorCode ierr; 2180 2181 PetscFunctionBegin; 2182 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2183 if (na) PetscValidScalarPointer(a,2); 2184 if (its) PetscValidIntPointer(its,3); 2185 if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2186 if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2187 ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2188 ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2189 snes->conv_malloc = PETSC_TRUE; 2190 } 2191 snes->conv_hist = a; 2192 snes->conv_hist_its = its; 2193 snes->conv_hist_max = na; 2194 snes->conv_hist_len = 0; 2195 snes->conv_hist_reset = reset; 2196 PetscFunctionReturn(0); 2197 } 2198 2199 #if defined(PETSC_HAVE_MATLAB_ENGINE) 2200 #include <engine.h> /* MATLAB include file */ 2201 #include <mex.h> /* MATLAB include file */ 2202 EXTERN_C_BEGIN 2203 #undef __FUNCT__ 2204 #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2205 mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2206 { 2207 mxArray *mat; 2208 PetscInt i; 2209 PetscReal *ar; 2210 2211 PetscFunctionBegin; 2212 mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2213 ar = (PetscReal*) mxGetData(mat); 2214 for (i=0; i<snes->conv_hist_len; i++) { 2215 ar[i] = snes->conv_hist[i]; 2216 } 2217 PetscFunctionReturn(mat); 2218 } 2219 EXTERN_C_END 2220 #endif 2221 2222 2223 #undef __FUNCT__ 2224 #define __FUNCT__ "SNESGetConvergenceHistory" 2225 /*@C 2226 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 2227 2228 Not Collective 2229 2230 Input Parameter: 2231 . snes - iterative context obtained from SNESCreate() 2232 2233 Output Parameters: 2234 . a - array to hold history 2235 . its - integer array holds the number of linear iterations (or 2236 negative if not converged) for each solve. 2237 - na - size of a and its 2238 2239 Notes: 2240 The calling sequence for this routine in Fortran is 2241 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 2242 2243 This routine is useful, e.g., when running a code for purposes 2244 of accurate performance monitoring, when no I/O should be done 2245 during the section of code that is being timed. 2246 2247 Level: intermediate 2248 2249 .keywords: SNES, get, convergence, history 2250 2251 .seealso: SNESSetConvergencHistory() 2252 2253 @*/ 2254 PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 2255 { 2256 PetscFunctionBegin; 2257 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2258 if (a) *a = snes->conv_hist; 2259 if (its) *its = snes->conv_hist_its; 2260 if (na) *na = snes->conv_hist_len; 2261 PetscFunctionReturn(0); 2262 } 2263 2264 #undef __FUNCT__ 2265 #define __FUNCT__ "SNESSetUpdate" 2266 /*@C 2267 SNESSetUpdate - Sets the general-purpose update function called 2268 at the beginning of every iteration of the nonlinear solve. Specifically 2269 it is called just before the Jacobian is "evaluated". 2270 2271 Logically Collective on SNES 2272 2273 Input Parameters: 2274 . snes - The nonlinear solver context 2275 . func - The function 2276 2277 Calling sequence of func: 2278 . func (SNES snes, PetscInt step); 2279 2280 . step - The current step of the iteration 2281 2282 Level: advanced 2283 2284 Note: This is NOT what one uses to update the ghost points before a function evaluation, that should be done at the beginning of your FormFunction() 2285 This is not used by most users. 2286 2287 .keywords: SNES, update 2288 2289 .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 2290 @*/ 2291 PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 2292 { 2293 PetscFunctionBegin; 2294 PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 2295 snes->ops->update = func; 2296 PetscFunctionReturn(0); 2297 } 2298 2299 #undef __FUNCT__ 2300 #define __FUNCT__ "SNESDefaultUpdate" 2301 /*@ 2302 SNESDefaultUpdate - The default update function which does nothing. 2303 2304 Not collective 2305 2306 Input Parameters: 2307 . snes - The nonlinear solver context 2308 . step - The current step of the iteration 2309 2310 Level: intermediate 2311 2312 .keywords: SNES, update 2313 .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 2314 @*/ 2315 PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 2316 { 2317 PetscFunctionBegin; 2318 PetscFunctionReturn(0); 2319 } 2320 2321 #undef __FUNCT__ 2322 #define __FUNCT__ "SNESScaleStep_Private" 2323 /* 2324 SNESScaleStep_Private - Scales a step so that its length is less than the 2325 positive parameter delta. 2326 2327 Input Parameters: 2328 + snes - the SNES context 2329 . y - approximate solution of linear system 2330 . fnorm - 2-norm of current function 2331 - delta - trust region size 2332 2333 Output Parameters: 2334 + gpnorm - predicted function norm at the new point, assuming local 2335 linearization. The value is zero if the step lies within the trust 2336 region, and exceeds zero otherwise. 2337 - ynorm - 2-norm of the step 2338 2339 Note: 2340 For non-trust region methods such as SNESLS, the parameter delta 2341 is set to be the maximum allowable step size. 2342 2343 .keywords: SNES, nonlinear, scale, step 2344 */ 2345 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 2346 { 2347 PetscReal nrm; 2348 PetscScalar cnorm; 2349 PetscErrorCode ierr; 2350 2351 PetscFunctionBegin; 2352 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2353 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 2354 PetscCheckSameComm(snes,1,y,2); 2355 2356 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 2357 if (nrm > *delta) { 2358 nrm = *delta/nrm; 2359 *gpnorm = (1.0 - nrm)*(*fnorm); 2360 cnorm = nrm; 2361 ierr = VecScale(y,cnorm);CHKERRQ(ierr); 2362 *ynorm = *delta; 2363 } else { 2364 *gpnorm = 0.0; 2365 *ynorm = nrm; 2366 } 2367 PetscFunctionReturn(0); 2368 } 2369 2370 #undef __FUNCT__ 2371 #define __FUNCT__ "SNESSolve" 2372 /*@C 2373 SNESSolve - Solves a nonlinear system F(x) = b. 2374 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 2375 2376 Collective on SNES 2377 2378 Input Parameters: 2379 + snes - the SNES context 2380 . b - the constant part of the equation, or PETSC_NULL to use zero. 2381 - x - the solution vector. 2382 2383 Notes: 2384 The user should initialize the vector,x, with the initial guess 2385 for the nonlinear solve prior to calling SNESSolve. In particular, 2386 to employ an initial guess of zero, the user should explicitly set 2387 this vector to zero by calling VecSet(). 2388 2389 Level: beginner 2390 2391 .keywords: SNES, nonlinear, solve 2392 2393 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian() 2394 @*/ 2395 PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 2396 { 2397 PetscErrorCode ierr; 2398 PetscBool flg; 2399 char filename[PETSC_MAX_PATH_LEN]; 2400 PetscViewer viewer; 2401 2402 PetscFunctionBegin; 2403 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2404 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2405 PetscCheckSameComm(snes,1,x,3); 2406 if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 2407 if (b) PetscCheckSameComm(snes,1,b,2); 2408 2409 /* set solution vector */ 2410 ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 2411 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 2412 snes->vec_sol = x; 2413 /* set afine vector if provided */ 2414 if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 2415 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 2416 snes->vec_rhs = b; 2417 2418 ierr = SNESSetUp(snes);CHKERRQ(ierr); 2419 2420 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 2421 snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 2422 2423 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 2424 ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 2425 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 2426 if (snes->domainerror){ 2427 snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 2428 snes->domainerror = PETSC_FALSE; 2429 } 2430 if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 2431 2432 ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 2433 if (flg && !PetscPreLoadingOn) { 2434 ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 2435 ierr = SNESView(snes,viewer);CHKERRQ(ierr); 2436 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2437 } 2438 2439 flg = PETSC_FALSE; 2440 ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 2441 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 2442 if (snes->printreason) { 2443 if (snes->reason > 0) { 2444 ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 2445 } else { 2446 ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 2447 } 2448 } 2449 2450 if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 2451 PetscFunctionReturn(0); 2452 } 2453 2454 /* --------- Internal routines for SNES Package --------- */ 2455 2456 #undef __FUNCT__ 2457 #define __FUNCT__ "SNESSetType" 2458 /*@C 2459 SNESSetType - Sets the method for the nonlinear solver. 2460 2461 Collective on SNES 2462 2463 Input Parameters: 2464 + snes - the SNES context 2465 - type - a known method 2466 2467 Options Database Key: 2468 . -snes_type <type> - Sets the method; use -help for a list 2469 of available methods (for instance, ls or tr) 2470 2471 Notes: 2472 See "petsc/include/petscsnes.h" for available methods (for instance) 2473 + SNESLS - Newton's method with line search 2474 (systems of nonlinear equations) 2475 . SNESTR - Newton's method with trust region 2476 (systems of nonlinear equations) 2477 2478 Normally, it is best to use the SNESSetFromOptions() command and then 2479 set the SNES solver type from the options database rather than by using 2480 this routine. Using the options database provides the user with 2481 maximum flexibility in evaluating the many nonlinear solvers. 2482 The SNESSetType() routine is provided for those situations where it 2483 is necessary to set the nonlinear solver independently of the command 2484 line or options database. This might be the case, for example, when 2485 the choice of solver changes during the execution of the program, 2486 and the user's application is taking responsibility for choosing the 2487 appropriate method. 2488 2489 Level: intermediate 2490 2491 .keywords: SNES, set, type 2492 2493 .seealso: SNESType, SNESCreate() 2494 2495 @*/ 2496 PetscErrorCode SNESSetType(SNES snes,const SNESType type) 2497 { 2498 PetscErrorCode ierr,(*r)(SNES); 2499 PetscBool match; 2500 2501 PetscFunctionBegin; 2502 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2503 PetscValidCharPointer(type,2); 2504 2505 ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 2506 if (match) PetscFunctionReturn(0); 2507 2508 ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 2509 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 2510 /* Destroy the previous private SNES context */ 2511 if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 2512 /* Reinitialize function pointers in SNESOps structure */ 2513 snes->ops->setup = 0; 2514 snes->ops->solve = 0; 2515 snes->ops->view = 0; 2516 snes->ops->setfromoptions = 0; 2517 snes->ops->destroy = 0; 2518 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 2519 snes->setupcalled = PETSC_FALSE; 2520 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 2521 ierr = (*r)(snes);CHKERRQ(ierr); 2522 #if defined(PETSC_HAVE_AMS) 2523 if (PetscAMSPublishAll) { 2524 ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 2525 } 2526 #endif 2527 PetscFunctionReturn(0); 2528 } 2529 2530 2531 /* --------------------------------------------------------------------- */ 2532 #undef __FUNCT__ 2533 #define __FUNCT__ "SNESRegisterDestroy" 2534 /*@ 2535 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 2536 registered by SNESRegisterDynamic(). 2537 2538 Not Collective 2539 2540 Level: advanced 2541 2542 .keywords: SNES, nonlinear, register, destroy 2543 2544 .seealso: SNESRegisterAll(), SNESRegisterAll() 2545 @*/ 2546 PetscErrorCode SNESRegisterDestroy(void) 2547 { 2548 PetscErrorCode ierr; 2549 2550 PetscFunctionBegin; 2551 ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 2552 SNESRegisterAllCalled = PETSC_FALSE; 2553 PetscFunctionReturn(0); 2554 } 2555 2556 #undef __FUNCT__ 2557 #define __FUNCT__ "SNESGetType" 2558 /*@C 2559 SNESGetType - Gets the SNES method type and name (as a string). 2560 2561 Not Collective 2562 2563 Input Parameter: 2564 . snes - nonlinear solver context 2565 2566 Output Parameter: 2567 . type - SNES method (a character string) 2568 2569 Level: intermediate 2570 2571 .keywords: SNES, nonlinear, get, type, name 2572 @*/ 2573 PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 2574 { 2575 PetscFunctionBegin; 2576 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2577 PetscValidPointer(type,2); 2578 *type = ((PetscObject)snes)->type_name; 2579 PetscFunctionReturn(0); 2580 } 2581 2582 #undef __FUNCT__ 2583 #define __FUNCT__ "SNESGetSolution" 2584 /*@ 2585 SNESGetSolution - Returns the vector where the approximate solution is 2586 stored. 2587 2588 Not Collective, but Vec is parallel if SNES is parallel 2589 2590 Input Parameter: 2591 . snes - the SNES context 2592 2593 Output Parameter: 2594 . x - the solution 2595 2596 Level: intermediate 2597 2598 .keywords: SNES, nonlinear, get, solution 2599 2600 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 2601 @*/ 2602 PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 2603 { 2604 PetscFunctionBegin; 2605 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2606 PetscValidPointer(x,2); 2607 *x = snes->vec_sol; 2608 PetscFunctionReturn(0); 2609 } 2610 2611 #undef __FUNCT__ 2612 #define __FUNCT__ "SNESGetSolutionUpdate" 2613 /*@ 2614 SNESGetSolutionUpdate - Returns the vector where the solution update is 2615 stored. 2616 2617 Not Collective, but Vec is parallel if SNES is parallel 2618 2619 Input Parameter: 2620 . snes - the SNES context 2621 2622 Output Parameter: 2623 . x - the solution update 2624 2625 Level: advanced 2626 2627 .keywords: SNES, nonlinear, get, solution, update 2628 2629 .seealso: SNESGetSolution(), SNESGetFunction() 2630 @*/ 2631 PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 2632 { 2633 PetscFunctionBegin; 2634 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2635 PetscValidPointer(x,2); 2636 *x = snes->vec_sol_update; 2637 PetscFunctionReturn(0); 2638 } 2639 2640 #undef __FUNCT__ 2641 #define __FUNCT__ "SNESGetFunction" 2642 /*@C 2643 SNESGetFunction - Returns the vector where the function is stored. 2644 2645 Not Collective, but Vec is parallel if SNES is parallel 2646 2647 Input Parameter: 2648 . snes - the SNES context 2649 2650 Output Parameter: 2651 + r - the function (or PETSC_NULL) 2652 . func - the function (or PETSC_NULL) 2653 - ctx - the function context (or PETSC_NULL) 2654 2655 Level: advanced 2656 2657 .keywords: SNES, nonlinear, get, function 2658 2659 .seealso: SNESSetFunction(), SNESGetSolution() 2660 @*/ 2661 PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 2662 { 2663 PetscFunctionBegin; 2664 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2665 if (r) *r = snes->vec_func; 2666 if (func) *func = snes->ops->computefunction; 2667 if (ctx) *ctx = snes->funP; 2668 PetscFunctionReturn(0); 2669 } 2670 2671 #undef __FUNCT__ 2672 #define __FUNCT__ "SNESSetOptionsPrefix" 2673 /*@C 2674 SNESSetOptionsPrefix - Sets the prefix used for searching for all 2675 SNES options in the database. 2676 2677 Logically Collective on SNES 2678 2679 Input Parameter: 2680 + snes - the SNES context 2681 - prefix - the prefix to prepend to all option names 2682 2683 Notes: 2684 A hyphen (-) must NOT be given at the beginning of the prefix name. 2685 The first character of all runtime options is AUTOMATICALLY the hyphen. 2686 2687 Level: advanced 2688 2689 .keywords: SNES, set, options, prefix, database 2690 2691 .seealso: SNESSetFromOptions() 2692 @*/ 2693 PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 2694 { 2695 PetscErrorCode ierr; 2696 2697 PetscFunctionBegin; 2698 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2699 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2700 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 2701 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2702 PetscFunctionReturn(0); 2703 } 2704 2705 #undef __FUNCT__ 2706 #define __FUNCT__ "SNESAppendOptionsPrefix" 2707 /*@C 2708 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 2709 SNES options in the database. 2710 2711 Logically Collective on SNES 2712 2713 Input Parameters: 2714 + snes - the SNES context 2715 - prefix - the prefix to prepend to all option names 2716 2717 Notes: 2718 A hyphen (-) must NOT be given at the beginning of the prefix name. 2719 The first character of all runtime options is AUTOMATICALLY the hyphen. 2720 2721 Level: advanced 2722 2723 .keywords: SNES, append, options, prefix, database 2724 2725 .seealso: SNESGetOptionsPrefix() 2726 @*/ 2727 PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 2728 { 2729 PetscErrorCode ierr; 2730 2731 PetscFunctionBegin; 2732 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2733 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2734 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 2735 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2736 PetscFunctionReturn(0); 2737 } 2738 2739 #undef __FUNCT__ 2740 #define __FUNCT__ "SNESGetOptionsPrefix" 2741 /*@C 2742 SNESGetOptionsPrefix - Sets the prefix used for searching for all 2743 SNES options in the database. 2744 2745 Not Collective 2746 2747 Input Parameter: 2748 . snes - the SNES context 2749 2750 Output Parameter: 2751 . prefix - pointer to the prefix string used 2752 2753 Notes: On the fortran side, the user should pass in a string 'prefix' of 2754 sufficient length to hold the prefix. 2755 2756 Level: advanced 2757 2758 .keywords: SNES, get, options, prefix, database 2759 2760 .seealso: SNESAppendOptionsPrefix() 2761 @*/ 2762 PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 2763 { 2764 PetscErrorCode ierr; 2765 2766 PetscFunctionBegin; 2767 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2768 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2769 PetscFunctionReturn(0); 2770 } 2771 2772 2773 #undef __FUNCT__ 2774 #define __FUNCT__ "SNESRegister" 2775 /*@C 2776 SNESRegister - See SNESRegisterDynamic() 2777 2778 Level: advanced 2779 @*/ 2780 PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 2781 { 2782 char fullname[PETSC_MAX_PATH_LEN]; 2783 PetscErrorCode ierr; 2784 2785 PetscFunctionBegin; 2786 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 2787 ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 2788 PetscFunctionReturn(0); 2789 } 2790 2791 #undef __FUNCT__ 2792 #define __FUNCT__ "SNESTestLocalMin" 2793 PetscErrorCode SNESTestLocalMin(SNES snes) 2794 { 2795 PetscErrorCode ierr; 2796 PetscInt N,i,j; 2797 Vec u,uh,fh; 2798 PetscScalar value; 2799 PetscReal norm; 2800 2801 PetscFunctionBegin; 2802 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 2803 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 2804 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 2805 2806 /* currently only works for sequential */ 2807 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 2808 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 2809 for (i=0; i<N; i++) { 2810 ierr = VecCopy(u,uh);CHKERRQ(ierr); 2811 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 2812 for (j=-10; j<11; j++) { 2813 value = PetscSign(j)*exp(PetscAbs(j)-10.0); 2814 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2815 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 2816 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 2817 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 2818 value = -value; 2819 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2820 } 2821 } 2822 ierr = VecDestroy(&uh);CHKERRQ(ierr); 2823 ierr = VecDestroy(&fh);CHKERRQ(ierr); 2824 PetscFunctionReturn(0); 2825 } 2826 2827 #undef __FUNCT__ 2828 #define __FUNCT__ "SNESKSPSetUseEW" 2829 /*@ 2830 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 2831 computing relative tolerance for linear solvers within an inexact 2832 Newton method. 2833 2834 Logically Collective on SNES 2835 2836 Input Parameters: 2837 + snes - SNES context 2838 - flag - PETSC_TRUE or PETSC_FALSE 2839 2840 Options Database: 2841 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 2842 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 2843 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 2844 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 2845 . -snes_ksp_ew_gamma <gamma> - Sets gamma 2846 . -snes_ksp_ew_alpha <alpha> - Sets alpha 2847 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 2848 - -snes_ksp_ew_threshold <threshold> - Sets threshold 2849 2850 Notes: 2851 Currently, the default is to use a constant relative tolerance for 2852 the inner linear solvers. Alternatively, one can use the 2853 Eisenstat-Walker method, where the relative convergence tolerance 2854 is reset at each Newton iteration according progress of the nonlinear 2855 solver. 2856 2857 Level: advanced 2858 2859 Reference: 2860 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2861 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2862 2863 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2864 2865 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 2866 @*/ 2867 PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 2868 { 2869 PetscFunctionBegin; 2870 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2871 PetscValidLogicalCollectiveBool(snes,flag,2); 2872 snes->ksp_ewconv = flag; 2873 PetscFunctionReturn(0); 2874 } 2875 2876 #undef __FUNCT__ 2877 #define __FUNCT__ "SNESKSPGetUseEW" 2878 /*@ 2879 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 2880 for computing relative tolerance for linear solvers within an 2881 inexact Newton method. 2882 2883 Not Collective 2884 2885 Input Parameter: 2886 . snes - SNES context 2887 2888 Output Parameter: 2889 . flag - PETSC_TRUE or PETSC_FALSE 2890 2891 Notes: 2892 Currently, the default is to use a constant relative tolerance for 2893 the inner linear solvers. Alternatively, one can use the 2894 Eisenstat-Walker method, where the relative convergence tolerance 2895 is reset at each Newton iteration according progress of the nonlinear 2896 solver. 2897 2898 Level: advanced 2899 2900 Reference: 2901 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2902 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2903 2904 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2905 2906 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 2907 @*/ 2908 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 2909 { 2910 PetscFunctionBegin; 2911 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2912 PetscValidPointer(flag,2); 2913 *flag = snes->ksp_ewconv; 2914 PetscFunctionReturn(0); 2915 } 2916 2917 #undef __FUNCT__ 2918 #define __FUNCT__ "SNESKSPSetParametersEW" 2919 /*@ 2920 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 2921 convergence criteria for the linear solvers within an inexact 2922 Newton method. 2923 2924 Logically Collective on SNES 2925 2926 Input Parameters: 2927 + snes - SNES context 2928 . version - version 1, 2 (default is 2) or 3 2929 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2930 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2931 . gamma - multiplicative factor for version 2 rtol computation 2932 (0 <= gamma2 <= 1) 2933 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2934 . alpha2 - power for safeguard 2935 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2936 2937 Note: 2938 Version 3 was contributed by Luis Chacon, June 2006. 2939 2940 Use PETSC_DEFAULT to retain the default for any of the parameters. 2941 2942 Level: advanced 2943 2944 Reference: 2945 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2946 inexact Newton method", Utah State University Math. Stat. Dept. Res. 2947 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 2948 2949 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 2950 2951 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 2952 @*/ 2953 PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 2954 PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 2955 { 2956 SNESKSPEW *kctx; 2957 PetscFunctionBegin; 2958 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2959 kctx = (SNESKSPEW*)snes->kspconvctx; 2960 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2961 PetscValidLogicalCollectiveInt(snes,version,2); 2962 PetscValidLogicalCollectiveReal(snes,rtol_0,3); 2963 PetscValidLogicalCollectiveReal(snes,rtol_max,4); 2964 PetscValidLogicalCollectiveReal(snes,gamma,5); 2965 PetscValidLogicalCollectiveReal(snes,alpha,6); 2966 PetscValidLogicalCollectiveReal(snes,alpha2,7); 2967 PetscValidLogicalCollectiveReal(snes,threshold,8); 2968 2969 if (version != PETSC_DEFAULT) kctx->version = version; 2970 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 2971 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 2972 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 2973 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 2974 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 2975 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 2976 2977 if (kctx->version < 1 || kctx->version > 3) { 2978 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 2979 } 2980 if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 2981 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 2982 } 2983 if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 2984 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 2985 } 2986 if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 2987 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 2988 } 2989 if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 2990 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 2991 } 2992 if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 2993 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 2994 } 2995 PetscFunctionReturn(0); 2996 } 2997 2998 #undef __FUNCT__ 2999 #define __FUNCT__ "SNESKSPGetParametersEW" 3000 /*@ 3001 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 3002 convergence criteria for the linear solvers within an inexact 3003 Newton method. 3004 3005 Not Collective 3006 3007 Input Parameters: 3008 snes - SNES context 3009 3010 Output Parameters: 3011 + version - version 1, 2 (default is 2) or 3 3012 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 3013 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 3014 . gamma - multiplicative factor for version 2 rtol computation 3015 (0 <= gamma2 <= 1) 3016 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 3017 . alpha2 - power for safeguard 3018 - threshold - threshold for imposing safeguard (0 < threshold < 1) 3019 3020 Level: advanced 3021 3022 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 3023 3024 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 3025 @*/ 3026 PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 3027 PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 3028 { 3029 SNESKSPEW *kctx; 3030 PetscFunctionBegin; 3031 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3032 kctx = (SNESKSPEW*)snes->kspconvctx; 3033 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3034 if(version) *version = kctx->version; 3035 if(rtol_0) *rtol_0 = kctx->rtol_0; 3036 if(rtol_max) *rtol_max = kctx->rtol_max; 3037 if(gamma) *gamma = kctx->gamma; 3038 if(alpha) *alpha = kctx->alpha; 3039 if(alpha2) *alpha2 = kctx->alpha2; 3040 if(threshold) *threshold = kctx->threshold; 3041 PetscFunctionReturn(0); 3042 } 3043 3044 #undef __FUNCT__ 3045 #define __FUNCT__ "SNESKSPEW_PreSolve" 3046 static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 3047 { 3048 PetscErrorCode ierr; 3049 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 3050 PetscReal rtol=PETSC_DEFAULT,stol; 3051 3052 PetscFunctionBegin; 3053 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3054 if (!snes->iter) { /* first time in, so use the original user rtol */ 3055 rtol = kctx->rtol_0; 3056 } else { 3057 if (kctx->version == 1) { 3058 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 3059 if (rtol < 0.0) rtol = -rtol; 3060 stol = pow(kctx->rtol_last,kctx->alpha2); 3061 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3062 } else if (kctx->version == 2) { 3063 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3064 stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 3065 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3066 } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 3067 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3068 /* safeguard: avoid sharp decrease of rtol */ 3069 stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 3070 stol = PetscMax(rtol,stol); 3071 rtol = PetscMin(kctx->rtol_0,stol); 3072 /* safeguard: avoid oversolving */ 3073 stol = kctx->gamma*(snes->ttol)/snes->norm; 3074 stol = PetscMax(rtol,stol); 3075 rtol = PetscMin(kctx->rtol_0,stol); 3076 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 3077 } 3078 /* safeguard: avoid rtol greater than one */ 3079 rtol = PetscMin(rtol,kctx->rtol_max); 3080 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 3081 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 3082 PetscFunctionReturn(0); 3083 } 3084 3085 #undef __FUNCT__ 3086 #define __FUNCT__ "SNESKSPEW_PostSolve" 3087 static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 3088 { 3089 PetscErrorCode ierr; 3090 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 3091 PCSide pcside; 3092 Vec lres; 3093 3094 PetscFunctionBegin; 3095 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3096 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 3097 ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 3098 if (kctx->version == 1) { 3099 ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 3100 if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 3101 /* KSP residual is true linear residual */ 3102 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 3103 } else { 3104 /* KSP residual is preconditioned residual */ 3105 /* compute true linear residual norm */ 3106 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 3107 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 3108 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 3109 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 3110 ierr = VecDestroy(&lres);CHKERRQ(ierr); 3111 } 3112 } 3113 PetscFunctionReturn(0); 3114 } 3115 3116 #undef __FUNCT__ 3117 #define __FUNCT__ "SNES_KSPSolve" 3118 PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 3119 { 3120 PetscErrorCode ierr; 3121 3122 PetscFunctionBegin; 3123 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3124 ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3125 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3126 PetscFunctionReturn(0); 3127 } 3128 3129 #undef __FUNCT__ 3130 #define __FUNCT__ "SNESSetDM" 3131 /*@ 3132 SNESSetDM - Sets the DM that may be used by some preconditioners 3133 3134 Logically Collective on SNES 3135 3136 Input Parameters: 3137 + snes - the preconditioner context 3138 - dm - the dm 3139 3140 Level: intermediate 3141 3142 3143 .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 3144 @*/ 3145 PetscErrorCode SNESSetDM(SNES snes,DM dm) 3146 { 3147 PetscErrorCode ierr; 3148 KSP ksp; 3149 3150 PetscFunctionBegin; 3151 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3152 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 3153 ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 3154 snes->dm = dm; 3155 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3156 ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3157 ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 3158 PetscFunctionReturn(0); 3159 } 3160 3161 #undef __FUNCT__ 3162 #define __FUNCT__ "SNESGetDM" 3163 /*@ 3164 SNESGetDM - Gets the DM that may be used by some preconditioners 3165 3166 Not Collective but DM obtained is parallel on SNES 3167 3168 Input Parameter: 3169 . snes - the preconditioner context 3170 3171 Output Parameter: 3172 . dm - the dm 3173 3174 Level: intermediate 3175 3176 3177 .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 3178 @*/ 3179 PetscErrorCode SNESGetDM(SNES snes,DM *dm) 3180 { 3181 PetscFunctionBegin; 3182 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3183 *dm = snes->dm; 3184 PetscFunctionReturn(0); 3185 } 3186 3187 #if defined(PETSC_HAVE_MATLAB_ENGINE) 3188 #include <mex.h> 3189 3190 typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 3191 3192 #undef __FUNCT__ 3193 #define __FUNCT__ "SNESComputeFunction_Matlab" 3194 /* 3195 SNESComputeFunction_Matlab - Calls the function that has been set with 3196 SNESSetFunctionMatlab(). 3197 3198 Collective on SNES 3199 3200 Input Parameters: 3201 + snes - the SNES context 3202 - x - input vector 3203 3204 Output Parameter: 3205 . y - function vector, as set by SNESSetFunction() 3206 3207 Notes: 3208 SNESComputeFunction() is typically used within nonlinear solvers 3209 implementations, so most users would not generally call this routine 3210 themselves. 3211 3212 Level: developer 3213 3214 .keywords: SNES, nonlinear, compute, function 3215 3216 .seealso: SNESSetFunction(), SNESGetFunction() 3217 */ 3218 PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 3219 { 3220 PetscErrorCode ierr; 3221 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3222 int nlhs = 1,nrhs = 5; 3223 mxArray *plhs[1],*prhs[5]; 3224 long long int lx = 0,ly = 0,ls = 0; 3225 3226 PetscFunctionBegin; 3227 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3228 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3229 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3230 PetscCheckSameComm(snes,1,x,2); 3231 PetscCheckSameComm(snes,1,y,3); 3232 3233 /* call Matlab function in ctx with arguments x and y */ 3234 3235 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3236 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3237 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 3238 prhs[0] = mxCreateDoubleScalar((double)ls); 3239 prhs[1] = mxCreateDoubleScalar((double)lx); 3240 prhs[2] = mxCreateDoubleScalar((double)ly); 3241 prhs[3] = mxCreateString(sctx->funcname); 3242 prhs[4] = sctx->ctx; 3243 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 3244 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3245 mxDestroyArray(prhs[0]); 3246 mxDestroyArray(prhs[1]); 3247 mxDestroyArray(prhs[2]); 3248 mxDestroyArray(prhs[3]); 3249 mxDestroyArray(plhs[0]); 3250 PetscFunctionReturn(0); 3251 } 3252 3253 3254 #undef __FUNCT__ 3255 #define __FUNCT__ "SNESSetFunctionMatlab" 3256 /* 3257 SNESSetFunctionMatlab - Sets the function evaluation routine and function 3258 vector for use by the SNES routines in solving systems of nonlinear 3259 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3260 3261 Logically Collective on SNES 3262 3263 Input Parameters: 3264 + snes - the SNES context 3265 . r - vector to store function value 3266 - func - function evaluation routine 3267 3268 Calling sequence of func: 3269 $ func (SNES snes,Vec x,Vec f,void *ctx); 3270 3271 3272 Notes: 3273 The Newton-like methods typically solve linear systems of the form 3274 $ f'(x) x = -f(x), 3275 where f'(x) denotes the Jacobian matrix and f(x) is the function. 3276 3277 Level: beginner 3278 3279 .keywords: SNES, nonlinear, set, function 3280 3281 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3282 */ 3283 PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 3284 { 3285 PetscErrorCode ierr; 3286 SNESMatlabContext *sctx; 3287 3288 PetscFunctionBegin; 3289 /* currently sctx is memory bleed */ 3290 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3291 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3292 /* 3293 This should work, but it doesn't 3294 sctx->ctx = ctx; 3295 mexMakeArrayPersistent(sctx->ctx); 3296 */ 3297 sctx->ctx = mxDuplicateArray(ctx); 3298 ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 3299 PetscFunctionReturn(0); 3300 } 3301 3302 #undef __FUNCT__ 3303 #define __FUNCT__ "SNESComputeJacobian_Matlab" 3304 /* 3305 SNESComputeJacobian_Matlab - Calls the function that has been set with 3306 SNESSetJacobianMatlab(). 3307 3308 Collective on SNES 3309 3310 Input Parameters: 3311 + snes - the SNES context 3312 . x - input vector 3313 . A, B - the matrices 3314 - ctx - user context 3315 3316 Output Parameter: 3317 . flag - structure of the matrix 3318 3319 Level: developer 3320 3321 .keywords: SNES, nonlinear, compute, function 3322 3323 .seealso: SNESSetFunction(), SNESGetFunction() 3324 @*/ 3325 PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 3326 { 3327 PetscErrorCode ierr; 3328 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3329 int nlhs = 2,nrhs = 6; 3330 mxArray *plhs[2],*prhs[6]; 3331 long long int lx = 0,lA = 0,ls = 0, lB = 0; 3332 3333 PetscFunctionBegin; 3334 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3335 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3336 3337 /* call Matlab function in ctx with arguments x and y */ 3338 3339 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3340 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3341 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 3342 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 3343 prhs[0] = mxCreateDoubleScalar((double)ls); 3344 prhs[1] = mxCreateDoubleScalar((double)lx); 3345 prhs[2] = mxCreateDoubleScalar((double)lA); 3346 prhs[3] = mxCreateDoubleScalar((double)lB); 3347 prhs[4] = mxCreateString(sctx->funcname); 3348 prhs[5] = sctx->ctx; 3349 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 3350 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3351 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 3352 mxDestroyArray(prhs[0]); 3353 mxDestroyArray(prhs[1]); 3354 mxDestroyArray(prhs[2]); 3355 mxDestroyArray(prhs[3]); 3356 mxDestroyArray(prhs[4]); 3357 mxDestroyArray(plhs[0]); 3358 mxDestroyArray(plhs[1]); 3359 PetscFunctionReturn(0); 3360 } 3361 3362 3363 #undef __FUNCT__ 3364 #define __FUNCT__ "SNESSetJacobianMatlab" 3365 /* 3366 SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 3367 vector for use by the SNES routines in solving systems of nonlinear 3368 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3369 3370 Logically Collective on SNES 3371 3372 Input Parameters: 3373 + snes - the SNES context 3374 . A,B - Jacobian matrices 3375 . func - function evaluation routine 3376 - ctx - user context 3377 3378 Calling sequence of func: 3379 $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 3380 3381 3382 Level: developer 3383 3384 .keywords: SNES, nonlinear, set, function 3385 3386 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3387 */ 3388 PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 3389 { 3390 PetscErrorCode ierr; 3391 SNESMatlabContext *sctx; 3392 3393 PetscFunctionBegin; 3394 /* currently sctx is memory bleed */ 3395 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3396 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3397 /* 3398 This should work, but it doesn't 3399 sctx->ctx = ctx; 3400 mexMakeArrayPersistent(sctx->ctx); 3401 */ 3402 sctx->ctx = mxDuplicateArray(ctx); 3403 ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 3404 PetscFunctionReturn(0); 3405 } 3406 3407 #undef __FUNCT__ 3408 #define __FUNCT__ "SNESMonitor_Matlab" 3409 /* 3410 SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 3411 3412 Collective on SNES 3413 3414 .seealso: SNESSetFunction(), SNESGetFunction() 3415 @*/ 3416 PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 3417 { 3418 PetscErrorCode ierr; 3419 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3420 int nlhs = 1,nrhs = 6; 3421 mxArray *plhs[1],*prhs[6]; 3422 long long int lx = 0,ls = 0; 3423 Vec x=snes->vec_sol; 3424 3425 PetscFunctionBegin; 3426 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3427 3428 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3429 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3430 prhs[0] = mxCreateDoubleScalar((double)ls); 3431 prhs[1] = mxCreateDoubleScalar((double)it); 3432 prhs[2] = mxCreateDoubleScalar((double)fnorm); 3433 prhs[3] = mxCreateDoubleScalar((double)lx); 3434 prhs[4] = mxCreateString(sctx->funcname); 3435 prhs[5] = sctx->ctx; 3436 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 3437 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3438 mxDestroyArray(prhs[0]); 3439 mxDestroyArray(prhs[1]); 3440 mxDestroyArray(prhs[2]); 3441 mxDestroyArray(prhs[3]); 3442 mxDestroyArray(prhs[4]); 3443 mxDestroyArray(plhs[0]); 3444 PetscFunctionReturn(0); 3445 } 3446 3447 3448 #undef __FUNCT__ 3449 #define __FUNCT__ "SNESMonitorSetMatlab" 3450 /* 3451 SNESMonitorSetMatlab - Sets the monitor function from MATLAB 3452 3453 Level: developer 3454 3455 .keywords: SNES, nonlinear, set, function 3456 3457 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3458 */ 3459 PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 3460 { 3461 PetscErrorCode ierr; 3462 SNESMatlabContext *sctx; 3463 3464 PetscFunctionBegin; 3465 /* currently sctx is memory bleed */ 3466 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3467 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3468 /* 3469 This should work, but it doesn't 3470 sctx->ctx = ctx; 3471 mexMakeArrayPersistent(sctx->ctx); 3472 */ 3473 sctx->ctx = mxDuplicateArray(ctx); 3474 ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 3475 PetscFunctionReturn(0); 3476 } 3477 3478 #endif 3479