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