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 if (snes->vec_func) {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 if (snes->jacobian) {ierr = MatDestroy(snes->jacobian);CHKERRQ(ierr);} 1333 snes->jacobian = A; 1334 } 1335 if (B) { 1336 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 1337 if (snes->jacobian_pre) {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__ "SNESDestroy" 1450 /*@ 1451 SNESDestroy - Destroys the nonlinear solver context that was created 1452 with SNESCreate(). 1453 1454 Collective on SNES 1455 1456 Input Parameter: 1457 . snes - the SNES context 1458 1459 Level: beginner 1460 1461 .keywords: SNES, nonlinear, destroy 1462 1463 .seealso: SNESCreate(), SNESSolve() 1464 @*/ 1465 PetscErrorCode SNESDestroy(SNES snes) 1466 { 1467 PetscErrorCode ierr; 1468 1469 PetscFunctionBegin; 1470 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1471 if (--((PetscObject)snes)->refct > 0) PetscFunctionReturn(0); 1472 1473 /* if memory was published with AMS then destroy it */ 1474 ierr = PetscObjectDepublish(snes);CHKERRQ(ierr); 1475 if (snes->ops->destroy) {ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);} 1476 1477 if (snes->dm) {ierr = DMDestroy(snes->dm);CHKERRQ(ierr);} 1478 if (snes->vec_rhs) {ierr = VecDestroy(snes->vec_rhs);CHKERRQ(ierr);} 1479 if (snes->vec_sol) {ierr = VecDestroy(snes->vec_sol);CHKERRQ(ierr);} 1480 if (snes->vec_sol_update) {ierr = VecDestroy(snes->vec_sol_update);CHKERRQ(ierr);} 1481 if (snes->vec_func) {ierr = VecDestroy(snes->vec_func);CHKERRQ(ierr);} 1482 if (snes->jacobian) {ierr = MatDestroy(snes->jacobian);CHKERRQ(ierr);} 1483 if (snes->jacobian_pre) {ierr = MatDestroy(snes->jacobian_pre);CHKERRQ(ierr);} 1484 if (snes->ksp) {ierr = KSPDestroy(snes->ksp);CHKERRQ(ierr);} 1485 if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 1486 if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);} 1487 ierr = PetscFree(snes->kspconvctx);CHKERRQ(ierr); 1488 if (snes->ops->convergeddestroy) {ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);} 1489 if (snes->conv_malloc) { 1490 ierr = PetscFree(snes->conv_hist);CHKERRQ(ierr); 1491 ierr = PetscFree(snes->conv_hist_its);CHKERRQ(ierr); 1492 } 1493 ierr = SNESMonitorCancel(snes);CHKERRQ(ierr); 1494 1495 ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 1496 PetscFunctionReturn(0); 1497 } 1498 1499 /* ----------- Routines to set solver parameters ---------- */ 1500 1501 #undef __FUNCT__ 1502 #define __FUNCT__ "SNESSetLagPreconditioner" 1503 /*@ 1504 SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 1505 1506 Logically Collective on SNES 1507 1508 Input Parameters: 1509 + snes - the SNES context 1510 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1511 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1512 1513 Options Database Keys: 1514 . -snes_lag_preconditioner <lag> 1515 1516 Notes: 1517 The default is 1 1518 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1519 If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 1520 1521 Level: intermediate 1522 1523 .keywords: SNES, nonlinear, set, convergence, tolerances 1524 1525 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1526 1527 @*/ 1528 PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 1529 { 1530 PetscFunctionBegin; 1531 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1532 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1533 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1534 PetscValidLogicalCollectiveInt(snes,lag,2); 1535 snes->lagpreconditioner = lag; 1536 PetscFunctionReturn(0); 1537 } 1538 1539 #undef __FUNCT__ 1540 #define __FUNCT__ "SNESGetLagPreconditioner" 1541 /*@ 1542 SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 1543 1544 Not Collective 1545 1546 Input Parameter: 1547 . snes - the SNES context 1548 1549 Output Parameter: 1550 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1551 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1552 1553 Options Database Keys: 1554 . -snes_lag_preconditioner <lag> 1555 1556 Notes: 1557 The default is 1 1558 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1559 1560 Level: intermediate 1561 1562 .keywords: SNES, nonlinear, set, convergence, tolerances 1563 1564 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 1565 1566 @*/ 1567 PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 1568 { 1569 PetscFunctionBegin; 1570 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1571 *lag = snes->lagpreconditioner; 1572 PetscFunctionReturn(0); 1573 } 1574 1575 #undef __FUNCT__ 1576 #define __FUNCT__ "SNESSetLagJacobian" 1577 /*@ 1578 SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 1579 often the preconditioner is rebuilt. 1580 1581 Logically Collective on SNES 1582 1583 Input Parameters: 1584 + snes - the SNES context 1585 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1586 the Jacobian is built etc. -2 means rebuild at next chance but then never again 1587 1588 Options Database Keys: 1589 . -snes_lag_jacobian <lag> 1590 1591 Notes: 1592 The default is 1 1593 The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1594 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 1595 at the next Newton step but never again (unless it is reset to another value) 1596 1597 Level: intermediate 1598 1599 .keywords: SNES, nonlinear, set, convergence, tolerances 1600 1601 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 1602 1603 @*/ 1604 PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 1605 { 1606 PetscFunctionBegin; 1607 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1608 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1609 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1610 PetscValidLogicalCollectiveInt(snes,lag,2); 1611 snes->lagjacobian = lag; 1612 PetscFunctionReturn(0); 1613 } 1614 1615 #undef __FUNCT__ 1616 #define __FUNCT__ "SNESGetLagJacobian" 1617 /*@ 1618 SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 1619 1620 Not Collective 1621 1622 Input Parameter: 1623 . snes - the SNES context 1624 1625 Output Parameter: 1626 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1627 the Jacobian is built etc. 1628 1629 Options Database Keys: 1630 . -snes_lag_jacobian <lag> 1631 1632 Notes: 1633 The default is 1 1634 The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1635 1636 Level: intermediate 1637 1638 .keywords: SNES, nonlinear, set, convergence, tolerances 1639 1640 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 1641 1642 @*/ 1643 PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 1644 { 1645 PetscFunctionBegin; 1646 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1647 *lag = snes->lagjacobian; 1648 PetscFunctionReturn(0); 1649 } 1650 1651 #undef __FUNCT__ 1652 #define __FUNCT__ "SNESSetTolerances" 1653 /*@ 1654 SNESSetTolerances - Sets various parameters used in convergence tests. 1655 1656 Logically Collective on SNES 1657 1658 Input Parameters: 1659 + snes - the SNES context 1660 . abstol - absolute convergence tolerance 1661 . rtol - relative convergence tolerance 1662 . stol - convergence tolerance in terms of the norm 1663 of the change in the solution between steps 1664 . maxit - maximum number of iterations 1665 - maxf - maximum number of function evaluations 1666 1667 Options Database Keys: 1668 + -snes_atol <abstol> - Sets abstol 1669 . -snes_rtol <rtol> - Sets rtol 1670 . -snes_stol <stol> - Sets stol 1671 . -snes_max_it <maxit> - Sets maxit 1672 - -snes_max_funcs <maxf> - Sets maxf 1673 1674 Notes: 1675 The default maximum number of iterations is 50. 1676 The default maximum number of function evaluations is 1000. 1677 1678 Level: intermediate 1679 1680 .keywords: SNES, nonlinear, set, convergence, tolerances 1681 1682 .seealso: SNESSetTrustRegionTolerance() 1683 @*/ 1684 PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 1685 { 1686 PetscFunctionBegin; 1687 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1688 PetscValidLogicalCollectiveReal(snes,abstol,2); 1689 PetscValidLogicalCollectiveReal(snes,rtol,3); 1690 PetscValidLogicalCollectiveReal(snes,stol,4); 1691 PetscValidLogicalCollectiveInt(snes,maxit,5); 1692 PetscValidLogicalCollectiveInt(snes,maxf,6); 1693 1694 if (abstol != PETSC_DEFAULT) snes->abstol = abstol; 1695 if (rtol != PETSC_DEFAULT) snes->rtol = rtol; 1696 if (stol != PETSC_DEFAULT) snes->xtol = stol; 1697 if (maxit != PETSC_DEFAULT) snes->max_its = maxit; 1698 if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf; 1699 PetscFunctionReturn(0); 1700 } 1701 1702 #undef __FUNCT__ 1703 #define __FUNCT__ "SNESGetTolerances" 1704 /*@ 1705 SNESGetTolerances - Gets various parameters used in convergence tests. 1706 1707 Not Collective 1708 1709 Input Parameters: 1710 + snes - the SNES context 1711 . atol - absolute convergence tolerance 1712 . rtol - relative convergence tolerance 1713 . stol - convergence tolerance in terms of the norm 1714 of the change in the solution between steps 1715 . maxit - maximum number of iterations 1716 - maxf - maximum number of function evaluations 1717 1718 Notes: 1719 The user can specify PETSC_NULL for any parameter that is not needed. 1720 1721 Level: intermediate 1722 1723 .keywords: SNES, nonlinear, get, convergence, tolerances 1724 1725 .seealso: SNESSetTolerances() 1726 @*/ 1727 PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 1728 { 1729 PetscFunctionBegin; 1730 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1731 if (atol) *atol = snes->abstol; 1732 if (rtol) *rtol = snes->rtol; 1733 if (stol) *stol = snes->xtol; 1734 if (maxit) *maxit = snes->max_its; 1735 if (maxf) *maxf = snes->max_funcs; 1736 PetscFunctionReturn(0); 1737 } 1738 1739 #undef __FUNCT__ 1740 #define __FUNCT__ "SNESSetTrustRegionTolerance" 1741 /*@ 1742 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 1743 1744 Logically Collective on SNES 1745 1746 Input Parameters: 1747 + snes - the SNES context 1748 - tol - tolerance 1749 1750 Options Database Key: 1751 . -snes_trtol <tol> - Sets tol 1752 1753 Level: intermediate 1754 1755 .keywords: SNES, nonlinear, set, trust region, tolerance 1756 1757 .seealso: SNESSetTolerances() 1758 @*/ 1759 PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 1760 { 1761 PetscFunctionBegin; 1762 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1763 PetscValidLogicalCollectiveReal(snes,tol,2); 1764 snes->deltatol = tol; 1765 PetscFunctionReturn(0); 1766 } 1767 1768 /* 1769 Duplicate the lg monitors for SNES from KSP; for some reason with 1770 dynamic libraries things don't work under Sun4 if we just use 1771 macros instead of functions 1772 */ 1773 #undef __FUNCT__ 1774 #define __FUNCT__ "SNESMonitorLG" 1775 PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 1776 { 1777 PetscErrorCode ierr; 1778 1779 PetscFunctionBegin; 1780 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1781 ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 1782 PetscFunctionReturn(0); 1783 } 1784 1785 #undef __FUNCT__ 1786 #define __FUNCT__ "SNESMonitorLGCreate" 1787 PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 1788 { 1789 PetscErrorCode ierr; 1790 1791 PetscFunctionBegin; 1792 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 1793 PetscFunctionReturn(0); 1794 } 1795 1796 #undef __FUNCT__ 1797 #define __FUNCT__ "SNESMonitorLGDestroy" 1798 PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG draw) 1799 { 1800 PetscErrorCode ierr; 1801 1802 PetscFunctionBegin; 1803 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 1804 PetscFunctionReturn(0); 1805 } 1806 1807 extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 1808 #undef __FUNCT__ 1809 #define __FUNCT__ "SNESMonitorLGRange" 1810 PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 1811 { 1812 PetscDrawLG lg; 1813 PetscErrorCode ierr; 1814 PetscReal x,y,per; 1815 PetscViewer v = (PetscViewer)monctx; 1816 static PetscReal prev; /* should be in the context */ 1817 PetscDraw draw; 1818 PetscFunctionBegin; 1819 if (!monctx) { 1820 MPI_Comm comm; 1821 1822 ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 1823 v = PETSC_VIEWER_DRAW_(comm); 1824 } 1825 ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 1826 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1827 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 1828 ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 1829 x = (PetscReal) n; 1830 if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 1831 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1832 if (n < 20 || !(n % 5)) { 1833 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1834 } 1835 1836 ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 1837 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1838 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 1839 ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 1840 ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 1841 x = (PetscReal) n; 1842 y = 100.0*per; 1843 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1844 if (n < 20 || !(n % 5)) { 1845 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1846 } 1847 1848 ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 1849 if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1850 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 1851 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 1852 x = (PetscReal) n; 1853 y = (prev - rnorm)/prev; 1854 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1855 if (n < 20 || !(n % 5)) { 1856 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1857 } 1858 1859 ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 1860 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1861 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 1862 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 1863 x = (PetscReal) n; 1864 y = (prev - rnorm)/(prev*per); 1865 if (n > 2) { /*skip initial crazy value */ 1866 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1867 } 1868 if (n < 20 || !(n % 5)) { 1869 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1870 } 1871 prev = rnorm; 1872 PetscFunctionReturn(0); 1873 } 1874 1875 #undef __FUNCT__ 1876 #define __FUNCT__ "SNESMonitorLGRangeCreate" 1877 PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 1878 { 1879 PetscErrorCode ierr; 1880 1881 PetscFunctionBegin; 1882 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 1883 PetscFunctionReturn(0); 1884 } 1885 1886 #undef __FUNCT__ 1887 #define __FUNCT__ "SNESMonitorLGRangeDestroy" 1888 PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG draw) 1889 { 1890 PetscErrorCode ierr; 1891 1892 PetscFunctionBegin; 1893 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 1894 PetscFunctionReturn(0); 1895 } 1896 1897 /* ------------ Routines to set performance monitoring options ----------- */ 1898 1899 #undef __FUNCT__ 1900 #define __FUNCT__ "SNESMonitorSet" 1901 /*@C 1902 SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 1903 iteration of the nonlinear solver to display the iteration's 1904 progress. 1905 1906 Logically Collective on SNES 1907 1908 Input Parameters: 1909 + snes - the SNES context 1910 . func - monitoring routine 1911 . mctx - [optional] user-defined context for private data for the 1912 monitor routine (use PETSC_NULL if no context is desired) 1913 - monitordestroy - [optional] routine that frees monitor context 1914 (may be PETSC_NULL) 1915 1916 Calling sequence of func: 1917 $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 1918 1919 + snes - the SNES context 1920 . its - iteration number 1921 . norm - 2-norm function value (may be estimated) 1922 - mctx - [optional] monitoring context 1923 1924 Options Database Keys: 1925 + -snes_monitor - sets SNESMonitorDefault() 1926 . -snes_monitor_draw - sets line graph monitor, 1927 uses SNESMonitorLGCreate() 1928 _ -snes_monitor_cancel - cancels all monitors that have 1929 been hardwired into a code by 1930 calls to SNESMonitorSet(), but 1931 does not cancel those set via 1932 the options database. 1933 1934 Notes: 1935 Several different monitoring routines may be set by calling 1936 SNESMonitorSet() multiple times; all will be called in the 1937 order in which they were set. 1938 1939 Fortran notes: Only a single monitor function can be set for each SNES object 1940 1941 Level: intermediate 1942 1943 .keywords: SNES, nonlinear, set, monitor 1944 1945 .seealso: SNESMonitorDefault(), SNESMonitorCancel() 1946 @*/ 1947 PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*)) 1948 { 1949 PetscInt i; 1950 1951 PetscFunctionBegin; 1952 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1953 if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 1954 for (i=0; i<snes->numbermonitors;i++) { 1955 if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) PetscFunctionReturn(0); 1956 1957 /* check if both default monitors that share common ASCII viewer */ 1958 if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) { 1959 if (mctx && snes->monitorcontext[i]) { 1960 PetscErrorCode ierr; 1961 PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx; 1962 PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i]; 1963 if (viewer1->viewer == viewer2->viewer) { 1964 ierr = (*monitordestroy)(mctx);CHKERRQ(ierr); 1965 PetscFunctionReturn(0); 1966 } 1967 } 1968 } 1969 } 1970 snes->monitor[snes->numbermonitors] = monitor; 1971 snes->monitordestroy[snes->numbermonitors] = monitordestroy; 1972 snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 1973 PetscFunctionReturn(0); 1974 } 1975 1976 #undef __FUNCT__ 1977 #define __FUNCT__ "SNESMonitorCancel" 1978 /*@C 1979 SNESMonitorCancel - Clears all the monitor functions for a SNES object. 1980 1981 Logically Collective on SNES 1982 1983 Input Parameters: 1984 . snes - the SNES context 1985 1986 Options Database Key: 1987 . -snes_monitor_cancel - cancels all monitors that have been hardwired 1988 into a code by calls to SNESMonitorSet(), but does not cancel those 1989 set via the options database 1990 1991 Notes: 1992 There is no way to clear one specific monitor from a SNES object. 1993 1994 Level: intermediate 1995 1996 .keywords: SNES, nonlinear, set, monitor 1997 1998 .seealso: SNESMonitorDefault(), SNESMonitorSet() 1999 @*/ 2000 PetscErrorCode SNESMonitorCancel(SNES snes) 2001 { 2002 PetscErrorCode ierr; 2003 PetscInt i; 2004 2005 PetscFunctionBegin; 2006 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2007 for (i=0; i<snes->numbermonitors; i++) { 2008 if (snes->monitordestroy[i]) { 2009 ierr = (*snes->monitordestroy[i])(snes->monitorcontext[i]);CHKERRQ(ierr); 2010 } 2011 } 2012 snes->numbermonitors = 0; 2013 PetscFunctionReturn(0); 2014 } 2015 2016 #undef __FUNCT__ 2017 #define __FUNCT__ "SNESSetConvergenceTest" 2018 /*@C 2019 SNESSetConvergenceTest - Sets the function that is to be used 2020 to test for convergence of the nonlinear iterative solution. 2021 2022 Logically Collective on SNES 2023 2024 Input Parameters: 2025 + snes - the SNES context 2026 . func - routine to test for convergence 2027 . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 2028 - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 2029 2030 Calling sequence of func: 2031 $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2032 2033 + snes - the SNES context 2034 . it - current iteration (0 is the first and is before any Newton step) 2035 . cctx - [optional] convergence context 2036 . reason - reason for convergence/divergence 2037 . xnorm - 2-norm of current iterate 2038 . gnorm - 2-norm of current step 2039 - f - 2-norm of function 2040 2041 Level: advanced 2042 2043 .keywords: SNES, nonlinear, set, convergence, test 2044 2045 .seealso: SNESDefaultConverged(), SNESSkipConverged() 2046 @*/ 2047 PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 2048 { 2049 PetscErrorCode ierr; 2050 2051 PetscFunctionBegin; 2052 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2053 if (!func) func = SNESSkipConverged; 2054 if (snes->ops->convergeddestroy) { 2055 ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 2056 } 2057 snes->ops->converged = func; 2058 snes->ops->convergeddestroy = destroy; 2059 snes->cnvP = cctx; 2060 PetscFunctionReturn(0); 2061 } 2062 2063 #undef __FUNCT__ 2064 #define __FUNCT__ "SNESGetConvergedReason" 2065 /*@ 2066 SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2067 2068 Not Collective 2069 2070 Input Parameter: 2071 . snes - the SNES context 2072 2073 Output Parameter: 2074 . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2075 manual pages for the individual convergence tests for complete lists 2076 2077 Level: intermediate 2078 2079 Notes: Can only be called after the call the SNESSolve() is complete. 2080 2081 .keywords: SNES, nonlinear, set, convergence, test 2082 2083 .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2084 @*/ 2085 PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2086 { 2087 PetscFunctionBegin; 2088 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2089 PetscValidPointer(reason,2); 2090 *reason = snes->reason; 2091 PetscFunctionReturn(0); 2092 } 2093 2094 #undef __FUNCT__ 2095 #define __FUNCT__ "SNESSetConvergenceHistory" 2096 /*@ 2097 SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2098 2099 Logically Collective on SNES 2100 2101 Input Parameters: 2102 + snes - iterative context obtained from SNESCreate() 2103 . a - array to hold history, this array will contain the function norms computed at each step 2104 . its - integer array holds the number of linear iterations for each solve. 2105 . na - size of a and its 2106 - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2107 else it continues storing new values for new nonlinear solves after the old ones 2108 2109 Notes: 2110 If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2111 default array of length 10000 is allocated. 2112 2113 This routine is useful, e.g., when running a code for purposes 2114 of accurate performance monitoring, when no I/O should be done 2115 during the section of code that is being timed. 2116 2117 Level: intermediate 2118 2119 .keywords: SNES, set, convergence, history 2120 2121 .seealso: SNESGetConvergenceHistory() 2122 2123 @*/ 2124 PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2125 { 2126 PetscErrorCode ierr; 2127 2128 PetscFunctionBegin; 2129 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2130 if (na) PetscValidScalarPointer(a,2); 2131 if (its) PetscValidIntPointer(its,3); 2132 if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2133 if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2134 ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2135 ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2136 snes->conv_malloc = PETSC_TRUE; 2137 } 2138 snes->conv_hist = a; 2139 snes->conv_hist_its = its; 2140 snes->conv_hist_max = na; 2141 snes->conv_hist_len = 0; 2142 snes->conv_hist_reset = reset; 2143 PetscFunctionReturn(0); 2144 } 2145 2146 #if defined(PETSC_HAVE_MATLAB_ENGINE) 2147 #include <engine.h> /* MATLAB include file */ 2148 #include <mex.h> /* MATLAB include file */ 2149 EXTERN_C_BEGIN 2150 #undef __FUNCT__ 2151 #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2152 mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2153 { 2154 mxArray *mat; 2155 PetscInt i; 2156 PetscReal *ar; 2157 2158 PetscFunctionBegin; 2159 mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2160 ar = (PetscReal*) mxGetData(mat); 2161 for (i=0; i<snes->conv_hist_len; i++) { 2162 ar[i] = snes->conv_hist[i]; 2163 } 2164 PetscFunctionReturn(mat); 2165 } 2166 EXTERN_C_END 2167 #endif 2168 2169 2170 #undef __FUNCT__ 2171 #define __FUNCT__ "SNESGetConvergenceHistory" 2172 /*@C 2173 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 2174 2175 Not Collective 2176 2177 Input Parameter: 2178 . snes - iterative context obtained from SNESCreate() 2179 2180 Output Parameters: 2181 . a - array to hold history 2182 . its - integer array holds the number of linear iterations (or 2183 negative if not converged) for each solve. 2184 - na - size of a and its 2185 2186 Notes: 2187 The calling sequence for this routine in Fortran is 2188 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 2189 2190 This routine is useful, e.g., when running a code for purposes 2191 of accurate performance monitoring, when no I/O should be done 2192 during the section of code that is being timed. 2193 2194 Level: intermediate 2195 2196 .keywords: SNES, get, convergence, history 2197 2198 .seealso: SNESSetConvergencHistory() 2199 2200 @*/ 2201 PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 2202 { 2203 PetscFunctionBegin; 2204 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2205 if (a) *a = snes->conv_hist; 2206 if (its) *its = snes->conv_hist_its; 2207 if (na) *na = snes->conv_hist_len; 2208 PetscFunctionReturn(0); 2209 } 2210 2211 #undef __FUNCT__ 2212 #define __FUNCT__ "SNESSetUpdate" 2213 /*@C 2214 SNESSetUpdate - Sets the general-purpose update function called 2215 at the beginning of every iteration of the nonlinear solve. Specifically 2216 it is called just before the Jacobian is "evaluated". 2217 2218 Logically Collective on SNES 2219 2220 Input Parameters: 2221 . snes - The nonlinear solver context 2222 . func - The function 2223 2224 Calling sequence of func: 2225 . func (SNES snes, PetscInt step); 2226 2227 . step - The current step of the iteration 2228 2229 Level: advanced 2230 2231 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() 2232 This is not used by most users. 2233 2234 .keywords: SNES, update 2235 2236 .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 2237 @*/ 2238 PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 2239 { 2240 PetscFunctionBegin; 2241 PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 2242 snes->ops->update = func; 2243 PetscFunctionReturn(0); 2244 } 2245 2246 #undef __FUNCT__ 2247 #define __FUNCT__ "SNESDefaultUpdate" 2248 /*@ 2249 SNESDefaultUpdate - The default update function which does nothing. 2250 2251 Not collective 2252 2253 Input Parameters: 2254 . snes - The nonlinear solver context 2255 . step - The current step of the iteration 2256 2257 Level: intermediate 2258 2259 .keywords: SNES, update 2260 .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 2261 @*/ 2262 PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 2263 { 2264 PetscFunctionBegin; 2265 PetscFunctionReturn(0); 2266 } 2267 2268 #undef __FUNCT__ 2269 #define __FUNCT__ "SNESScaleStep_Private" 2270 /* 2271 SNESScaleStep_Private - Scales a step so that its length is less than the 2272 positive parameter delta. 2273 2274 Input Parameters: 2275 + snes - the SNES context 2276 . y - approximate solution of linear system 2277 . fnorm - 2-norm of current function 2278 - delta - trust region size 2279 2280 Output Parameters: 2281 + gpnorm - predicted function norm at the new point, assuming local 2282 linearization. The value is zero if the step lies within the trust 2283 region, and exceeds zero otherwise. 2284 - ynorm - 2-norm of the step 2285 2286 Note: 2287 For non-trust region methods such as SNESLS, the parameter delta 2288 is set to be the maximum allowable step size. 2289 2290 .keywords: SNES, nonlinear, scale, step 2291 */ 2292 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 2293 { 2294 PetscReal nrm; 2295 PetscScalar cnorm; 2296 PetscErrorCode ierr; 2297 2298 PetscFunctionBegin; 2299 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2300 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 2301 PetscCheckSameComm(snes,1,y,2); 2302 2303 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 2304 if (nrm > *delta) { 2305 nrm = *delta/nrm; 2306 *gpnorm = (1.0 - nrm)*(*fnorm); 2307 cnorm = nrm; 2308 ierr = VecScale(y,cnorm);CHKERRQ(ierr); 2309 *ynorm = *delta; 2310 } else { 2311 *gpnorm = 0.0; 2312 *ynorm = nrm; 2313 } 2314 PetscFunctionReturn(0); 2315 } 2316 2317 #undef __FUNCT__ 2318 #define __FUNCT__ "SNESSolve" 2319 /*@C 2320 SNESSolve - Solves a nonlinear system F(x) = b. 2321 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 2322 2323 Collective on SNES 2324 2325 Input Parameters: 2326 + snes - the SNES context 2327 . b - the constant part of the equation, or PETSC_NULL to use zero. 2328 - x - the solution vector. 2329 2330 Notes: 2331 The user should initialize the vector,x, with the initial guess 2332 for the nonlinear solve prior to calling SNESSolve. In particular, 2333 to employ an initial guess of zero, the user should explicitly set 2334 this vector to zero by calling VecSet(). 2335 2336 Level: beginner 2337 2338 .keywords: SNES, nonlinear, solve 2339 2340 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian() 2341 @*/ 2342 PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 2343 { 2344 PetscErrorCode ierr; 2345 PetscBool flg; 2346 char filename[PETSC_MAX_PATH_LEN]; 2347 PetscViewer viewer; 2348 2349 PetscFunctionBegin; 2350 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2351 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2352 PetscCheckSameComm(snes,1,x,3); 2353 if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 2354 if (b) PetscCheckSameComm(snes,1,b,2); 2355 2356 /* set solution vector */ 2357 ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 2358 if (snes->vec_sol) { ierr = VecDestroy(snes->vec_sol);CHKERRQ(ierr); } 2359 snes->vec_sol = x; 2360 /* set afine vector if provided */ 2361 if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 2362 if (snes->vec_rhs) { ierr = VecDestroy(snes->vec_rhs);CHKERRQ(ierr); } 2363 snes->vec_rhs = b; 2364 2365 ierr = SNESSetUp(snes);CHKERRQ(ierr); 2366 2367 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 2368 snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 2369 2370 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 2371 ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 2372 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 2373 if (snes->domainerror){ 2374 snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 2375 snes->domainerror = PETSC_FALSE; 2376 } 2377 if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 2378 2379 ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 2380 if (flg && !PetscPreLoadingOn) { 2381 ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 2382 ierr = SNESView(snes,viewer);CHKERRQ(ierr); 2383 ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); 2384 } 2385 2386 flg = PETSC_FALSE; 2387 ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 2388 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 2389 if (snes->printreason) { 2390 if (snes->reason > 0) { 2391 ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 2392 } else { 2393 ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 2394 } 2395 } 2396 2397 if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 2398 PetscFunctionReturn(0); 2399 } 2400 2401 /* --------- Internal routines for SNES Package --------- */ 2402 2403 #undef __FUNCT__ 2404 #define __FUNCT__ "SNESSetType" 2405 /*@C 2406 SNESSetType - Sets the method for the nonlinear solver. 2407 2408 Collective on SNES 2409 2410 Input Parameters: 2411 + snes - the SNES context 2412 - type - a known method 2413 2414 Options Database Key: 2415 . -snes_type <type> - Sets the method; use -help for a list 2416 of available methods (for instance, ls or tr) 2417 2418 Notes: 2419 See "petsc/include/petscsnes.h" for available methods (for instance) 2420 + SNESLS - Newton's method with line search 2421 (systems of nonlinear equations) 2422 . SNESTR - Newton's method with trust region 2423 (systems of nonlinear equations) 2424 2425 Normally, it is best to use the SNESSetFromOptions() command and then 2426 set the SNES solver type from the options database rather than by using 2427 this routine. Using the options database provides the user with 2428 maximum flexibility in evaluating the many nonlinear solvers. 2429 The SNESSetType() routine is provided for those situations where it 2430 is necessary to set the nonlinear solver independently of the command 2431 line or options database. This might be the case, for example, when 2432 the choice of solver changes during the execution of the program, 2433 and the user's application is taking responsibility for choosing the 2434 appropriate method. 2435 2436 Level: intermediate 2437 2438 .keywords: SNES, set, type 2439 2440 .seealso: SNESType, SNESCreate() 2441 2442 @*/ 2443 PetscErrorCode SNESSetType(SNES snes,const SNESType type) 2444 { 2445 PetscErrorCode ierr,(*r)(SNES); 2446 PetscBool match; 2447 2448 PetscFunctionBegin; 2449 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2450 PetscValidCharPointer(type,2); 2451 2452 ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 2453 if (match) PetscFunctionReturn(0); 2454 2455 ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 2456 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 2457 /* Destroy the previous private SNES context */ 2458 if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 2459 /* Reinitialize function pointers in SNESOps structure */ 2460 snes->ops->setup = 0; 2461 snes->ops->solve = 0; 2462 snes->ops->view = 0; 2463 snes->ops->setfromoptions = 0; 2464 snes->ops->destroy = 0; 2465 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 2466 snes->setupcalled = PETSC_FALSE; 2467 ierr = (*r)(snes);CHKERRQ(ierr); 2468 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 2469 #if defined(PETSC_HAVE_AMS) 2470 if (PetscAMSPublishAll) { 2471 ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 2472 } 2473 #endif 2474 PetscFunctionReturn(0); 2475 } 2476 2477 2478 /* --------------------------------------------------------------------- */ 2479 #undef __FUNCT__ 2480 #define __FUNCT__ "SNESRegisterDestroy" 2481 /*@ 2482 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 2483 registered by SNESRegisterDynamic(). 2484 2485 Not Collective 2486 2487 Level: advanced 2488 2489 .keywords: SNES, nonlinear, register, destroy 2490 2491 .seealso: SNESRegisterAll(), SNESRegisterAll() 2492 @*/ 2493 PetscErrorCode SNESRegisterDestroy(void) 2494 { 2495 PetscErrorCode ierr; 2496 2497 PetscFunctionBegin; 2498 ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 2499 SNESRegisterAllCalled = PETSC_FALSE; 2500 PetscFunctionReturn(0); 2501 } 2502 2503 #undef __FUNCT__ 2504 #define __FUNCT__ "SNESGetType" 2505 /*@C 2506 SNESGetType - Gets the SNES method type and name (as a string). 2507 2508 Not Collective 2509 2510 Input Parameter: 2511 . snes - nonlinear solver context 2512 2513 Output Parameter: 2514 . type - SNES method (a character string) 2515 2516 Level: intermediate 2517 2518 .keywords: SNES, nonlinear, get, type, name 2519 @*/ 2520 PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 2521 { 2522 PetscFunctionBegin; 2523 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2524 PetscValidPointer(type,2); 2525 *type = ((PetscObject)snes)->type_name; 2526 PetscFunctionReturn(0); 2527 } 2528 2529 #undef __FUNCT__ 2530 #define __FUNCT__ "SNESGetSolution" 2531 /*@ 2532 SNESGetSolution - Returns the vector where the approximate solution is 2533 stored. 2534 2535 Not Collective, but Vec is parallel if SNES is parallel 2536 2537 Input Parameter: 2538 . snes - the SNES context 2539 2540 Output Parameter: 2541 . x - the solution 2542 2543 Level: intermediate 2544 2545 .keywords: SNES, nonlinear, get, solution 2546 2547 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 2548 @*/ 2549 PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 2550 { 2551 PetscFunctionBegin; 2552 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2553 PetscValidPointer(x,2); 2554 *x = snes->vec_sol; 2555 PetscFunctionReturn(0); 2556 } 2557 2558 #undef __FUNCT__ 2559 #define __FUNCT__ "SNESGetSolutionUpdate" 2560 /*@ 2561 SNESGetSolutionUpdate - Returns the vector where the solution update is 2562 stored. 2563 2564 Not Collective, but Vec is parallel if SNES is parallel 2565 2566 Input Parameter: 2567 . snes - the SNES context 2568 2569 Output Parameter: 2570 . x - the solution update 2571 2572 Level: advanced 2573 2574 .keywords: SNES, nonlinear, get, solution, update 2575 2576 .seealso: SNESGetSolution(), SNESGetFunction() 2577 @*/ 2578 PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 2579 { 2580 PetscFunctionBegin; 2581 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2582 PetscValidPointer(x,2); 2583 *x = snes->vec_sol_update; 2584 PetscFunctionReturn(0); 2585 } 2586 2587 #undef __FUNCT__ 2588 #define __FUNCT__ "SNESGetFunction" 2589 /*@C 2590 SNESGetFunction - Returns the vector where the function is stored. 2591 2592 Not Collective, but Vec is parallel if SNES is parallel 2593 2594 Input Parameter: 2595 . snes - the SNES context 2596 2597 Output Parameter: 2598 + r - the function (or PETSC_NULL) 2599 . func - the function (or PETSC_NULL) 2600 - ctx - the function context (or PETSC_NULL) 2601 2602 Level: advanced 2603 2604 .keywords: SNES, nonlinear, get, function 2605 2606 .seealso: SNESSetFunction(), SNESGetSolution() 2607 @*/ 2608 PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 2609 { 2610 PetscFunctionBegin; 2611 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2612 if (r) *r = snes->vec_func; 2613 if (func) *func = snes->ops->computefunction; 2614 if (ctx) *ctx = snes->funP; 2615 PetscFunctionReturn(0); 2616 } 2617 2618 #undef __FUNCT__ 2619 #define __FUNCT__ "SNESSetOptionsPrefix" 2620 /*@C 2621 SNESSetOptionsPrefix - Sets the prefix used for searching for all 2622 SNES options in the database. 2623 2624 Logically Collective on SNES 2625 2626 Input Parameter: 2627 + snes - the SNES context 2628 - prefix - the prefix to prepend to all option names 2629 2630 Notes: 2631 A hyphen (-) must NOT be given at the beginning of the prefix name. 2632 The first character of all runtime options is AUTOMATICALLY the hyphen. 2633 2634 Level: advanced 2635 2636 .keywords: SNES, set, options, prefix, database 2637 2638 .seealso: SNESSetFromOptions() 2639 @*/ 2640 PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 2641 { 2642 PetscErrorCode ierr; 2643 2644 PetscFunctionBegin; 2645 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2646 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2647 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 2648 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2649 PetscFunctionReturn(0); 2650 } 2651 2652 #undef __FUNCT__ 2653 #define __FUNCT__ "SNESAppendOptionsPrefix" 2654 /*@C 2655 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 2656 SNES options in the database. 2657 2658 Logically Collective on SNES 2659 2660 Input Parameters: 2661 + snes - the SNES context 2662 - prefix - the prefix to prepend to all option names 2663 2664 Notes: 2665 A hyphen (-) must NOT be given at the beginning of the prefix name. 2666 The first character of all runtime options is AUTOMATICALLY the hyphen. 2667 2668 Level: advanced 2669 2670 .keywords: SNES, append, options, prefix, database 2671 2672 .seealso: SNESGetOptionsPrefix() 2673 @*/ 2674 PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 2675 { 2676 PetscErrorCode ierr; 2677 2678 PetscFunctionBegin; 2679 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2680 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2681 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 2682 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2683 PetscFunctionReturn(0); 2684 } 2685 2686 #undef __FUNCT__ 2687 #define __FUNCT__ "SNESGetOptionsPrefix" 2688 /*@C 2689 SNESGetOptionsPrefix - Sets the prefix used for searching for all 2690 SNES options in the database. 2691 2692 Not Collective 2693 2694 Input Parameter: 2695 . snes - the SNES context 2696 2697 Output Parameter: 2698 . prefix - pointer to the prefix string used 2699 2700 Notes: On the fortran side, the user should pass in a string 'prefix' of 2701 sufficient length to hold the prefix. 2702 2703 Level: advanced 2704 2705 .keywords: SNES, get, options, prefix, database 2706 2707 .seealso: SNESAppendOptionsPrefix() 2708 @*/ 2709 PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 2710 { 2711 PetscErrorCode ierr; 2712 2713 PetscFunctionBegin; 2714 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2715 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2716 PetscFunctionReturn(0); 2717 } 2718 2719 2720 #undef __FUNCT__ 2721 #define __FUNCT__ "SNESRegister" 2722 /*@C 2723 SNESRegister - See SNESRegisterDynamic() 2724 2725 Level: advanced 2726 @*/ 2727 PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 2728 { 2729 char fullname[PETSC_MAX_PATH_LEN]; 2730 PetscErrorCode ierr; 2731 2732 PetscFunctionBegin; 2733 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 2734 ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 2735 PetscFunctionReturn(0); 2736 } 2737 2738 #undef __FUNCT__ 2739 #define __FUNCT__ "SNESTestLocalMin" 2740 PetscErrorCode SNESTestLocalMin(SNES snes) 2741 { 2742 PetscErrorCode ierr; 2743 PetscInt N,i,j; 2744 Vec u,uh,fh; 2745 PetscScalar value; 2746 PetscReal norm; 2747 2748 PetscFunctionBegin; 2749 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 2750 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 2751 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 2752 2753 /* currently only works for sequential */ 2754 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 2755 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 2756 for (i=0; i<N; i++) { 2757 ierr = VecCopy(u,uh);CHKERRQ(ierr); 2758 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 2759 for (j=-10; j<11; j++) { 2760 value = PetscSign(j)*exp(PetscAbs(j)-10.0); 2761 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2762 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 2763 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 2764 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 2765 value = -value; 2766 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2767 } 2768 } 2769 ierr = VecDestroy(uh);CHKERRQ(ierr); 2770 ierr = VecDestroy(fh);CHKERRQ(ierr); 2771 PetscFunctionReturn(0); 2772 } 2773 2774 #undef __FUNCT__ 2775 #define __FUNCT__ "SNESKSPSetUseEW" 2776 /*@ 2777 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 2778 computing relative tolerance for linear solvers within an inexact 2779 Newton method. 2780 2781 Logically Collective on SNES 2782 2783 Input Parameters: 2784 + snes - SNES context 2785 - flag - PETSC_TRUE or PETSC_FALSE 2786 2787 Options Database: 2788 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 2789 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 2790 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 2791 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 2792 . -snes_ksp_ew_gamma <gamma> - Sets gamma 2793 . -snes_ksp_ew_alpha <alpha> - Sets alpha 2794 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 2795 - -snes_ksp_ew_threshold <threshold> - Sets threshold 2796 2797 Notes: 2798 Currently, the default is to use a constant relative tolerance for 2799 the inner linear solvers. Alternatively, one can use the 2800 Eisenstat-Walker method, where the relative convergence tolerance 2801 is reset at each Newton iteration according progress of the nonlinear 2802 solver. 2803 2804 Level: advanced 2805 2806 Reference: 2807 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2808 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2809 2810 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2811 2812 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 2813 @*/ 2814 PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 2815 { 2816 PetscFunctionBegin; 2817 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2818 PetscValidLogicalCollectiveBool(snes,flag,2); 2819 snes->ksp_ewconv = flag; 2820 PetscFunctionReturn(0); 2821 } 2822 2823 #undef __FUNCT__ 2824 #define __FUNCT__ "SNESKSPGetUseEW" 2825 /*@ 2826 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 2827 for computing relative tolerance for linear solvers within an 2828 inexact Newton method. 2829 2830 Not Collective 2831 2832 Input Parameter: 2833 . snes - SNES context 2834 2835 Output Parameter: 2836 . flag - PETSC_TRUE or PETSC_FALSE 2837 2838 Notes: 2839 Currently, the default is to use a constant relative tolerance for 2840 the inner linear solvers. Alternatively, one can use the 2841 Eisenstat-Walker method, where the relative convergence tolerance 2842 is reset at each Newton iteration according progress of the nonlinear 2843 solver. 2844 2845 Level: advanced 2846 2847 Reference: 2848 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2849 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2850 2851 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2852 2853 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 2854 @*/ 2855 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 2856 { 2857 PetscFunctionBegin; 2858 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2859 PetscValidPointer(flag,2); 2860 *flag = snes->ksp_ewconv; 2861 PetscFunctionReturn(0); 2862 } 2863 2864 #undef __FUNCT__ 2865 #define __FUNCT__ "SNESKSPSetParametersEW" 2866 /*@ 2867 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 2868 convergence criteria for the linear solvers within an inexact 2869 Newton method. 2870 2871 Logically Collective on SNES 2872 2873 Input Parameters: 2874 + snes - SNES context 2875 . version - version 1, 2 (default is 2) or 3 2876 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2877 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2878 . gamma - multiplicative factor for version 2 rtol computation 2879 (0 <= gamma2 <= 1) 2880 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2881 . alpha2 - power for safeguard 2882 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2883 2884 Note: 2885 Version 3 was contributed by Luis Chacon, June 2006. 2886 2887 Use PETSC_DEFAULT to retain the default for any of the parameters. 2888 2889 Level: advanced 2890 2891 Reference: 2892 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2893 inexact Newton method", Utah State University Math. Stat. Dept. Res. 2894 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 2895 2896 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 2897 2898 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 2899 @*/ 2900 PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 2901 PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 2902 { 2903 SNESKSPEW *kctx; 2904 PetscFunctionBegin; 2905 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2906 kctx = (SNESKSPEW*)snes->kspconvctx; 2907 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2908 PetscValidLogicalCollectiveInt(snes,version,2); 2909 PetscValidLogicalCollectiveReal(snes,rtol_0,3); 2910 PetscValidLogicalCollectiveReal(snes,rtol_max,4); 2911 PetscValidLogicalCollectiveReal(snes,gamma,5); 2912 PetscValidLogicalCollectiveReal(snes,alpha,6); 2913 PetscValidLogicalCollectiveReal(snes,alpha2,7); 2914 PetscValidLogicalCollectiveReal(snes,threshold,8); 2915 2916 if (version != PETSC_DEFAULT) kctx->version = version; 2917 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 2918 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 2919 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 2920 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 2921 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 2922 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 2923 2924 if (kctx->version < 1 || kctx->version > 3) { 2925 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 2926 } 2927 if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 2928 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 2929 } 2930 if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 2931 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 2932 } 2933 if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 2934 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 2935 } 2936 if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 2937 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 2938 } 2939 if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 2940 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 2941 } 2942 PetscFunctionReturn(0); 2943 } 2944 2945 #undef __FUNCT__ 2946 #define __FUNCT__ "SNESKSPGetParametersEW" 2947 /*@ 2948 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 2949 convergence criteria for the linear solvers within an inexact 2950 Newton method. 2951 2952 Not Collective 2953 2954 Input Parameters: 2955 snes - SNES context 2956 2957 Output Parameters: 2958 + version - version 1, 2 (default is 2) or 3 2959 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2960 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2961 . gamma - multiplicative factor for version 2 rtol computation 2962 (0 <= gamma2 <= 1) 2963 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2964 . alpha2 - power for safeguard 2965 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2966 2967 Level: advanced 2968 2969 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 2970 2971 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 2972 @*/ 2973 PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 2974 PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 2975 { 2976 SNESKSPEW *kctx; 2977 PetscFunctionBegin; 2978 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2979 kctx = (SNESKSPEW*)snes->kspconvctx; 2980 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2981 if(version) *version = kctx->version; 2982 if(rtol_0) *rtol_0 = kctx->rtol_0; 2983 if(rtol_max) *rtol_max = kctx->rtol_max; 2984 if(gamma) *gamma = kctx->gamma; 2985 if(alpha) *alpha = kctx->alpha; 2986 if(alpha2) *alpha2 = kctx->alpha2; 2987 if(threshold) *threshold = kctx->threshold; 2988 PetscFunctionReturn(0); 2989 } 2990 2991 #undef __FUNCT__ 2992 #define __FUNCT__ "SNESKSPEW_PreSolve" 2993 static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 2994 { 2995 PetscErrorCode ierr; 2996 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 2997 PetscReal rtol=PETSC_DEFAULT,stol; 2998 2999 PetscFunctionBegin; 3000 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3001 if (!snes->iter) { /* first time in, so use the original user rtol */ 3002 rtol = kctx->rtol_0; 3003 } else { 3004 if (kctx->version == 1) { 3005 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 3006 if (rtol < 0.0) rtol = -rtol; 3007 stol = pow(kctx->rtol_last,kctx->alpha2); 3008 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3009 } else if (kctx->version == 2) { 3010 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3011 stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 3012 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3013 } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 3014 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3015 /* safeguard: avoid sharp decrease of rtol */ 3016 stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 3017 stol = PetscMax(rtol,stol); 3018 rtol = PetscMin(kctx->rtol_0,stol); 3019 /* safeguard: avoid oversolving */ 3020 stol = kctx->gamma*(snes->ttol)/snes->norm; 3021 stol = PetscMax(rtol,stol); 3022 rtol = PetscMin(kctx->rtol_0,stol); 3023 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 3024 } 3025 /* safeguard: avoid rtol greater than one */ 3026 rtol = PetscMin(rtol,kctx->rtol_max); 3027 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 3028 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 3029 PetscFunctionReturn(0); 3030 } 3031 3032 #undef __FUNCT__ 3033 #define __FUNCT__ "SNESKSPEW_PostSolve" 3034 static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 3035 { 3036 PetscErrorCode ierr; 3037 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 3038 PCSide pcside; 3039 Vec lres; 3040 3041 PetscFunctionBegin; 3042 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3043 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 3044 ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 3045 if (kctx->version == 1) { 3046 ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 3047 if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 3048 /* KSP residual is true linear residual */ 3049 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 3050 } else { 3051 /* KSP residual is preconditioned residual */ 3052 /* compute true linear residual norm */ 3053 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 3054 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 3055 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 3056 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 3057 ierr = VecDestroy(lres);CHKERRQ(ierr); 3058 } 3059 } 3060 PetscFunctionReturn(0); 3061 } 3062 3063 #undef __FUNCT__ 3064 #define __FUNCT__ "SNES_KSPSolve" 3065 PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 3066 { 3067 PetscErrorCode ierr; 3068 3069 PetscFunctionBegin; 3070 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3071 ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3072 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3073 PetscFunctionReturn(0); 3074 } 3075 3076 #undef __FUNCT__ 3077 #define __FUNCT__ "SNESSetDM" 3078 /*@ 3079 SNESSetDM - Sets the DM that may be used by some preconditioners 3080 3081 Logically Collective on SNES 3082 3083 Input Parameters: 3084 + snes - the preconditioner context 3085 - dm - the dm 3086 3087 Level: intermediate 3088 3089 3090 .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 3091 @*/ 3092 PetscErrorCode SNESSetDM(SNES snes,DM dm) 3093 { 3094 PetscErrorCode ierr; 3095 KSP ksp; 3096 3097 PetscFunctionBegin; 3098 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3099 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 3100 if (snes->dm) {ierr = DMDestroy(snes->dm);CHKERRQ(ierr);} 3101 snes->dm = dm; 3102 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3103 ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3104 ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 3105 PetscFunctionReturn(0); 3106 } 3107 3108 #undef __FUNCT__ 3109 #define __FUNCT__ "SNESGetDM" 3110 /*@ 3111 SNESGetDM - Gets the DM that may be used by some preconditioners 3112 3113 Not Collective but DM obtained is parallel on SNES 3114 3115 Input Parameter: 3116 . snes - the preconditioner context 3117 3118 Output Parameter: 3119 . dm - the dm 3120 3121 Level: intermediate 3122 3123 3124 .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 3125 @*/ 3126 PetscErrorCode SNESGetDM(SNES snes,DM *dm) 3127 { 3128 PetscFunctionBegin; 3129 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3130 *dm = snes->dm; 3131 PetscFunctionReturn(0); 3132 } 3133 3134 #if defined(PETSC_HAVE_MATLAB_ENGINE) 3135 #include <mex.h> 3136 3137 typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 3138 3139 #undef __FUNCT__ 3140 #define __FUNCT__ "SNESComputeFunction_Matlab" 3141 /* 3142 SNESComputeFunction_Matlab - Calls the function that has been set with 3143 SNESSetFunctionMatlab(). 3144 3145 Collective on SNES 3146 3147 Input Parameters: 3148 + snes - the SNES context 3149 - x - input vector 3150 3151 Output Parameter: 3152 . y - function vector, as set by SNESSetFunction() 3153 3154 Notes: 3155 SNESComputeFunction() is typically used within nonlinear solvers 3156 implementations, so most users would not generally call this routine 3157 themselves. 3158 3159 Level: developer 3160 3161 .keywords: SNES, nonlinear, compute, function 3162 3163 .seealso: SNESSetFunction(), SNESGetFunction() 3164 */ 3165 PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 3166 { 3167 PetscErrorCode ierr; 3168 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3169 int nlhs = 1,nrhs = 5; 3170 mxArray *plhs[1],*prhs[5]; 3171 long long int lx = 0,ly = 0,ls = 0; 3172 3173 PetscFunctionBegin; 3174 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3175 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3176 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3177 PetscCheckSameComm(snes,1,x,2); 3178 PetscCheckSameComm(snes,1,y,3); 3179 3180 /* call Matlab function in ctx with arguments x and y */ 3181 3182 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3183 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3184 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 3185 prhs[0] = mxCreateDoubleScalar((double)ls); 3186 prhs[1] = mxCreateDoubleScalar((double)lx); 3187 prhs[2] = mxCreateDoubleScalar((double)ly); 3188 prhs[3] = mxCreateString(sctx->funcname); 3189 prhs[4] = sctx->ctx; 3190 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 3191 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3192 mxDestroyArray(prhs[0]); 3193 mxDestroyArray(prhs[1]); 3194 mxDestroyArray(prhs[2]); 3195 mxDestroyArray(prhs[3]); 3196 mxDestroyArray(plhs[0]); 3197 PetscFunctionReturn(0); 3198 } 3199 3200 3201 #undef __FUNCT__ 3202 #define __FUNCT__ "SNESSetFunctionMatlab" 3203 /* 3204 SNESSetFunctionMatlab - Sets the function evaluation routine and function 3205 vector for use by the SNES routines in solving systems of nonlinear 3206 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3207 3208 Logically Collective on SNES 3209 3210 Input Parameters: 3211 + snes - the SNES context 3212 . r - vector to store function value 3213 - func - function evaluation routine 3214 3215 Calling sequence of func: 3216 $ func (SNES snes,Vec x,Vec f,void *ctx); 3217 3218 3219 Notes: 3220 The Newton-like methods typically solve linear systems of the form 3221 $ f'(x) x = -f(x), 3222 where f'(x) denotes the Jacobian matrix and f(x) is the function. 3223 3224 Level: beginner 3225 3226 .keywords: SNES, nonlinear, set, function 3227 3228 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3229 */ 3230 PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 3231 { 3232 PetscErrorCode ierr; 3233 SNESMatlabContext *sctx; 3234 3235 PetscFunctionBegin; 3236 /* currently sctx is memory bleed */ 3237 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3238 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3239 /* 3240 This should work, but it doesn't 3241 sctx->ctx = ctx; 3242 mexMakeArrayPersistent(sctx->ctx); 3243 */ 3244 sctx->ctx = mxDuplicateArray(ctx); 3245 ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 3246 PetscFunctionReturn(0); 3247 } 3248 3249 #undef __FUNCT__ 3250 #define __FUNCT__ "SNESComputeJacobian_Matlab" 3251 /* 3252 SNESComputeJacobian_Matlab - Calls the function that has been set with 3253 SNESSetJacobianMatlab(). 3254 3255 Collective on SNES 3256 3257 Input Parameters: 3258 + snes - the SNES context 3259 . x - input vector 3260 . A, B - the matrices 3261 - ctx - user context 3262 3263 Output Parameter: 3264 . flag - structure of the matrix 3265 3266 Level: developer 3267 3268 .keywords: SNES, nonlinear, compute, function 3269 3270 .seealso: SNESSetFunction(), SNESGetFunction() 3271 @*/ 3272 PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 3273 { 3274 PetscErrorCode ierr; 3275 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3276 int nlhs = 2,nrhs = 6; 3277 mxArray *plhs[2],*prhs[6]; 3278 long long int lx = 0,lA = 0,ls = 0, lB = 0; 3279 3280 PetscFunctionBegin; 3281 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3282 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3283 3284 /* call Matlab function in ctx with arguments x and y */ 3285 3286 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3287 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3288 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 3289 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 3290 prhs[0] = mxCreateDoubleScalar((double)ls); 3291 prhs[1] = mxCreateDoubleScalar((double)lx); 3292 prhs[2] = mxCreateDoubleScalar((double)lA); 3293 prhs[3] = mxCreateDoubleScalar((double)lB); 3294 prhs[4] = mxCreateString(sctx->funcname); 3295 prhs[5] = sctx->ctx; 3296 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 3297 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3298 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 3299 mxDestroyArray(prhs[0]); 3300 mxDestroyArray(prhs[1]); 3301 mxDestroyArray(prhs[2]); 3302 mxDestroyArray(prhs[3]); 3303 mxDestroyArray(prhs[4]); 3304 mxDestroyArray(plhs[0]); 3305 mxDestroyArray(plhs[1]); 3306 PetscFunctionReturn(0); 3307 } 3308 3309 3310 #undef __FUNCT__ 3311 #define __FUNCT__ "SNESSetJacobianMatlab" 3312 /* 3313 SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 3314 vector for use by the SNES routines in solving systems of nonlinear 3315 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3316 3317 Logically Collective on SNES 3318 3319 Input Parameters: 3320 + snes - the SNES context 3321 . A,B - Jacobian matrices 3322 . func - function evaluation routine 3323 - ctx - user context 3324 3325 Calling sequence of func: 3326 $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 3327 3328 3329 Level: developer 3330 3331 .keywords: SNES, nonlinear, set, function 3332 3333 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3334 */ 3335 PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 3336 { 3337 PetscErrorCode ierr; 3338 SNESMatlabContext *sctx; 3339 3340 PetscFunctionBegin; 3341 /* currently sctx is memory bleed */ 3342 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3343 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3344 /* 3345 This should work, but it doesn't 3346 sctx->ctx = ctx; 3347 mexMakeArrayPersistent(sctx->ctx); 3348 */ 3349 sctx->ctx = mxDuplicateArray(ctx); 3350 ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 3351 PetscFunctionReturn(0); 3352 } 3353 3354 #undef __FUNCT__ 3355 #define __FUNCT__ "SNESMonitor_Matlab" 3356 /* 3357 SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 3358 3359 Collective on SNES 3360 3361 .seealso: SNESSetFunction(), SNESGetFunction() 3362 @*/ 3363 PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 3364 { 3365 PetscErrorCode ierr; 3366 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3367 int nlhs = 1,nrhs = 6; 3368 mxArray *plhs[1],*prhs[6]; 3369 long long int lx = 0,ls = 0; 3370 Vec x=snes->vec_sol; 3371 3372 PetscFunctionBegin; 3373 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3374 3375 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3376 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3377 prhs[0] = mxCreateDoubleScalar((double)ls); 3378 prhs[1] = mxCreateDoubleScalar((double)it); 3379 prhs[2] = mxCreateDoubleScalar((double)fnorm); 3380 prhs[3] = mxCreateDoubleScalar((double)lx); 3381 prhs[4] = mxCreateString(sctx->funcname); 3382 prhs[5] = sctx->ctx; 3383 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 3384 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3385 mxDestroyArray(prhs[0]); 3386 mxDestroyArray(prhs[1]); 3387 mxDestroyArray(prhs[2]); 3388 mxDestroyArray(prhs[3]); 3389 mxDestroyArray(prhs[4]); 3390 mxDestroyArray(plhs[0]); 3391 PetscFunctionReturn(0); 3392 } 3393 3394 3395 #undef __FUNCT__ 3396 #define __FUNCT__ "SNESMonitorSetMatlab" 3397 /* 3398 SNESMonitorSetMatlab - Sets the monitor function from MATLAB 3399 3400 Level: developer 3401 3402 .keywords: SNES, nonlinear, set, function 3403 3404 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3405 */ 3406 PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 3407 { 3408 PetscErrorCode ierr; 3409 SNESMatlabContext *sctx; 3410 3411 PetscFunctionBegin; 3412 /* currently sctx is memory bleed */ 3413 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3414 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3415 /* 3416 This should work, but it doesn't 3417 sctx->ctx = ctx; 3418 mexMakeArrayPersistent(sctx->ctx); 3419 */ 3420 sctx->ctx = mxDuplicateArray(ctx); 3421 ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 3422 PetscFunctionReturn(0); 3423 } 3424 3425 #endif 3426