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