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