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