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->numLinearSolveFailures = 0; 1135 snes->maxLinearSolveFailures = 1; 1136 1137 /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 1138 ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 1139 snes->kspconvctx = (void*)kctx; 1140 kctx->version = 2; 1141 kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 1142 this was too large for some test cases */ 1143 kctx->rtol_last = 0.0; 1144 kctx->rtol_max = .9; 1145 kctx->gamma = 1.0; 1146 kctx->alpha = .5*(1.0 + sqrt(5.0)); 1147 kctx->alpha2 = kctx->alpha; 1148 kctx->threshold = .1; 1149 kctx->lresid_last = 0.0; 1150 kctx->norm_last = 0.0; 1151 1152 *outsnes = snes; 1153 PetscFunctionReturn(0); 1154 } 1155 1156 #undef __FUNCT__ 1157 #define __FUNCT__ "SNESSetFunction" 1158 /*@C 1159 SNESSetFunction - Sets the function evaluation routine and function 1160 vector for use by the SNES routines in solving systems of nonlinear 1161 equations. 1162 1163 Logically Collective on SNES 1164 1165 Input Parameters: 1166 + snes - the SNES context 1167 . r - vector to store function value 1168 . func - function evaluation routine 1169 - ctx - [optional] user-defined context for private data for the 1170 function evaluation routine (may be PETSC_NULL) 1171 1172 Calling sequence of func: 1173 $ func (SNES snes,Vec x,Vec f,void *ctx); 1174 1175 . f - function vector 1176 - ctx - optional user-defined function context 1177 1178 Notes: 1179 The Newton-like methods typically solve linear systems of the form 1180 $ f'(x) x = -f(x), 1181 where f'(x) denotes the Jacobian matrix and f(x) is the function. 1182 1183 Level: beginner 1184 1185 .keywords: SNES, nonlinear, set, function 1186 1187 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1188 @*/ 1189 PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 1190 { 1191 PetscErrorCode ierr; 1192 PetscFunctionBegin; 1193 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1194 if (r) { 1195 PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1196 PetscCheckSameComm(snes,1,r,2); 1197 ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 1198 ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 1199 snes->vec_func = r; 1200 } else if (!snes->vec_func && snes->dm) { 1201 ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1202 } 1203 if (func) snes->ops->computefunction = func; 1204 if (ctx) snes->funP = ctx; 1205 PetscFunctionReturn(0); 1206 } 1207 1208 #undef __FUNCT__ 1209 #define __FUNCT__ "SNESSetComputeInitialGuess" 1210 /*@C 1211 SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1212 1213 Logically Collective on SNES 1214 1215 Input Parameters: 1216 + snes - the SNES context 1217 . func - function evaluation routine 1218 - ctx - [optional] user-defined context for private data for the 1219 function evaluation routine (may be PETSC_NULL) 1220 1221 Calling sequence of func: 1222 $ func (SNES snes,Vec x,void *ctx); 1223 1224 . f - function vector 1225 - ctx - optional user-defined function context 1226 1227 Level: intermediate 1228 1229 .keywords: SNES, nonlinear, set, function 1230 1231 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1232 @*/ 1233 PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1234 { 1235 PetscFunctionBegin; 1236 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1237 if (func) snes->ops->computeinitialguess = func; 1238 if (ctx) snes->initialguessP = ctx; 1239 PetscFunctionReturn(0); 1240 } 1241 1242 /* --------------------------------------------------------------- */ 1243 #undef __FUNCT__ 1244 #define __FUNCT__ "SNESGetRhs" 1245 /*@C 1246 SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 1247 it assumes a zero right hand side. 1248 1249 Logically Collective on SNES 1250 1251 Input Parameter: 1252 . snes - the SNES context 1253 1254 Output Parameter: 1255 . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 1256 1257 Level: intermediate 1258 1259 .keywords: SNES, nonlinear, get, function, right hand side 1260 1261 .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 1262 @*/ 1263 PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 1264 { 1265 PetscFunctionBegin; 1266 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1267 PetscValidPointer(rhs,2); 1268 *rhs = snes->vec_rhs; 1269 PetscFunctionReturn(0); 1270 } 1271 1272 #undef __FUNCT__ 1273 #define __FUNCT__ "SNESComputeFunction" 1274 /*@ 1275 SNESComputeFunction - Calls the function that has been set with 1276 SNESSetFunction(). 1277 1278 Collective on SNES 1279 1280 Input Parameters: 1281 + snes - the SNES context 1282 - x - input vector 1283 1284 Output Parameter: 1285 . y - function vector, as set by SNESSetFunction() 1286 1287 Notes: 1288 SNESComputeFunction() is typically used within nonlinear solvers 1289 implementations, so most users would not generally call this routine 1290 themselves. 1291 1292 Level: developer 1293 1294 .keywords: SNES, nonlinear, compute, function 1295 1296 .seealso: SNESSetFunction(), SNESGetFunction() 1297 @*/ 1298 PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 1299 { 1300 PetscErrorCode ierr; 1301 1302 PetscFunctionBegin; 1303 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1304 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1305 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1306 PetscCheckSameComm(snes,1,x,2); 1307 PetscCheckSameComm(snes,1,y,3); 1308 1309 ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1310 if (snes->ops->computefunction) { 1311 PetscStackPush("SNES user function"); 1312 ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr); 1313 PetscStackPop; 1314 } else if (snes->dm) { 1315 ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1316 } else if (snes->vec_rhs) { 1317 ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1318 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 1319 if (snes->vec_rhs) { 1320 ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 1321 } 1322 snes->nfuncs++; 1323 ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1324 PetscFunctionReturn(0); 1325 } 1326 1327 #undef __FUNCT__ 1328 #define __FUNCT__ "SNESComputeJacobian" 1329 /*@ 1330 SNESComputeJacobian - Computes the Jacobian matrix that has been 1331 set with SNESSetJacobian(). 1332 1333 Collective on SNES and Mat 1334 1335 Input Parameters: 1336 + snes - the SNES context 1337 - x - input vector 1338 1339 Output Parameters: 1340 + A - Jacobian matrix 1341 . B - optional preconditioning matrix 1342 - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1343 1344 Options Database Keys: 1345 + -snes_lag_preconditioner <lag> 1346 . -snes_lag_jacobian <lag> 1347 . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1348 . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1349 . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 1350 - -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1351 1352 Notes: 1353 Most users should not need to explicitly call this routine, as it 1354 is used internally within the nonlinear solvers. 1355 1356 See KSPSetOperators() for important information about setting the 1357 flag parameter. 1358 1359 Level: developer 1360 1361 .keywords: SNES, compute, Jacobian, matrix 1362 1363 .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 1364 @*/ 1365 PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 1366 { 1367 PetscErrorCode ierr; 1368 PetscBool flag; 1369 1370 PetscFunctionBegin; 1371 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1372 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 1373 PetscValidPointer(flg,5); 1374 PetscCheckSameComm(snes,1,X,2); 1375 if (!snes->ops->computejacobian) PetscFunctionReturn(0); 1376 1377 /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1378 1379 if (snes->lagjacobian == -2) { 1380 snes->lagjacobian = -1; 1381 ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1382 } else if (snes->lagjacobian == -1) { 1383 *flg = SAME_PRECONDITIONER; 1384 ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1385 ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1386 if (flag) { 1387 ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1388 ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1389 } 1390 PetscFunctionReturn(0); 1391 } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1392 *flg = SAME_PRECONDITIONER; 1393 ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1394 ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1395 if (flag) { 1396 ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1397 ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1398 } 1399 PetscFunctionReturn(0); 1400 } 1401 1402 *flg = DIFFERENT_NONZERO_PATTERN; 1403 ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1404 PetscStackPush("SNES user Jacobian function"); 1405 ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr); 1406 PetscStackPop; 1407 ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1408 1409 if (snes->lagpreconditioner == -2) { 1410 ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 1411 snes->lagpreconditioner = -1; 1412 } else if (snes->lagpreconditioner == -1) { 1413 *flg = SAME_PRECONDITIONER; 1414 ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1415 } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1416 *flg = SAME_PRECONDITIONER; 1417 ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1418 } 1419 1420 /* make sure user returned a correct Jacobian and preconditioner */ 1421 /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 1422 PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1423 { 1424 PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1425 ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1426 ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1427 ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1428 ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1429 if (flag || flag_draw || flag_contour) { 1430 Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1431 MatStructure mstruct; 1432 PetscViewer vdraw,vstdout; 1433 PetscBool flg; 1434 if (flag_operator) { 1435 ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1436 Bexp = Bexp_mine; 1437 } else { 1438 /* See if the preconditioning matrix can be viewed and added directly */ 1439 ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1440 if (flg) Bexp = *B; 1441 else { 1442 /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1443 ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1444 Bexp = Bexp_mine; 1445 } 1446 } 1447 ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1448 ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1449 ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1450 if (flag_draw || flag_contour) { 1451 ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1452 if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1453 } else vdraw = PETSC_NULL; 1454 ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1455 if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1456 if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1457 ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1458 if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1459 if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1460 ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1461 ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1462 if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1463 if (vdraw) { /* Always use contour for the difference */ 1464 ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1465 ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1466 ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1467 } 1468 if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1469 ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1470 ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1471 ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1472 } 1473 } 1474 PetscFunctionReturn(0); 1475 } 1476 1477 #undef __FUNCT__ 1478 #define __FUNCT__ "SNESSetJacobian" 1479 /*@C 1480 SNESSetJacobian - Sets the function to compute Jacobian as well as the 1481 location to store the matrix. 1482 1483 Logically Collective on SNES and Mat 1484 1485 Input Parameters: 1486 + snes - the SNES context 1487 . A - Jacobian matrix 1488 . B - preconditioner matrix (usually same as the Jacobian) 1489 . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 1490 - ctx - [optional] user-defined context for private data for the 1491 Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 1492 1493 Calling sequence of func: 1494 $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 1495 1496 + x - input vector 1497 . A - Jacobian matrix 1498 . B - preconditioner matrix, usually the same as A 1499 . flag - flag indicating information about the preconditioner matrix 1500 structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 1501 - ctx - [optional] user-defined Jacobian context 1502 1503 Notes: 1504 See KSPSetOperators() for important information about setting the flag 1505 output parameter in the routine func(). Be sure to read this information! 1506 1507 The routine func() takes Mat * as the matrix arguments rather than Mat. 1508 This allows the Jacobian evaluation routine to replace A and/or B with a 1509 completely new new matrix structure (not just different matrix elements) 1510 when appropriate, for instance, if the nonzero structure is changing 1511 throughout the global iterations. 1512 1513 If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 1514 each matrix. 1515 1516 If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 1517 must be a MatFDColoring. 1518 1519 Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 1520 example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 1521 1522 Level: beginner 1523 1524 .keywords: SNES, nonlinear, set, Jacobian, matrix 1525 1526 .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 1527 @*/ 1528 PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 1529 { 1530 PetscErrorCode ierr; 1531 1532 PetscFunctionBegin; 1533 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1534 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 1535 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 1536 if (A) PetscCheckSameComm(snes,1,A,2); 1537 if (B) PetscCheckSameComm(snes,1,B,3); 1538 if (func) snes->ops->computejacobian = func; 1539 if (ctx) snes->jacP = ctx; 1540 if (A) { 1541 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 1542 ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 1543 snes->jacobian = A; 1544 } 1545 if (B) { 1546 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 1547 ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 1548 snes->jacobian_pre = B; 1549 } 1550 PetscFunctionReturn(0); 1551 } 1552 1553 #undef __FUNCT__ 1554 #define __FUNCT__ "SNESGetJacobian" 1555 /*@C 1556 SNESGetJacobian - Returns the Jacobian matrix and optionally the user 1557 provided context for evaluating the Jacobian. 1558 1559 Not Collective, but Mat object will be parallel if SNES object is 1560 1561 Input Parameter: 1562 . snes - the nonlinear solver context 1563 1564 Output Parameters: 1565 + A - location to stash Jacobian matrix (or PETSC_NULL) 1566 . B - location to stash preconditioner matrix (or PETSC_NULL) 1567 . func - location to put Jacobian function (or PETSC_NULL) 1568 - ctx - location to stash Jacobian ctx (or PETSC_NULL) 1569 1570 Level: advanced 1571 1572 .seealso: SNESSetJacobian(), SNESComputeJacobian() 1573 @*/ 1574 PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 1575 { 1576 PetscFunctionBegin; 1577 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1578 if (A) *A = snes->jacobian; 1579 if (B) *B = snes->jacobian_pre; 1580 if (func) *func = snes->ops->computejacobian; 1581 if (ctx) *ctx = snes->jacP; 1582 PetscFunctionReturn(0); 1583 } 1584 1585 /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 1586 1587 #undef __FUNCT__ 1588 #define __FUNCT__ "SNESSetUp" 1589 /*@ 1590 SNESSetUp - Sets up the internal data structures for the later use 1591 of a nonlinear solver. 1592 1593 Collective on SNES 1594 1595 Input Parameters: 1596 . snes - the SNES context 1597 1598 Notes: 1599 For basic use of the SNES solvers the user need not explicitly call 1600 SNESSetUp(), since these actions will automatically occur during 1601 the call to SNESSolve(). However, if one wishes to control this 1602 phase separately, SNESSetUp() should be called after SNESCreate() 1603 and optional routines of the form SNESSetXXX(), but before SNESSolve(). 1604 1605 Level: advanced 1606 1607 .keywords: SNES, nonlinear, setup 1608 1609 .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 1610 @*/ 1611 PetscErrorCode SNESSetUp(SNES snes) 1612 { 1613 PetscErrorCode ierr; 1614 1615 PetscFunctionBegin; 1616 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1617 if (snes->setupcalled) PetscFunctionReturn(0); 1618 1619 if (!((PetscObject)snes)->type_name) { 1620 ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 1621 } 1622 1623 if (!snes->vec_func) { 1624 if (snes->vec_rhs) { 1625 ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 1626 } else if (snes->vec_sol) { 1627 ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 1628 } else if (snes->dm) { 1629 ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1630 } 1631 } 1632 if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 1633 if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 1634 1635 if (!snes->vec_sol_update /* && snes->vec_sol */) { 1636 ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 1637 ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 1638 } 1639 1640 if (!snes->ops->computejacobian && snes->dm) { 1641 Mat J; 1642 ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1643 ierr = SNESSetJacobian(snes,J,J,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 1644 ierr = MatDestroy(&J);CHKERRQ(ierr); 1645 } else if (!snes->jacobian && snes->ops->computejacobian == MatMFFDComputeJacobian) { 1646 Mat J; 1647 ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 1648 ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 1649 ierr = MatSetFromOptions(J);CHKERRQ(ierr); 1650 ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 1651 ierr = MatDestroy(&J);CHKERRQ(ierr); 1652 } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 1653 Mat J,B; 1654 ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 1655 ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 1656 ierr = MatSetFromOptions(J);CHKERRQ(ierr); 1657 ierr = DMGetMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 1658 ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,snes->funP);CHKERRQ(ierr); 1659 ierr = MatDestroy(&J);CHKERRQ(ierr); 1660 ierr = MatDestroy(&B);CHKERRQ(ierr); 1661 } else if (snes->dm && !snes->jacobian_pre){ 1662 Mat J; 1663 ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1664 ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1665 ierr = MatDestroy(&J);CHKERRQ(ierr); 1666 } 1667 if (!snes->ops->computefunction && !snes->dm) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction() or call SNESSetDM()"); 1668 if (!snes->vec_func) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a vector when calling SNESSetFunction() or call SNESSetDM()"); 1669 1670 if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 1671 1672 if (snes->ops->usercompute && !snes->user) { 1673 ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 1674 } 1675 1676 if (snes->ops->setup) { 1677 ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 1678 } 1679 1680 snes->setupcalled = PETSC_TRUE; 1681 PetscFunctionReturn(0); 1682 } 1683 1684 #undef __FUNCT__ 1685 #define __FUNCT__ "SNESReset" 1686 /*@ 1687 SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 1688 1689 Collective on SNES 1690 1691 Input Parameter: 1692 . snes - iterative context obtained from SNESCreate() 1693 1694 Level: intermediate 1695 1696 Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 1697 1698 .keywords: SNES, destroy 1699 1700 .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 1701 @*/ 1702 PetscErrorCode SNESReset(SNES snes) 1703 { 1704 PetscErrorCode ierr; 1705 1706 PetscFunctionBegin; 1707 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1708 if (snes->ops->userdestroy && snes->user) { 1709 ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 1710 snes->user = PETSC_NULL; 1711 } 1712 if (snes->pc) { 1713 ierr = SNESReset(snes->pc);CHKERRQ(ierr); 1714 } 1715 1716 if (snes->ops->reset) { 1717 ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 1718 } 1719 if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 1720 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 1721 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 1722 ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 1723 ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 1724 ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 1725 ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 1726 if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 1727 if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);} 1728 snes->nwork = snes->nvwork = 0; 1729 snes->setupcalled = PETSC_FALSE; 1730 PetscFunctionReturn(0); 1731 } 1732 1733 #undef __FUNCT__ 1734 #define __FUNCT__ "SNESDestroy" 1735 /*@ 1736 SNESDestroy - Destroys the nonlinear solver context that was created 1737 with SNESCreate(). 1738 1739 Collective on SNES 1740 1741 Input Parameter: 1742 . snes - the SNES context 1743 1744 Level: beginner 1745 1746 .keywords: SNES, nonlinear, destroy 1747 1748 .seealso: SNESCreate(), SNESSolve() 1749 @*/ 1750 PetscErrorCode SNESDestroy(SNES *snes) 1751 { 1752 PetscErrorCode ierr; 1753 1754 PetscFunctionBegin; 1755 if (!*snes) PetscFunctionReturn(0); 1756 PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 1757 if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 1758 1759 ierr = SNESReset((*snes));CHKERRQ(ierr); 1760 ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 1761 1762 /* if memory was published with AMS then destroy it */ 1763 ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 1764 if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 1765 1766 ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 1767 ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 1768 1769 ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 1770 if ((*snes)->ops->convergeddestroy) { 1771 ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 1772 } 1773 if ((*snes)->conv_malloc) { 1774 ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 1775 ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 1776 } 1777 ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr); 1778 ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 1779 ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 1780 PetscFunctionReturn(0); 1781 } 1782 1783 /* ----------- Routines to set solver parameters ---------- */ 1784 1785 #undef __FUNCT__ 1786 #define __FUNCT__ "SNESSetLagPreconditioner" 1787 /*@ 1788 SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 1789 1790 Logically Collective on SNES 1791 1792 Input Parameters: 1793 + snes - the SNES context 1794 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1795 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1796 1797 Options Database Keys: 1798 . -snes_lag_preconditioner <lag> 1799 1800 Notes: 1801 The default is 1 1802 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1803 If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 1804 1805 Level: intermediate 1806 1807 .keywords: SNES, nonlinear, set, convergence, tolerances 1808 1809 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1810 1811 @*/ 1812 PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 1813 { 1814 PetscFunctionBegin; 1815 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1816 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1817 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1818 PetscValidLogicalCollectiveInt(snes,lag,2); 1819 snes->lagpreconditioner = lag; 1820 PetscFunctionReturn(0); 1821 } 1822 1823 #undef __FUNCT__ 1824 #define __FUNCT__ "SNESSetGridSequence" 1825 /*@ 1826 SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 1827 1828 Logically Collective on SNES 1829 1830 Input Parameters: 1831 + snes - the SNES context 1832 - steps - the number of refinements to do, defaults to 0 1833 1834 Options Database Keys: 1835 . -snes_grid_sequence <steps> 1836 1837 Level: intermediate 1838 1839 .keywords: SNES, nonlinear, set, convergence, tolerances 1840 1841 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1842 1843 @*/ 1844 PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 1845 { 1846 PetscFunctionBegin; 1847 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1848 PetscValidLogicalCollectiveInt(snes,steps,2); 1849 snes->gridsequence = steps; 1850 PetscFunctionReturn(0); 1851 } 1852 1853 #undef __FUNCT__ 1854 #define __FUNCT__ "SNESGetLagPreconditioner" 1855 /*@ 1856 SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 1857 1858 Not Collective 1859 1860 Input Parameter: 1861 . snes - the SNES context 1862 1863 Output Parameter: 1864 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1865 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1866 1867 Options Database Keys: 1868 . -snes_lag_preconditioner <lag> 1869 1870 Notes: 1871 The default is 1 1872 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1873 1874 Level: intermediate 1875 1876 .keywords: SNES, nonlinear, set, convergence, tolerances 1877 1878 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 1879 1880 @*/ 1881 PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 1882 { 1883 PetscFunctionBegin; 1884 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1885 *lag = snes->lagpreconditioner; 1886 PetscFunctionReturn(0); 1887 } 1888 1889 #undef __FUNCT__ 1890 #define __FUNCT__ "SNESSetLagJacobian" 1891 /*@ 1892 SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 1893 often the preconditioner is rebuilt. 1894 1895 Logically Collective on SNES 1896 1897 Input Parameters: 1898 + snes - the SNES context 1899 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1900 the Jacobian is built etc. -2 means rebuild at next chance but then never again 1901 1902 Options Database Keys: 1903 . -snes_lag_jacobian <lag> 1904 1905 Notes: 1906 The default is 1 1907 The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1908 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 1909 at the next Newton step but never again (unless it is reset to another value) 1910 1911 Level: intermediate 1912 1913 .keywords: SNES, nonlinear, set, convergence, tolerances 1914 1915 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 1916 1917 @*/ 1918 PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 1919 { 1920 PetscFunctionBegin; 1921 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1922 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1923 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1924 PetscValidLogicalCollectiveInt(snes,lag,2); 1925 snes->lagjacobian = lag; 1926 PetscFunctionReturn(0); 1927 } 1928 1929 #undef __FUNCT__ 1930 #define __FUNCT__ "SNESGetLagJacobian" 1931 /*@ 1932 SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 1933 1934 Not Collective 1935 1936 Input Parameter: 1937 . snes - the SNES context 1938 1939 Output Parameter: 1940 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1941 the Jacobian is built etc. 1942 1943 Options Database Keys: 1944 . -snes_lag_jacobian <lag> 1945 1946 Notes: 1947 The default is 1 1948 The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1949 1950 Level: intermediate 1951 1952 .keywords: SNES, nonlinear, set, convergence, tolerances 1953 1954 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 1955 1956 @*/ 1957 PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 1958 { 1959 PetscFunctionBegin; 1960 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1961 *lag = snes->lagjacobian; 1962 PetscFunctionReturn(0); 1963 } 1964 1965 #undef __FUNCT__ 1966 #define __FUNCT__ "SNESSetTolerances" 1967 /*@ 1968 SNESSetTolerances - Sets various parameters used in convergence tests. 1969 1970 Logically Collective on SNES 1971 1972 Input Parameters: 1973 + snes - the SNES context 1974 . abstol - absolute convergence tolerance 1975 . rtol - relative convergence tolerance 1976 . stol - convergence tolerance in terms of the norm 1977 of the change in the solution between steps 1978 . maxit - maximum number of iterations 1979 - maxf - maximum number of function evaluations 1980 1981 Options Database Keys: 1982 + -snes_atol <abstol> - Sets abstol 1983 . -snes_rtol <rtol> - Sets rtol 1984 . -snes_stol <stol> - Sets stol 1985 . -snes_max_it <maxit> - Sets maxit 1986 - -snes_max_funcs <maxf> - Sets maxf 1987 1988 Notes: 1989 The default maximum number of iterations is 50. 1990 The default maximum number of function evaluations is 1000. 1991 1992 Level: intermediate 1993 1994 .keywords: SNES, nonlinear, set, convergence, tolerances 1995 1996 .seealso: SNESSetTrustRegionTolerance() 1997 @*/ 1998 PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 1999 { 2000 PetscFunctionBegin; 2001 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2002 PetscValidLogicalCollectiveReal(snes,abstol,2); 2003 PetscValidLogicalCollectiveReal(snes,rtol,3); 2004 PetscValidLogicalCollectiveReal(snes,stol,4); 2005 PetscValidLogicalCollectiveInt(snes,maxit,5); 2006 PetscValidLogicalCollectiveInt(snes,maxf,6); 2007 2008 if (abstol != PETSC_DEFAULT) { 2009 if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2010 snes->abstol = abstol; 2011 } 2012 if (rtol != PETSC_DEFAULT) { 2013 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); 2014 snes->rtol = rtol; 2015 } 2016 if (stol != PETSC_DEFAULT) { 2017 if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2018 snes->xtol = stol; 2019 } 2020 if (maxit != PETSC_DEFAULT) { 2021 if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2022 snes->max_its = maxit; 2023 } 2024 if (maxf != PETSC_DEFAULT) { 2025 if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2026 snes->max_funcs = maxf; 2027 } 2028 PetscFunctionReturn(0); 2029 } 2030 2031 #undef __FUNCT__ 2032 #define __FUNCT__ "SNESGetTolerances" 2033 /*@ 2034 SNESGetTolerances - Gets various parameters used in convergence tests. 2035 2036 Not Collective 2037 2038 Input Parameters: 2039 + snes - the SNES context 2040 . atol - absolute convergence tolerance 2041 . rtol - relative convergence tolerance 2042 . stol - convergence tolerance in terms of the norm 2043 of the change in the solution between steps 2044 . maxit - maximum number of iterations 2045 - maxf - maximum number of function evaluations 2046 2047 Notes: 2048 The user can specify PETSC_NULL for any parameter that is not needed. 2049 2050 Level: intermediate 2051 2052 .keywords: SNES, nonlinear, get, convergence, tolerances 2053 2054 .seealso: SNESSetTolerances() 2055 @*/ 2056 PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 2057 { 2058 PetscFunctionBegin; 2059 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2060 if (atol) *atol = snes->abstol; 2061 if (rtol) *rtol = snes->rtol; 2062 if (stol) *stol = snes->xtol; 2063 if (maxit) *maxit = snes->max_its; 2064 if (maxf) *maxf = snes->max_funcs; 2065 PetscFunctionReturn(0); 2066 } 2067 2068 #undef __FUNCT__ 2069 #define __FUNCT__ "SNESSetTrustRegionTolerance" 2070 /*@ 2071 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 2072 2073 Logically Collective on SNES 2074 2075 Input Parameters: 2076 + snes - the SNES context 2077 - tol - tolerance 2078 2079 Options Database Key: 2080 . -snes_trtol <tol> - Sets tol 2081 2082 Level: intermediate 2083 2084 .keywords: SNES, nonlinear, set, trust region, tolerance 2085 2086 .seealso: SNESSetTolerances() 2087 @*/ 2088 PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 2089 { 2090 PetscFunctionBegin; 2091 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2092 PetscValidLogicalCollectiveReal(snes,tol,2); 2093 snes->deltatol = tol; 2094 PetscFunctionReturn(0); 2095 } 2096 2097 /* 2098 Duplicate the lg monitors for SNES from KSP; for some reason with 2099 dynamic libraries things don't work under Sun4 if we just use 2100 macros instead of functions 2101 */ 2102 #undef __FUNCT__ 2103 #define __FUNCT__ "SNESMonitorLG" 2104 PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2105 { 2106 PetscErrorCode ierr; 2107 2108 PetscFunctionBegin; 2109 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2110 ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2111 PetscFunctionReturn(0); 2112 } 2113 2114 #undef __FUNCT__ 2115 #define __FUNCT__ "SNESMonitorLGCreate" 2116 PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2117 { 2118 PetscErrorCode ierr; 2119 2120 PetscFunctionBegin; 2121 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2122 PetscFunctionReturn(0); 2123 } 2124 2125 #undef __FUNCT__ 2126 #define __FUNCT__ "SNESMonitorLGDestroy" 2127 PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2128 { 2129 PetscErrorCode ierr; 2130 2131 PetscFunctionBegin; 2132 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2133 PetscFunctionReturn(0); 2134 } 2135 2136 extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2137 #undef __FUNCT__ 2138 #define __FUNCT__ "SNESMonitorLGRange" 2139 PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2140 { 2141 PetscDrawLG lg; 2142 PetscErrorCode ierr; 2143 PetscReal x,y,per; 2144 PetscViewer v = (PetscViewer)monctx; 2145 static PetscReal prev; /* should be in the context */ 2146 PetscDraw draw; 2147 PetscFunctionBegin; 2148 if (!monctx) { 2149 MPI_Comm comm; 2150 2151 ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2152 v = PETSC_VIEWER_DRAW_(comm); 2153 } 2154 ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2155 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2156 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2157 ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2158 x = (PetscReal) n; 2159 if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2160 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2161 if (n < 20 || !(n % 5)) { 2162 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2163 } 2164 2165 ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2166 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2167 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2168 ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2169 ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2170 x = (PetscReal) n; 2171 y = 100.0*per; 2172 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2173 if (n < 20 || !(n % 5)) { 2174 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2175 } 2176 2177 ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2178 if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2179 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2180 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2181 x = (PetscReal) n; 2182 y = (prev - rnorm)/prev; 2183 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2184 if (n < 20 || !(n % 5)) { 2185 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2186 } 2187 2188 ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2189 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2190 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2191 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2192 x = (PetscReal) n; 2193 y = (prev - rnorm)/(prev*per); 2194 if (n > 2) { /*skip initial crazy value */ 2195 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2196 } 2197 if (n < 20 || !(n % 5)) { 2198 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2199 } 2200 prev = rnorm; 2201 PetscFunctionReturn(0); 2202 } 2203 2204 #undef __FUNCT__ 2205 #define __FUNCT__ "SNESMonitorLGRangeCreate" 2206 PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2207 { 2208 PetscErrorCode ierr; 2209 2210 PetscFunctionBegin; 2211 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2212 PetscFunctionReturn(0); 2213 } 2214 2215 #undef __FUNCT__ 2216 #define __FUNCT__ "SNESMonitorLGRangeDestroy" 2217 PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2218 { 2219 PetscErrorCode ierr; 2220 2221 PetscFunctionBegin; 2222 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2223 PetscFunctionReturn(0); 2224 } 2225 2226 #undef __FUNCT__ 2227 #define __FUNCT__ "SNESMonitor" 2228 /*@ 2229 SNESMonitor - runs the user provided monitor routines, if they exist 2230 2231 Collective on SNES 2232 2233 Input Parameters: 2234 + snes - nonlinear solver context obtained from SNESCreate() 2235 . iter - iteration number 2236 - rnorm - relative norm of the residual 2237 2238 Notes: 2239 This routine is called by the SNES implementations. 2240 It does not typically need to be called by the user. 2241 2242 Level: developer 2243 2244 .seealso: SNESMonitorSet() 2245 @*/ 2246 PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 2247 { 2248 PetscErrorCode ierr; 2249 PetscInt i,n = snes->numbermonitors; 2250 2251 PetscFunctionBegin; 2252 for (i=0; i<n; i++) { 2253 ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 2254 } 2255 PetscFunctionReturn(0); 2256 } 2257 2258 /* ------------ Routines to set performance monitoring options ----------- */ 2259 2260 #undef __FUNCT__ 2261 #define __FUNCT__ "SNESMonitorSet" 2262 /*@C 2263 SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 2264 iteration of the nonlinear solver to display the iteration's 2265 progress. 2266 2267 Logically Collective on SNES 2268 2269 Input Parameters: 2270 + snes - the SNES context 2271 . func - monitoring routine 2272 . mctx - [optional] user-defined context for private data for the 2273 monitor routine (use PETSC_NULL if no context is desired) 2274 - monitordestroy - [optional] routine that frees monitor context 2275 (may be PETSC_NULL) 2276 2277 Calling sequence of func: 2278 $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2279 2280 + snes - the SNES context 2281 . its - iteration number 2282 . norm - 2-norm function value (may be estimated) 2283 - mctx - [optional] monitoring context 2284 2285 Options Database Keys: 2286 + -snes_monitor - sets SNESMonitorDefault() 2287 . -snes_monitor_draw - sets line graph monitor, 2288 uses SNESMonitorLGCreate() 2289 - -snes_monitor_cancel - cancels all monitors that have 2290 been hardwired into a code by 2291 calls to SNESMonitorSet(), but 2292 does not cancel those set via 2293 the options database. 2294 2295 Notes: 2296 Several different monitoring routines may be set by calling 2297 SNESMonitorSet() multiple times; all will be called in the 2298 order in which they were set. 2299 2300 Fortran notes: Only a single monitor function can be set for each SNES object 2301 2302 Level: intermediate 2303 2304 .keywords: SNES, nonlinear, set, monitor 2305 2306 .seealso: SNESMonitorDefault(), SNESMonitorCancel() 2307 @*/ 2308 PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 2309 { 2310 PetscInt i; 2311 PetscErrorCode ierr; 2312 2313 PetscFunctionBegin; 2314 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2315 if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2316 for (i=0; i<snes->numbermonitors;i++) { 2317 if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2318 if (monitordestroy) { 2319 ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2320 } 2321 PetscFunctionReturn(0); 2322 } 2323 } 2324 snes->monitor[snes->numbermonitors] = monitor; 2325 snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2326 snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 2327 PetscFunctionReturn(0); 2328 } 2329 2330 #undef __FUNCT__ 2331 #define __FUNCT__ "SNESMonitorCancel" 2332 /*@C 2333 SNESMonitorCancel - Clears all the monitor functions for a SNES object. 2334 2335 Logically Collective on SNES 2336 2337 Input Parameters: 2338 . snes - the SNES context 2339 2340 Options Database Key: 2341 . -snes_monitor_cancel - cancels all monitors that have been hardwired 2342 into a code by calls to SNESMonitorSet(), but does not cancel those 2343 set via the options database 2344 2345 Notes: 2346 There is no way to clear one specific monitor from a SNES object. 2347 2348 Level: intermediate 2349 2350 .keywords: SNES, nonlinear, set, monitor 2351 2352 .seealso: SNESMonitorDefault(), SNESMonitorSet() 2353 @*/ 2354 PetscErrorCode SNESMonitorCancel(SNES snes) 2355 { 2356 PetscErrorCode ierr; 2357 PetscInt i; 2358 2359 PetscFunctionBegin; 2360 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2361 for (i=0; i<snes->numbermonitors; i++) { 2362 if (snes->monitordestroy[i]) { 2363 ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2364 } 2365 } 2366 snes->numbermonitors = 0; 2367 PetscFunctionReturn(0); 2368 } 2369 2370 #undef __FUNCT__ 2371 #define __FUNCT__ "SNESSetConvergenceTest" 2372 /*@C 2373 SNESSetConvergenceTest - Sets the function that is to be used 2374 to test for convergence of the nonlinear iterative solution. 2375 2376 Logically Collective on SNES 2377 2378 Input Parameters: 2379 + snes - the SNES context 2380 . func - routine to test for convergence 2381 . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 2382 - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 2383 2384 Calling sequence of func: 2385 $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2386 2387 + snes - the SNES context 2388 . it - current iteration (0 is the first and is before any Newton step) 2389 . cctx - [optional] convergence context 2390 . reason - reason for convergence/divergence 2391 . xnorm - 2-norm of current iterate 2392 . gnorm - 2-norm of current step 2393 - f - 2-norm of function 2394 2395 Level: advanced 2396 2397 .keywords: SNES, nonlinear, set, convergence, test 2398 2399 .seealso: SNESDefaultConverged(), SNESSkipConverged() 2400 @*/ 2401 PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 2402 { 2403 PetscErrorCode ierr; 2404 2405 PetscFunctionBegin; 2406 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2407 if (!func) func = SNESSkipConverged; 2408 if (snes->ops->convergeddestroy) { 2409 ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 2410 } 2411 snes->ops->converged = func; 2412 snes->ops->convergeddestroy = destroy; 2413 snes->cnvP = cctx; 2414 PetscFunctionReturn(0); 2415 } 2416 2417 #undef __FUNCT__ 2418 #define __FUNCT__ "SNESGetConvergedReason" 2419 /*@ 2420 SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2421 2422 Not Collective 2423 2424 Input Parameter: 2425 . snes - the SNES context 2426 2427 Output Parameter: 2428 . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2429 manual pages for the individual convergence tests for complete lists 2430 2431 Level: intermediate 2432 2433 Notes: Can only be called after the call the SNESSolve() is complete. 2434 2435 .keywords: SNES, nonlinear, set, convergence, test 2436 2437 .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2438 @*/ 2439 PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2440 { 2441 PetscFunctionBegin; 2442 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2443 PetscValidPointer(reason,2); 2444 *reason = snes->reason; 2445 PetscFunctionReturn(0); 2446 } 2447 2448 #undef __FUNCT__ 2449 #define __FUNCT__ "SNESSetConvergenceHistory" 2450 /*@ 2451 SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2452 2453 Logically Collective on SNES 2454 2455 Input Parameters: 2456 + snes - iterative context obtained from SNESCreate() 2457 . a - array to hold history, this array will contain the function norms computed at each step 2458 . its - integer array holds the number of linear iterations for each solve. 2459 . na - size of a and its 2460 - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2461 else it continues storing new values for new nonlinear solves after the old ones 2462 2463 Notes: 2464 If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2465 default array of length 10000 is allocated. 2466 2467 This routine is useful, e.g., when running a code for purposes 2468 of accurate performance monitoring, when no I/O should be done 2469 during the section of code that is being timed. 2470 2471 Level: intermediate 2472 2473 .keywords: SNES, set, convergence, history 2474 2475 .seealso: SNESGetConvergenceHistory() 2476 2477 @*/ 2478 PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2479 { 2480 PetscErrorCode ierr; 2481 2482 PetscFunctionBegin; 2483 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2484 if (na) PetscValidScalarPointer(a,2); 2485 if (its) PetscValidIntPointer(its,3); 2486 if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2487 if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2488 ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2489 ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2490 snes->conv_malloc = PETSC_TRUE; 2491 } 2492 snes->conv_hist = a; 2493 snes->conv_hist_its = its; 2494 snes->conv_hist_max = na; 2495 snes->conv_hist_len = 0; 2496 snes->conv_hist_reset = reset; 2497 PetscFunctionReturn(0); 2498 } 2499 2500 #if defined(PETSC_HAVE_MATLAB_ENGINE) 2501 #include <engine.h> /* MATLAB include file */ 2502 #include <mex.h> /* MATLAB include file */ 2503 EXTERN_C_BEGIN 2504 #undef __FUNCT__ 2505 #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2506 mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2507 { 2508 mxArray *mat; 2509 PetscInt i; 2510 PetscReal *ar; 2511 2512 PetscFunctionBegin; 2513 mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2514 ar = (PetscReal*) mxGetData(mat); 2515 for (i=0; i<snes->conv_hist_len; i++) { 2516 ar[i] = snes->conv_hist[i]; 2517 } 2518 PetscFunctionReturn(mat); 2519 } 2520 EXTERN_C_END 2521 #endif 2522 2523 2524 #undef __FUNCT__ 2525 #define __FUNCT__ "SNESGetConvergenceHistory" 2526 /*@C 2527 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 2528 2529 Not Collective 2530 2531 Input Parameter: 2532 . snes - iterative context obtained from SNESCreate() 2533 2534 Output Parameters: 2535 . a - array to hold history 2536 . its - integer array holds the number of linear iterations (or 2537 negative if not converged) for each solve. 2538 - na - size of a and its 2539 2540 Notes: 2541 The calling sequence for this routine in Fortran is 2542 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 2543 2544 This routine is useful, e.g., when running a code for purposes 2545 of accurate performance monitoring, when no I/O should be done 2546 during the section of code that is being timed. 2547 2548 Level: intermediate 2549 2550 .keywords: SNES, get, convergence, history 2551 2552 .seealso: SNESSetConvergencHistory() 2553 2554 @*/ 2555 PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 2556 { 2557 PetscFunctionBegin; 2558 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2559 if (a) *a = snes->conv_hist; 2560 if (its) *its = snes->conv_hist_its; 2561 if (na) *na = snes->conv_hist_len; 2562 PetscFunctionReturn(0); 2563 } 2564 2565 #undef __FUNCT__ 2566 #define __FUNCT__ "SNESSetUpdate" 2567 /*@C 2568 SNESSetUpdate - Sets the general-purpose update function called 2569 at the beginning of every iteration of the nonlinear solve. Specifically 2570 it is called just before the Jacobian is "evaluated". 2571 2572 Logically Collective on SNES 2573 2574 Input Parameters: 2575 . snes - The nonlinear solver context 2576 . func - The function 2577 2578 Calling sequence of func: 2579 . func (SNES snes, PetscInt step); 2580 2581 . step - The current step of the iteration 2582 2583 Level: advanced 2584 2585 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() 2586 This is not used by most users. 2587 2588 .keywords: SNES, update 2589 2590 .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 2591 @*/ 2592 PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 2593 { 2594 PetscFunctionBegin; 2595 PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 2596 snes->ops->update = func; 2597 PetscFunctionReturn(0); 2598 } 2599 2600 #undef __FUNCT__ 2601 #define __FUNCT__ "SNESDefaultUpdate" 2602 /*@ 2603 SNESDefaultUpdate - The default update function which does nothing. 2604 2605 Not collective 2606 2607 Input Parameters: 2608 . snes - The nonlinear solver context 2609 . step - The current step of the iteration 2610 2611 Level: intermediate 2612 2613 .keywords: SNES, update 2614 .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 2615 @*/ 2616 PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 2617 { 2618 PetscFunctionBegin; 2619 PetscFunctionReturn(0); 2620 } 2621 2622 #undef __FUNCT__ 2623 #define __FUNCT__ "SNESScaleStep_Private" 2624 /* 2625 SNESScaleStep_Private - Scales a step so that its length is less than the 2626 positive parameter delta. 2627 2628 Input Parameters: 2629 + snes - the SNES context 2630 . y - approximate solution of linear system 2631 . fnorm - 2-norm of current function 2632 - delta - trust region size 2633 2634 Output Parameters: 2635 + gpnorm - predicted function norm at the new point, assuming local 2636 linearization. The value is zero if the step lies within the trust 2637 region, and exceeds zero otherwise. 2638 - ynorm - 2-norm of the step 2639 2640 Note: 2641 For non-trust region methods such as SNESLS, the parameter delta 2642 is set to be the maximum allowable step size. 2643 2644 .keywords: SNES, nonlinear, scale, step 2645 */ 2646 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 2647 { 2648 PetscReal nrm; 2649 PetscScalar cnorm; 2650 PetscErrorCode ierr; 2651 2652 PetscFunctionBegin; 2653 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2654 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 2655 PetscCheckSameComm(snes,1,y,2); 2656 2657 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 2658 if (nrm > *delta) { 2659 nrm = *delta/nrm; 2660 *gpnorm = (1.0 - nrm)*(*fnorm); 2661 cnorm = nrm; 2662 ierr = VecScale(y,cnorm);CHKERRQ(ierr); 2663 *ynorm = *delta; 2664 } else { 2665 *gpnorm = 0.0; 2666 *ynorm = nrm; 2667 } 2668 PetscFunctionReturn(0); 2669 } 2670 2671 #undef __FUNCT__ 2672 #define __FUNCT__ "SNESSolve" 2673 /*@C 2674 SNESSolve - Solves a nonlinear system F(x) = b. 2675 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 2676 2677 Collective on SNES 2678 2679 Input Parameters: 2680 + snes - the SNES context 2681 . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 2682 - x - the solution vector. 2683 2684 Notes: 2685 The user should initialize the vector,x, with the initial guess 2686 for the nonlinear solve prior to calling SNESSolve. In particular, 2687 to employ an initial guess of zero, the user should explicitly set 2688 this vector to zero by calling VecSet(). 2689 2690 Level: beginner 2691 2692 .keywords: SNES, nonlinear, solve 2693 2694 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian() 2695 @*/ 2696 PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 2697 { 2698 PetscErrorCode ierr; 2699 PetscBool flg; 2700 char filename[PETSC_MAX_PATH_LEN]; 2701 PetscViewer viewer; 2702 PetscInt grid; 2703 2704 PetscFunctionBegin; 2705 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2706 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2707 PetscCheckSameComm(snes,1,x,3); 2708 if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 2709 if (b) PetscCheckSameComm(snes,1,b,2); 2710 2711 for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 2712 for (grid=0; grid<snes->gridsequence+1; grid++) { 2713 2714 /* set solution vector */ 2715 if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 2716 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 2717 snes->vec_sol = x; 2718 /* set afine vector if provided */ 2719 if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 2720 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 2721 snes->vec_rhs = b; 2722 2723 ierr = SNESSetUp(snes);CHKERRQ(ierr); 2724 2725 if (!grid && snes->ops->computeinitialguess) { 2726 ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 2727 } 2728 2729 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 2730 snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 2731 2732 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 2733 ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 2734 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 2735 if (snes->domainerror){ 2736 snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 2737 snes->domainerror = PETSC_FALSE; 2738 } 2739 if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 2740 2741 ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 2742 if (flg && !PetscPreLoadingOn) { 2743 ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 2744 ierr = SNESView(snes,viewer);CHKERRQ(ierr); 2745 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2746 } 2747 2748 flg = PETSC_FALSE; 2749 ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 2750 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 2751 if (snes->printreason) { 2752 ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 2753 if (snes->reason > 0) { 2754 ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 2755 } else { 2756 ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 2757 } 2758 ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 2759 } 2760 2761 flg = PETSC_FALSE; 2762 ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 2763 if (flg) { 2764 PetscViewer viewer; 2765 ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 2766 ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 2767 ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 2768 ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 2769 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2770 } 2771 2772 if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 2773 if (grid < snes->gridsequence) { 2774 DM fine; 2775 Vec xnew; 2776 Mat interp; 2777 2778 ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 2779 ierr = DMGetInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 2780 ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 2781 ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 2782 ierr = MatDestroy(&interp);CHKERRQ(ierr); 2783 x = xnew; 2784 2785 ierr = SNESReset(snes);CHKERRQ(ierr); 2786 ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 2787 ierr = DMDestroy(&fine);CHKERRQ(ierr); 2788 ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 2789 } 2790 } 2791 PetscFunctionReturn(0); 2792 } 2793 2794 /* --------- Internal routines for SNES Package --------- */ 2795 2796 #undef __FUNCT__ 2797 #define __FUNCT__ "SNESSetType" 2798 /*@C 2799 SNESSetType - Sets the method for the nonlinear solver. 2800 2801 Collective on SNES 2802 2803 Input Parameters: 2804 + snes - the SNES context 2805 - type - a known method 2806 2807 Options Database Key: 2808 . -snes_type <type> - Sets the method; use -help for a list 2809 of available methods (for instance, ls or tr) 2810 2811 Notes: 2812 See "petsc/include/petscsnes.h" for available methods (for instance) 2813 + SNESLS - Newton's method with line search 2814 (systems of nonlinear equations) 2815 . SNESTR - Newton's method with trust region 2816 (systems of nonlinear equations) 2817 2818 Normally, it is best to use the SNESSetFromOptions() command and then 2819 set the SNES solver type from the options database rather than by using 2820 this routine. Using the options database provides the user with 2821 maximum flexibility in evaluating the many nonlinear solvers. 2822 The SNESSetType() routine is provided for those situations where it 2823 is necessary to set the nonlinear solver independently of the command 2824 line or options database. This might be the case, for example, when 2825 the choice of solver changes during the execution of the program, 2826 and the user's application is taking responsibility for choosing the 2827 appropriate method. 2828 2829 Level: intermediate 2830 2831 .keywords: SNES, set, type 2832 2833 .seealso: SNESType, SNESCreate() 2834 2835 @*/ 2836 PetscErrorCode SNESSetType(SNES snes,const SNESType type) 2837 { 2838 PetscErrorCode ierr,(*r)(SNES); 2839 PetscBool match; 2840 2841 PetscFunctionBegin; 2842 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2843 PetscValidCharPointer(type,2); 2844 2845 ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 2846 if (match) PetscFunctionReturn(0); 2847 2848 ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 2849 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 2850 /* Destroy the previous private SNES context */ 2851 if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 2852 /* Reinitialize function pointers in SNESOps structure */ 2853 snes->ops->setup = 0; 2854 snes->ops->solve = 0; 2855 snes->ops->view = 0; 2856 snes->ops->setfromoptions = 0; 2857 snes->ops->destroy = 0; 2858 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 2859 snes->setupcalled = PETSC_FALSE; 2860 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 2861 ierr = (*r)(snes);CHKERRQ(ierr); 2862 #if defined(PETSC_HAVE_AMS) 2863 if (PetscAMSPublishAll) { 2864 ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 2865 } 2866 #endif 2867 PetscFunctionReturn(0); 2868 } 2869 2870 2871 /* --------------------------------------------------------------------- */ 2872 #undef __FUNCT__ 2873 #define __FUNCT__ "SNESRegisterDestroy" 2874 /*@ 2875 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 2876 registered by SNESRegisterDynamic(). 2877 2878 Not Collective 2879 2880 Level: advanced 2881 2882 .keywords: SNES, nonlinear, register, destroy 2883 2884 .seealso: SNESRegisterAll(), SNESRegisterAll() 2885 @*/ 2886 PetscErrorCode SNESRegisterDestroy(void) 2887 { 2888 PetscErrorCode ierr; 2889 2890 PetscFunctionBegin; 2891 ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 2892 SNESRegisterAllCalled = PETSC_FALSE; 2893 PetscFunctionReturn(0); 2894 } 2895 2896 #undef __FUNCT__ 2897 #define __FUNCT__ "SNESGetType" 2898 /*@C 2899 SNESGetType - Gets the SNES method type and name (as a string). 2900 2901 Not Collective 2902 2903 Input Parameter: 2904 . snes - nonlinear solver context 2905 2906 Output Parameter: 2907 . type - SNES method (a character string) 2908 2909 Level: intermediate 2910 2911 .keywords: SNES, nonlinear, get, type, name 2912 @*/ 2913 PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 2914 { 2915 PetscFunctionBegin; 2916 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2917 PetscValidPointer(type,2); 2918 *type = ((PetscObject)snes)->type_name; 2919 PetscFunctionReturn(0); 2920 } 2921 2922 #undef __FUNCT__ 2923 #define __FUNCT__ "SNESGetSolution" 2924 /*@ 2925 SNESGetSolution - Returns the vector where the approximate solution is 2926 stored. 2927 2928 Not Collective, but Vec is parallel if SNES is parallel 2929 2930 Input Parameter: 2931 . snes - the SNES context 2932 2933 Output Parameter: 2934 . x - the solution 2935 2936 Level: intermediate 2937 2938 .keywords: SNES, nonlinear, get, solution 2939 2940 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 2941 @*/ 2942 PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 2943 { 2944 PetscFunctionBegin; 2945 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2946 PetscValidPointer(x,2); 2947 *x = snes->vec_sol; 2948 PetscFunctionReturn(0); 2949 } 2950 2951 #undef __FUNCT__ 2952 #define __FUNCT__ "SNESGetSolutionUpdate" 2953 /*@ 2954 SNESGetSolutionUpdate - Returns the vector where the solution update is 2955 stored. 2956 2957 Not Collective, but Vec is parallel if SNES is parallel 2958 2959 Input Parameter: 2960 . snes - the SNES context 2961 2962 Output Parameter: 2963 . x - the solution update 2964 2965 Level: advanced 2966 2967 .keywords: SNES, nonlinear, get, solution, update 2968 2969 .seealso: SNESGetSolution(), SNESGetFunction() 2970 @*/ 2971 PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 2972 { 2973 PetscFunctionBegin; 2974 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2975 PetscValidPointer(x,2); 2976 *x = snes->vec_sol_update; 2977 PetscFunctionReturn(0); 2978 } 2979 2980 #undef __FUNCT__ 2981 #define __FUNCT__ "SNESGetFunction" 2982 /*@C 2983 SNESGetFunction - Returns the vector where the function is stored. 2984 2985 Not Collective, but Vec is parallel if SNES is parallel 2986 2987 Input Parameter: 2988 . snes - the SNES context 2989 2990 Output Parameter: 2991 + r - the function (or PETSC_NULL) 2992 . func - the function (or PETSC_NULL) 2993 - ctx - the function context (or PETSC_NULL) 2994 2995 Level: advanced 2996 2997 .keywords: SNES, nonlinear, get, function 2998 2999 .seealso: SNESSetFunction(), SNESGetSolution() 3000 @*/ 3001 PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 3002 { 3003 PetscFunctionBegin; 3004 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3005 if (r) *r = snes->vec_func; 3006 if (func) *func = snes->ops->computefunction; 3007 if (ctx) *ctx = snes->funP; 3008 PetscFunctionReturn(0); 3009 } 3010 3011 #undef __FUNCT__ 3012 #define __FUNCT__ "SNESSetOptionsPrefix" 3013 /*@C 3014 SNESSetOptionsPrefix - Sets the prefix used for searching for all 3015 SNES options in the database. 3016 3017 Logically Collective on SNES 3018 3019 Input Parameter: 3020 + snes - the SNES context 3021 - prefix - the prefix to prepend to all option names 3022 3023 Notes: 3024 A hyphen (-) must NOT be given at the beginning of the prefix name. 3025 The first character of all runtime options is AUTOMATICALLY the hyphen. 3026 3027 Level: advanced 3028 3029 .keywords: SNES, set, options, prefix, database 3030 3031 .seealso: SNESSetFromOptions() 3032 @*/ 3033 PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 3034 { 3035 PetscErrorCode ierr; 3036 3037 PetscFunctionBegin; 3038 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3039 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 3040 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 3041 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 3042 PetscFunctionReturn(0); 3043 } 3044 3045 #undef __FUNCT__ 3046 #define __FUNCT__ "SNESAppendOptionsPrefix" 3047 /*@C 3048 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3049 SNES options in the database. 3050 3051 Logically Collective on SNES 3052 3053 Input Parameters: 3054 + snes - the SNES context 3055 - prefix - the prefix to prepend to all option names 3056 3057 Notes: 3058 A hyphen (-) must NOT be given at the beginning of the prefix name. 3059 The first character of all runtime options is AUTOMATICALLY the hyphen. 3060 3061 Level: advanced 3062 3063 .keywords: SNES, append, options, prefix, database 3064 3065 .seealso: SNESGetOptionsPrefix() 3066 @*/ 3067 PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 3068 { 3069 PetscErrorCode ierr; 3070 3071 PetscFunctionBegin; 3072 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3073 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 3074 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 3075 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 3076 PetscFunctionReturn(0); 3077 } 3078 3079 #undef __FUNCT__ 3080 #define __FUNCT__ "SNESGetOptionsPrefix" 3081 /*@C 3082 SNESGetOptionsPrefix - Sets the prefix used for searching for all 3083 SNES options in the database. 3084 3085 Not Collective 3086 3087 Input Parameter: 3088 . snes - the SNES context 3089 3090 Output Parameter: 3091 . prefix - pointer to the prefix string used 3092 3093 Notes: On the fortran side, the user should pass in a string 'prefix' of 3094 sufficient length to hold the prefix. 3095 3096 Level: advanced 3097 3098 .keywords: SNES, get, options, prefix, database 3099 3100 .seealso: SNESAppendOptionsPrefix() 3101 @*/ 3102 PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 3103 { 3104 PetscErrorCode ierr; 3105 3106 PetscFunctionBegin; 3107 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3108 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 3109 PetscFunctionReturn(0); 3110 } 3111 3112 3113 #undef __FUNCT__ 3114 #define __FUNCT__ "SNESRegister" 3115 /*@C 3116 SNESRegister - See SNESRegisterDynamic() 3117 3118 Level: advanced 3119 @*/ 3120 PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3121 { 3122 char fullname[PETSC_MAX_PATH_LEN]; 3123 PetscErrorCode ierr; 3124 3125 PetscFunctionBegin; 3126 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3127 ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3128 PetscFunctionReturn(0); 3129 } 3130 3131 #undef __FUNCT__ 3132 #define __FUNCT__ "SNESTestLocalMin" 3133 PetscErrorCode SNESTestLocalMin(SNES snes) 3134 { 3135 PetscErrorCode ierr; 3136 PetscInt N,i,j; 3137 Vec u,uh,fh; 3138 PetscScalar value; 3139 PetscReal norm; 3140 3141 PetscFunctionBegin; 3142 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3143 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3144 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3145 3146 /* currently only works for sequential */ 3147 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3148 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3149 for (i=0; i<N; i++) { 3150 ierr = VecCopy(u,uh);CHKERRQ(ierr); 3151 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3152 for (j=-10; j<11; j++) { 3153 value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3154 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3155 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3156 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 3157 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3158 value = -value; 3159 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3160 } 3161 } 3162 ierr = VecDestroy(&uh);CHKERRQ(ierr); 3163 ierr = VecDestroy(&fh);CHKERRQ(ierr); 3164 PetscFunctionReturn(0); 3165 } 3166 3167 #undef __FUNCT__ 3168 #define __FUNCT__ "SNESKSPSetUseEW" 3169 /*@ 3170 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 3171 computing relative tolerance for linear solvers within an inexact 3172 Newton method. 3173 3174 Logically Collective on SNES 3175 3176 Input Parameters: 3177 + snes - SNES context 3178 - flag - PETSC_TRUE or PETSC_FALSE 3179 3180 Options Database: 3181 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 3182 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 3183 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 3184 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 3185 . -snes_ksp_ew_gamma <gamma> - Sets gamma 3186 . -snes_ksp_ew_alpha <alpha> - Sets alpha 3187 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 3188 - -snes_ksp_ew_threshold <threshold> - Sets threshold 3189 3190 Notes: 3191 Currently, the default is to use a constant relative tolerance for 3192 the inner linear solvers. Alternatively, one can use the 3193 Eisenstat-Walker method, where the relative convergence tolerance 3194 is reset at each Newton iteration according progress of the nonlinear 3195 solver. 3196 3197 Level: advanced 3198 3199 Reference: 3200 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 3201 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 3202 3203 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 3204 3205 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 3206 @*/ 3207 PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 3208 { 3209 PetscFunctionBegin; 3210 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3211 PetscValidLogicalCollectiveBool(snes,flag,2); 3212 snes->ksp_ewconv = flag; 3213 PetscFunctionReturn(0); 3214 } 3215 3216 #undef __FUNCT__ 3217 #define __FUNCT__ "SNESKSPGetUseEW" 3218 /*@ 3219 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 3220 for computing relative tolerance for linear solvers within an 3221 inexact Newton method. 3222 3223 Not Collective 3224 3225 Input Parameter: 3226 . snes - SNES context 3227 3228 Output Parameter: 3229 . flag - PETSC_TRUE or PETSC_FALSE 3230 3231 Notes: 3232 Currently, the default is to use a constant relative tolerance for 3233 the inner linear solvers. Alternatively, one can use the 3234 Eisenstat-Walker method, where the relative convergence tolerance 3235 is reset at each Newton iteration according progress of the nonlinear 3236 solver. 3237 3238 Level: advanced 3239 3240 Reference: 3241 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 3242 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 3243 3244 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 3245 3246 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 3247 @*/ 3248 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 3249 { 3250 PetscFunctionBegin; 3251 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3252 PetscValidPointer(flag,2); 3253 *flag = snes->ksp_ewconv; 3254 PetscFunctionReturn(0); 3255 } 3256 3257 #undef __FUNCT__ 3258 #define __FUNCT__ "SNESKSPSetParametersEW" 3259 /*@ 3260 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 3261 convergence criteria for the linear solvers within an inexact 3262 Newton method. 3263 3264 Logically Collective on SNES 3265 3266 Input Parameters: 3267 + snes - SNES context 3268 . version - version 1, 2 (default is 2) or 3 3269 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 3270 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 3271 . gamma - multiplicative factor for version 2 rtol computation 3272 (0 <= gamma2 <= 1) 3273 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 3274 . alpha2 - power for safeguard 3275 - threshold - threshold for imposing safeguard (0 < threshold < 1) 3276 3277 Note: 3278 Version 3 was contributed by Luis Chacon, June 2006. 3279 3280 Use PETSC_DEFAULT to retain the default for any of the parameters. 3281 3282 Level: advanced 3283 3284 Reference: 3285 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 3286 inexact Newton method", Utah State University Math. Stat. Dept. Res. 3287 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 3288 3289 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 3290 3291 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 3292 @*/ 3293 PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 3294 PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 3295 { 3296 SNESKSPEW *kctx; 3297 PetscFunctionBegin; 3298 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3299 kctx = (SNESKSPEW*)snes->kspconvctx; 3300 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3301 PetscValidLogicalCollectiveInt(snes,version,2); 3302 PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3303 PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3304 PetscValidLogicalCollectiveReal(snes,gamma,5); 3305 PetscValidLogicalCollectiveReal(snes,alpha,6); 3306 PetscValidLogicalCollectiveReal(snes,alpha2,7); 3307 PetscValidLogicalCollectiveReal(snes,threshold,8); 3308 3309 if (version != PETSC_DEFAULT) kctx->version = version; 3310 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 3311 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 3312 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 3313 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 3314 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 3315 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 3316 3317 if (kctx->version < 1 || kctx->version > 3) { 3318 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 3319 } 3320 if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3321 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 3322 } 3323 if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3324 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 3325 } 3326 if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3327 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 3328 } 3329 if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3330 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 3331 } 3332 if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3333 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 3334 } 3335 PetscFunctionReturn(0); 3336 } 3337 3338 #undef __FUNCT__ 3339 #define __FUNCT__ "SNESKSPGetParametersEW" 3340 /*@ 3341 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 3342 convergence criteria for the linear solvers within an inexact 3343 Newton method. 3344 3345 Not Collective 3346 3347 Input Parameters: 3348 snes - SNES context 3349 3350 Output Parameters: 3351 + version - version 1, 2 (default is 2) or 3 3352 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 3353 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 3354 . gamma - multiplicative factor for version 2 rtol computation 3355 (0 <= gamma2 <= 1) 3356 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 3357 . alpha2 - power for safeguard 3358 - threshold - threshold for imposing safeguard (0 < threshold < 1) 3359 3360 Level: advanced 3361 3362 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 3363 3364 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 3365 @*/ 3366 PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 3367 PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 3368 { 3369 SNESKSPEW *kctx; 3370 PetscFunctionBegin; 3371 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3372 kctx = (SNESKSPEW*)snes->kspconvctx; 3373 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3374 if(version) *version = kctx->version; 3375 if(rtol_0) *rtol_0 = kctx->rtol_0; 3376 if(rtol_max) *rtol_max = kctx->rtol_max; 3377 if(gamma) *gamma = kctx->gamma; 3378 if(alpha) *alpha = kctx->alpha; 3379 if(alpha2) *alpha2 = kctx->alpha2; 3380 if(threshold) *threshold = kctx->threshold; 3381 PetscFunctionReturn(0); 3382 } 3383 3384 #undef __FUNCT__ 3385 #define __FUNCT__ "SNESKSPEW_PreSolve" 3386 static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 3387 { 3388 PetscErrorCode ierr; 3389 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 3390 PetscReal rtol=PETSC_DEFAULT,stol; 3391 3392 PetscFunctionBegin; 3393 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3394 if (!snes->iter) { /* first time in, so use the original user rtol */ 3395 rtol = kctx->rtol_0; 3396 } else { 3397 if (kctx->version == 1) { 3398 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 3399 if (rtol < 0.0) rtol = -rtol; 3400 stol = pow(kctx->rtol_last,kctx->alpha2); 3401 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3402 } else if (kctx->version == 2) { 3403 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3404 stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 3405 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3406 } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 3407 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3408 /* safeguard: avoid sharp decrease of rtol */ 3409 stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 3410 stol = PetscMax(rtol,stol); 3411 rtol = PetscMin(kctx->rtol_0,stol); 3412 /* safeguard: avoid oversolving */ 3413 stol = kctx->gamma*(snes->ttol)/snes->norm; 3414 stol = PetscMax(rtol,stol); 3415 rtol = PetscMin(kctx->rtol_0,stol); 3416 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 3417 } 3418 /* safeguard: avoid rtol greater than one */ 3419 rtol = PetscMin(rtol,kctx->rtol_max); 3420 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 3421 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 3422 PetscFunctionReturn(0); 3423 } 3424 3425 #undef __FUNCT__ 3426 #define __FUNCT__ "SNESKSPEW_PostSolve" 3427 static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 3428 { 3429 PetscErrorCode ierr; 3430 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 3431 PCSide pcside; 3432 Vec lres; 3433 3434 PetscFunctionBegin; 3435 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3436 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 3437 ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 3438 if (kctx->version == 1) { 3439 ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 3440 if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 3441 /* KSP residual is true linear residual */ 3442 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 3443 } else { 3444 /* KSP residual is preconditioned residual */ 3445 /* compute true linear residual norm */ 3446 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 3447 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 3448 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 3449 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 3450 ierr = VecDestroy(&lres);CHKERRQ(ierr); 3451 } 3452 } 3453 PetscFunctionReturn(0); 3454 } 3455 3456 #undef __FUNCT__ 3457 #define __FUNCT__ "SNES_KSPSolve" 3458 PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 3459 { 3460 PetscErrorCode ierr; 3461 3462 PetscFunctionBegin; 3463 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3464 ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3465 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3466 PetscFunctionReturn(0); 3467 } 3468 3469 #undef __FUNCT__ 3470 #define __FUNCT__ "SNESSetDM" 3471 /*@ 3472 SNESSetDM - Sets the DM that may be used by some preconditioners 3473 3474 Logically Collective on SNES 3475 3476 Input Parameters: 3477 + snes - the preconditioner context 3478 - dm - the dm 3479 3480 Level: intermediate 3481 3482 3483 .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 3484 @*/ 3485 PetscErrorCode SNESSetDM(SNES snes,DM dm) 3486 { 3487 PetscErrorCode ierr; 3488 KSP ksp; 3489 3490 PetscFunctionBegin; 3491 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3492 if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 3493 ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 3494 snes->dm = dm; 3495 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3496 ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3497 ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 3498 if (snes->pc) { 3499 ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 3500 } 3501 PetscFunctionReturn(0); 3502 } 3503 3504 #undef __FUNCT__ 3505 #define __FUNCT__ "SNESGetDM" 3506 /*@ 3507 SNESGetDM - Gets the DM that may be used by some preconditioners 3508 3509 Not Collective but DM obtained is parallel on SNES 3510 3511 Input Parameter: 3512 . snes - the preconditioner context 3513 3514 Output Parameter: 3515 . dm - the dm 3516 3517 Level: intermediate 3518 3519 3520 .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 3521 @*/ 3522 PetscErrorCode SNESGetDM(SNES snes,DM *dm) 3523 { 3524 PetscFunctionBegin; 3525 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3526 *dm = snes->dm; 3527 PetscFunctionReturn(0); 3528 } 3529 3530 #undef __FUNCT__ 3531 #define __FUNCT__ "SNESSetPC" 3532 /*@ 3533 SNESSetPC - Sets the nonlinear preconditioner to be used. 3534 3535 Collective on SNES 3536 3537 Input Parameters: 3538 + snes - iterative context obtained from SNESCreate() 3539 - pc - the preconditioner object 3540 3541 Notes: 3542 Use SNESGetPC() to retrieve the preconditioner context (for example, 3543 to configure it using the API). 3544 3545 Level: developer 3546 3547 .keywords: SNES, set, precondition 3548 .seealso: SNESGetPC() 3549 @*/ 3550 PetscErrorCode SNESSetPC(SNES snes, SNES pc) 3551 { 3552 PetscErrorCode ierr; 3553 3554 PetscFunctionBegin; 3555 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3556 PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 3557 PetscCheckSameComm(snes, 1, pc, 2); 3558 ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 3559 ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 3560 snes->pc = pc; 3561 ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 3562 PetscFunctionReturn(0); 3563 } 3564 3565 #undef __FUNCT__ 3566 #define __FUNCT__ "SNESGetPC" 3567 /*@ 3568 SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 3569 3570 Not Collective 3571 3572 Input Parameter: 3573 . snes - iterative context obtained from SNESCreate() 3574 3575 Output Parameter: 3576 . pc - preconditioner context 3577 3578 Level: developer 3579 3580 .keywords: SNES, get, preconditioner 3581 .seealso: SNESSetPC() 3582 @*/ 3583 PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 3584 { 3585 PetscErrorCode ierr; 3586 3587 PetscFunctionBegin; 3588 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3589 PetscValidPointer(pc, 2); 3590 if (!snes->pc) { 3591 ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 3592 ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 3593 ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 3594 } 3595 *pc = snes->pc; 3596 PetscFunctionReturn(0); 3597 } 3598 3599 #if defined(PETSC_HAVE_MATLAB_ENGINE) 3600 #include <mex.h> 3601 3602 typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 3603 3604 #undef __FUNCT__ 3605 #define __FUNCT__ "SNESComputeFunction_Matlab" 3606 /* 3607 SNESComputeFunction_Matlab - Calls the function that has been set with 3608 SNESSetFunctionMatlab(). 3609 3610 Collective on SNES 3611 3612 Input Parameters: 3613 + snes - the SNES context 3614 - x - input vector 3615 3616 Output Parameter: 3617 . y - function vector, as set by SNESSetFunction() 3618 3619 Notes: 3620 SNESComputeFunction() is typically used within nonlinear solvers 3621 implementations, so most users would not generally call this routine 3622 themselves. 3623 3624 Level: developer 3625 3626 .keywords: SNES, nonlinear, compute, function 3627 3628 .seealso: SNESSetFunction(), SNESGetFunction() 3629 */ 3630 PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 3631 { 3632 PetscErrorCode ierr; 3633 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3634 int nlhs = 1,nrhs = 5; 3635 mxArray *plhs[1],*prhs[5]; 3636 long long int lx = 0,ly = 0,ls = 0; 3637 3638 PetscFunctionBegin; 3639 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3640 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3641 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3642 PetscCheckSameComm(snes,1,x,2); 3643 PetscCheckSameComm(snes,1,y,3); 3644 3645 /* call Matlab function in ctx with arguments x and y */ 3646 3647 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3648 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3649 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 3650 prhs[0] = mxCreateDoubleScalar((double)ls); 3651 prhs[1] = mxCreateDoubleScalar((double)lx); 3652 prhs[2] = mxCreateDoubleScalar((double)ly); 3653 prhs[3] = mxCreateString(sctx->funcname); 3654 prhs[4] = sctx->ctx; 3655 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 3656 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3657 mxDestroyArray(prhs[0]); 3658 mxDestroyArray(prhs[1]); 3659 mxDestroyArray(prhs[2]); 3660 mxDestroyArray(prhs[3]); 3661 mxDestroyArray(plhs[0]); 3662 PetscFunctionReturn(0); 3663 } 3664 3665 3666 #undef __FUNCT__ 3667 #define __FUNCT__ "SNESSetFunctionMatlab" 3668 /* 3669 SNESSetFunctionMatlab - Sets the function evaluation routine and function 3670 vector for use by the SNES routines in solving systems of nonlinear 3671 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3672 3673 Logically Collective on SNES 3674 3675 Input Parameters: 3676 + snes - the SNES context 3677 . r - vector to store function value 3678 - func - function evaluation routine 3679 3680 Calling sequence of func: 3681 $ func (SNES snes,Vec x,Vec f,void *ctx); 3682 3683 3684 Notes: 3685 The Newton-like methods typically solve linear systems of the form 3686 $ f'(x) x = -f(x), 3687 where f'(x) denotes the Jacobian matrix and f(x) is the function. 3688 3689 Level: beginner 3690 3691 .keywords: SNES, nonlinear, set, function 3692 3693 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3694 */ 3695 PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 3696 { 3697 PetscErrorCode ierr; 3698 SNESMatlabContext *sctx; 3699 3700 PetscFunctionBegin; 3701 /* currently sctx is memory bleed */ 3702 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3703 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3704 /* 3705 This should work, but it doesn't 3706 sctx->ctx = ctx; 3707 mexMakeArrayPersistent(sctx->ctx); 3708 */ 3709 sctx->ctx = mxDuplicateArray(ctx); 3710 ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 3711 PetscFunctionReturn(0); 3712 } 3713 3714 #undef __FUNCT__ 3715 #define __FUNCT__ "SNESComputeJacobian_Matlab" 3716 /* 3717 SNESComputeJacobian_Matlab - Calls the function that has been set with 3718 SNESSetJacobianMatlab(). 3719 3720 Collective on SNES 3721 3722 Input Parameters: 3723 + snes - the SNES context 3724 . x - input vector 3725 . A, B - the matrices 3726 - ctx - user context 3727 3728 Output Parameter: 3729 . flag - structure of the matrix 3730 3731 Level: developer 3732 3733 .keywords: SNES, nonlinear, compute, function 3734 3735 .seealso: SNESSetFunction(), SNESGetFunction() 3736 @*/ 3737 PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 3738 { 3739 PetscErrorCode ierr; 3740 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3741 int nlhs = 2,nrhs = 6; 3742 mxArray *plhs[2],*prhs[6]; 3743 long long int lx = 0,lA = 0,ls = 0, lB = 0; 3744 3745 PetscFunctionBegin; 3746 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3747 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3748 3749 /* call Matlab function in ctx with arguments x and y */ 3750 3751 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3752 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3753 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 3754 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 3755 prhs[0] = mxCreateDoubleScalar((double)ls); 3756 prhs[1] = mxCreateDoubleScalar((double)lx); 3757 prhs[2] = mxCreateDoubleScalar((double)lA); 3758 prhs[3] = mxCreateDoubleScalar((double)lB); 3759 prhs[4] = mxCreateString(sctx->funcname); 3760 prhs[5] = sctx->ctx; 3761 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 3762 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3763 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 3764 mxDestroyArray(prhs[0]); 3765 mxDestroyArray(prhs[1]); 3766 mxDestroyArray(prhs[2]); 3767 mxDestroyArray(prhs[3]); 3768 mxDestroyArray(prhs[4]); 3769 mxDestroyArray(plhs[0]); 3770 mxDestroyArray(plhs[1]); 3771 PetscFunctionReturn(0); 3772 } 3773 3774 3775 #undef __FUNCT__ 3776 #define __FUNCT__ "SNESSetJacobianMatlab" 3777 /* 3778 SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 3779 vector for use by the SNES routines in solving systems of nonlinear 3780 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3781 3782 Logically Collective on SNES 3783 3784 Input Parameters: 3785 + snes - the SNES context 3786 . A,B - Jacobian matrices 3787 . func - function evaluation routine 3788 - ctx - user context 3789 3790 Calling sequence of func: 3791 $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 3792 3793 3794 Level: developer 3795 3796 .keywords: SNES, nonlinear, set, function 3797 3798 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3799 */ 3800 PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 3801 { 3802 PetscErrorCode ierr; 3803 SNESMatlabContext *sctx; 3804 3805 PetscFunctionBegin; 3806 /* currently sctx is memory bleed */ 3807 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3808 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3809 /* 3810 This should work, but it doesn't 3811 sctx->ctx = ctx; 3812 mexMakeArrayPersistent(sctx->ctx); 3813 */ 3814 sctx->ctx = mxDuplicateArray(ctx); 3815 ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 3816 PetscFunctionReturn(0); 3817 } 3818 3819 #undef __FUNCT__ 3820 #define __FUNCT__ "SNESMonitor_Matlab" 3821 /* 3822 SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 3823 3824 Collective on SNES 3825 3826 .seealso: SNESSetFunction(), SNESGetFunction() 3827 @*/ 3828 PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 3829 { 3830 PetscErrorCode ierr; 3831 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3832 int nlhs = 1,nrhs = 6; 3833 mxArray *plhs[1],*prhs[6]; 3834 long long int lx = 0,ls = 0; 3835 Vec x=snes->vec_sol; 3836 3837 PetscFunctionBegin; 3838 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3839 3840 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3841 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3842 prhs[0] = mxCreateDoubleScalar((double)ls); 3843 prhs[1] = mxCreateDoubleScalar((double)it); 3844 prhs[2] = mxCreateDoubleScalar((double)fnorm); 3845 prhs[3] = mxCreateDoubleScalar((double)lx); 3846 prhs[4] = mxCreateString(sctx->funcname); 3847 prhs[5] = sctx->ctx; 3848 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 3849 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3850 mxDestroyArray(prhs[0]); 3851 mxDestroyArray(prhs[1]); 3852 mxDestroyArray(prhs[2]); 3853 mxDestroyArray(prhs[3]); 3854 mxDestroyArray(prhs[4]); 3855 mxDestroyArray(plhs[0]); 3856 PetscFunctionReturn(0); 3857 } 3858 3859 3860 #undef __FUNCT__ 3861 #define __FUNCT__ "SNESMonitorSetMatlab" 3862 /* 3863 SNESMonitorSetMatlab - Sets the monitor function from MATLAB 3864 3865 Level: developer 3866 3867 .keywords: SNES, nonlinear, set, function 3868 3869 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3870 */ 3871 PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 3872 { 3873 PetscErrorCode ierr; 3874 SNESMatlabContext *sctx; 3875 3876 PetscFunctionBegin; 3877 /* currently sctx is memory bleed */ 3878 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3879 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3880 /* 3881 This should work, but it doesn't 3882 sctx->ctx = ctx; 3883 mexMakeArrayPersistent(sctx->ctx); 3884 */ 3885 sctx->ctx = mxDuplicateArray(ctx); 3886 ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 3887 PetscFunctionReturn(0); 3888 } 3889 3890 #endif 3891