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 if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 2762 if (grid < snes->gridsequence) { 2763 DM fine; 2764 Vec xnew; 2765 Mat interp; 2766 2767 ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 2768 ierr = DMGetInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 2769 ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 2770 ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 2771 ierr = MatDestroy(&interp);CHKERRQ(ierr); 2772 x = xnew; 2773 2774 ierr = SNESReset(snes);CHKERRQ(ierr); 2775 ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 2776 ierr = DMDestroy(&fine);CHKERRQ(ierr); 2777 ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 2778 } 2779 } 2780 PetscFunctionReturn(0); 2781 } 2782 2783 /* --------- Internal routines for SNES Package --------- */ 2784 2785 #undef __FUNCT__ 2786 #define __FUNCT__ "SNESSetType" 2787 /*@C 2788 SNESSetType - Sets the method for the nonlinear solver. 2789 2790 Collective on SNES 2791 2792 Input Parameters: 2793 + snes - the SNES context 2794 - type - a known method 2795 2796 Options Database Key: 2797 . -snes_type <type> - Sets the method; use -help for a list 2798 of available methods (for instance, ls or tr) 2799 2800 Notes: 2801 See "petsc/include/petscsnes.h" for available methods (for instance) 2802 + SNESLS - Newton's method with line search 2803 (systems of nonlinear equations) 2804 . SNESTR - Newton's method with trust region 2805 (systems of nonlinear equations) 2806 2807 Normally, it is best to use the SNESSetFromOptions() command and then 2808 set the SNES solver type from the options database rather than by using 2809 this routine. Using the options database provides the user with 2810 maximum flexibility in evaluating the many nonlinear solvers. 2811 The SNESSetType() routine is provided for those situations where it 2812 is necessary to set the nonlinear solver independently of the command 2813 line or options database. This might be the case, for example, when 2814 the choice of solver changes during the execution of the program, 2815 and the user's application is taking responsibility for choosing the 2816 appropriate method. 2817 2818 Level: intermediate 2819 2820 .keywords: SNES, set, type 2821 2822 .seealso: SNESType, SNESCreate() 2823 2824 @*/ 2825 PetscErrorCode SNESSetType(SNES snes,const SNESType type) 2826 { 2827 PetscErrorCode ierr,(*r)(SNES); 2828 PetscBool match; 2829 2830 PetscFunctionBegin; 2831 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2832 PetscValidCharPointer(type,2); 2833 2834 ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 2835 if (match) PetscFunctionReturn(0); 2836 2837 ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 2838 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 2839 /* Destroy the previous private SNES context */ 2840 if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 2841 /* Reinitialize function pointers in SNESOps structure */ 2842 snes->ops->setup = 0; 2843 snes->ops->solve = 0; 2844 snes->ops->view = 0; 2845 snes->ops->setfromoptions = 0; 2846 snes->ops->destroy = 0; 2847 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 2848 snes->setupcalled = PETSC_FALSE; 2849 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 2850 ierr = (*r)(snes);CHKERRQ(ierr); 2851 #if defined(PETSC_HAVE_AMS) 2852 if (PetscAMSPublishAll) { 2853 ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 2854 } 2855 #endif 2856 PetscFunctionReturn(0); 2857 } 2858 2859 2860 /* --------------------------------------------------------------------- */ 2861 #undef __FUNCT__ 2862 #define __FUNCT__ "SNESRegisterDestroy" 2863 /*@ 2864 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 2865 registered by SNESRegisterDynamic(). 2866 2867 Not Collective 2868 2869 Level: advanced 2870 2871 .keywords: SNES, nonlinear, register, destroy 2872 2873 .seealso: SNESRegisterAll(), SNESRegisterAll() 2874 @*/ 2875 PetscErrorCode SNESRegisterDestroy(void) 2876 { 2877 PetscErrorCode ierr; 2878 2879 PetscFunctionBegin; 2880 ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 2881 SNESRegisterAllCalled = PETSC_FALSE; 2882 PetscFunctionReturn(0); 2883 } 2884 2885 #undef __FUNCT__ 2886 #define __FUNCT__ "SNESGetType" 2887 /*@C 2888 SNESGetType - Gets the SNES method type and name (as a string). 2889 2890 Not Collective 2891 2892 Input Parameter: 2893 . snes - nonlinear solver context 2894 2895 Output Parameter: 2896 . type - SNES method (a character string) 2897 2898 Level: intermediate 2899 2900 .keywords: SNES, nonlinear, get, type, name 2901 @*/ 2902 PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 2903 { 2904 PetscFunctionBegin; 2905 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2906 PetscValidPointer(type,2); 2907 *type = ((PetscObject)snes)->type_name; 2908 PetscFunctionReturn(0); 2909 } 2910 2911 #undef __FUNCT__ 2912 #define __FUNCT__ "SNESGetSolution" 2913 /*@ 2914 SNESGetSolution - Returns the vector where the approximate solution is 2915 stored. 2916 2917 Not Collective, but Vec is parallel if SNES is parallel 2918 2919 Input Parameter: 2920 . snes - the SNES context 2921 2922 Output Parameter: 2923 . x - the solution 2924 2925 Level: intermediate 2926 2927 .keywords: SNES, nonlinear, get, solution 2928 2929 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 2930 @*/ 2931 PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 2932 { 2933 PetscFunctionBegin; 2934 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2935 PetscValidPointer(x,2); 2936 *x = snes->vec_sol; 2937 PetscFunctionReturn(0); 2938 } 2939 2940 #undef __FUNCT__ 2941 #define __FUNCT__ "SNESGetSolutionUpdate" 2942 /*@ 2943 SNESGetSolutionUpdate - Returns the vector where the solution update is 2944 stored. 2945 2946 Not Collective, but Vec is parallel if SNES is parallel 2947 2948 Input Parameter: 2949 . snes - the SNES context 2950 2951 Output Parameter: 2952 . x - the solution update 2953 2954 Level: advanced 2955 2956 .keywords: SNES, nonlinear, get, solution, update 2957 2958 .seealso: SNESGetSolution(), SNESGetFunction() 2959 @*/ 2960 PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 2961 { 2962 PetscFunctionBegin; 2963 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2964 PetscValidPointer(x,2); 2965 *x = snes->vec_sol_update; 2966 PetscFunctionReturn(0); 2967 } 2968 2969 #undef __FUNCT__ 2970 #define __FUNCT__ "SNESGetFunction" 2971 /*@C 2972 SNESGetFunction - Returns the vector where the function is stored. 2973 2974 Not Collective, but Vec is parallel if SNES is parallel 2975 2976 Input Parameter: 2977 . snes - the SNES context 2978 2979 Output Parameter: 2980 + r - the function (or PETSC_NULL) 2981 . func - the function (or PETSC_NULL) 2982 - ctx - the function context (or PETSC_NULL) 2983 2984 Level: advanced 2985 2986 .keywords: SNES, nonlinear, get, function 2987 2988 .seealso: SNESSetFunction(), SNESGetSolution() 2989 @*/ 2990 PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 2991 { 2992 PetscFunctionBegin; 2993 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2994 if (r) *r = snes->vec_func; 2995 if (func) *func = snes->ops->computefunction; 2996 if (ctx) *ctx = snes->funP; 2997 PetscFunctionReturn(0); 2998 } 2999 3000 #undef __FUNCT__ 3001 #define __FUNCT__ "SNESSetOptionsPrefix" 3002 /*@C 3003 SNESSetOptionsPrefix - Sets the prefix used for searching for all 3004 SNES options in the database. 3005 3006 Logically Collective on SNES 3007 3008 Input Parameter: 3009 + snes - the SNES context 3010 - prefix - the prefix to prepend to all option names 3011 3012 Notes: 3013 A hyphen (-) must NOT be given at the beginning of the prefix name. 3014 The first character of all runtime options is AUTOMATICALLY the hyphen. 3015 3016 Level: advanced 3017 3018 .keywords: SNES, set, options, prefix, database 3019 3020 .seealso: SNESSetFromOptions() 3021 @*/ 3022 PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 3023 { 3024 PetscErrorCode ierr; 3025 3026 PetscFunctionBegin; 3027 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3028 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 3029 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 3030 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 3031 PetscFunctionReturn(0); 3032 } 3033 3034 #undef __FUNCT__ 3035 #define __FUNCT__ "SNESAppendOptionsPrefix" 3036 /*@C 3037 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3038 SNES options in the database. 3039 3040 Logically Collective on SNES 3041 3042 Input Parameters: 3043 + snes - the SNES context 3044 - prefix - the prefix to prepend to all option names 3045 3046 Notes: 3047 A hyphen (-) must NOT be given at the beginning of the prefix name. 3048 The first character of all runtime options is AUTOMATICALLY the hyphen. 3049 3050 Level: advanced 3051 3052 .keywords: SNES, append, options, prefix, database 3053 3054 .seealso: SNESGetOptionsPrefix() 3055 @*/ 3056 PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 3057 { 3058 PetscErrorCode ierr; 3059 3060 PetscFunctionBegin; 3061 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3062 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 3063 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 3064 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 3065 PetscFunctionReturn(0); 3066 } 3067 3068 #undef __FUNCT__ 3069 #define __FUNCT__ "SNESGetOptionsPrefix" 3070 /*@C 3071 SNESGetOptionsPrefix - Sets the prefix used for searching for all 3072 SNES options in the database. 3073 3074 Not Collective 3075 3076 Input Parameter: 3077 . snes - the SNES context 3078 3079 Output Parameter: 3080 . prefix - pointer to the prefix string used 3081 3082 Notes: On the fortran side, the user should pass in a string 'prefix' of 3083 sufficient length to hold the prefix. 3084 3085 Level: advanced 3086 3087 .keywords: SNES, get, options, prefix, database 3088 3089 .seealso: SNESAppendOptionsPrefix() 3090 @*/ 3091 PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 3092 { 3093 PetscErrorCode ierr; 3094 3095 PetscFunctionBegin; 3096 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3097 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 3098 PetscFunctionReturn(0); 3099 } 3100 3101 3102 #undef __FUNCT__ 3103 #define __FUNCT__ "SNESRegister" 3104 /*@C 3105 SNESRegister - See SNESRegisterDynamic() 3106 3107 Level: advanced 3108 @*/ 3109 PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3110 { 3111 char fullname[PETSC_MAX_PATH_LEN]; 3112 PetscErrorCode ierr; 3113 3114 PetscFunctionBegin; 3115 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3116 ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3117 PetscFunctionReturn(0); 3118 } 3119 3120 #undef __FUNCT__ 3121 #define __FUNCT__ "SNESTestLocalMin" 3122 PetscErrorCode SNESTestLocalMin(SNES snes) 3123 { 3124 PetscErrorCode ierr; 3125 PetscInt N,i,j; 3126 Vec u,uh,fh; 3127 PetscScalar value; 3128 PetscReal norm; 3129 3130 PetscFunctionBegin; 3131 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3132 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3133 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3134 3135 /* currently only works for sequential */ 3136 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3137 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3138 for (i=0; i<N; i++) { 3139 ierr = VecCopy(u,uh);CHKERRQ(ierr); 3140 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3141 for (j=-10; j<11; j++) { 3142 value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3143 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3144 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3145 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 3146 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3147 value = -value; 3148 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3149 } 3150 } 3151 ierr = VecDestroy(&uh);CHKERRQ(ierr); 3152 ierr = VecDestroy(&fh);CHKERRQ(ierr); 3153 PetscFunctionReturn(0); 3154 } 3155 3156 #undef __FUNCT__ 3157 #define __FUNCT__ "SNESKSPSetUseEW" 3158 /*@ 3159 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 3160 computing relative tolerance for linear solvers within an inexact 3161 Newton method. 3162 3163 Logically Collective on SNES 3164 3165 Input Parameters: 3166 + snes - SNES context 3167 - flag - PETSC_TRUE or PETSC_FALSE 3168 3169 Options Database: 3170 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 3171 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 3172 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 3173 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 3174 . -snes_ksp_ew_gamma <gamma> - Sets gamma 3175 . -snes_ksp_ew_alpha <alpha> - Sets alpha 3176 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 3177 - -snes_ksp_ew_threshold <threshold> - Sets threshold 3178 3179 Notes: 3180 Currently, the default is to use a constant relative tolerance for 3181 the inner linear solvers. Alternatively, one can use the 3182 Eisenstat-Walker method, where the relative convergence tolerance 3183 is reset at each Newton iteration according progress of the nonlinear 3184 solver. 3185 3186 Level: advanced 3187 3188 Reference: 3189 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 3190 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 3191 3192 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 3193 3194 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 3195 @*/ 3196 PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 3197 { 3198 PetscFunctionBegin; 3199 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3200 PetscValidLogicalCollectiveBool(snes,flag,2); 3201 snes->ksp_ewconv = flag; 3202 PetscFunctionReturn(0); 3203 } 3204 3205 #undef __FUNCT__ 3206 #define __FUNCT__ "SNESKSPGetUseEW" 3207 /*@ 3208 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 3209 for computing relative tolerance for linear solvers within an 3210 inexact Newton method. 3211 3212 Not Collective 3213 3214 Input Parameter: 3215 . snes - SNES context 3216 3217 Output Parameter: 3218 . flag - PETSC_TRUE or PETSC_FALSE 3219 3220 Notes: 3221 Currently, the default is to use a constant relative tolerance for 3222 the inner linear solvers. Alternatively, one can use the 3223 Eisenstat-Walker method, where the relative convergence tolerance 3224 is reset at each Newton iteration according progress of the nonlinear 3225 solver. 3226 3227 Level: advanced 3228 3229 Reference: 3230 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 3231 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 3232 3233 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 3234 3235 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 3236 @*/ 3237 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 3238 { 3239 PetscFunctionBegin; 3240 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3241 PetscValidPointer(flag,2); 3242 *flag = snes->ksp_ewconv; 3243 PetscFunctionReturn(0); 3244 } 3245 3246 #undef __FUNCT__ 3247 #define __FUNCT__ "SNESKSPSetParametersEW" 3248 /*@ 3249 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 3250 convergence criteria for the linear solvers within an inexact 3251 Newton method. 3252 3253 Logically Collective on SNES 3254 3255 Input Parameters: 3256 + snes - SNES context 3257 . version - version 1, 2 (default is 2) or 3 3258 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 3259 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 3260 . gamma - multiplicative factor for version 2 rtol computation 3261 (0 <= gamma2 <= 1) 3262 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 3263 . alpha2 - power for safeguard 3264 - threshold - threshold for imposing safeguard (0 < threshold < 1) 3265 3266 Note: 3267 Version 3 was contributed by Luis Chacon, June 2006. 3268 3269 Use PETSC_DEFAULT to retain the default for any of the parameters. 3270 3271 Level: advanced 3272 3273 Reference: 3274 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 3275 inexact Newton method", Utah State University Math. Stat. Dept. Res. 3276 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 3277 3278 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 3279 3280 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 3281 @*/ 3282 PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 3283 PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 3284 { 3285 SNESKSPEW *kctx; 3286 PetscFunctionBegin; 3287 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3288 kctx = (SNESKSPEW*)snes->kspconvctx; 3289 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3290 PetscValidLogicalCollectiveInt(snes,version,2); 3291 PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3292 PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3293 PetscValidLogicalCollectiveReal(snes,gamma,5); 3294 PetscValidLogicalCollectiveReal(snes,alpha,6); 3295 PetscValidLogicalCollectiveReal(snes,alpha2,7); 3296 PetscValidLogicalCollectiveReal(snes,threshold,8); 3297 3298 if (version != PETSC_DEFAULT) kctx->version = version; 3299 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 3300 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 3301 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 3302 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 3303 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 3304 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 3305 3306 if (kctx->version < 1 || kctx->version > 3) { 3307 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 3308 } 3309 if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3310 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 3311 } 3312 if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3313 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 3314 } 3315 if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3316 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 3317 } 3318 if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3319 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 3320 } 3321 if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3322 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 3323 } 3324 PetscFunctionReturn(0); 3325 } 3326 3327 #undef __FUNCT__ 3328 #define __FUNCT__ "SNESKSPGetParametersEW" 3329 /*@ 3330 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 3331 convergence criteria for the linear solvers within an inexact 3332 Newton method. 3333 3334 Not Collective 3335 3336 Input Parameters: 3337 snes - SNES context 3338 3339 Output Parameters: 3340 + version - version 1, 2 (default is 2) or 3 3341 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 3342 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 3343 . gamma - multiplicative factor for version 2 rtol computation 3344 (0 <= gamma2 <= 1) 3345 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 3346 . alpha2 - power for safeguard 3347 - threshold - threshold for imposing safeguard (0 < threshold < 1) 3348 3349 Level: advanced 3350 3351 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 3352 3353 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 3354 @*/ 3355 PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 3356 PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 3357 { 3358 SNESKSPEW *kctx; 3359 PetscFunctionBegin; 3360 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3361 kctx = (SNESKSPEW*)snes->kspconvctx; 3362 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3363 if(version) *version = kctx->version; 3364 if(rtol_0) *rtol_0 = kctx->rtol_0; 3365 if(rtol_max) *rtol_max = kctx->rtol_max; 3366 if(gamma) *gamma = kctx->gamma; 3367 if(alpha) *alpha = kctx->alpha; 3368 if(alpha2) *alpha2 = kctx->alpha2; 3369 if(threshold) *threshold = kctx->threshold; 3370 PetscFunctionReturn(0); 3371 } 3372 3373 #undef __FUNCT__ 3374 #define __FUNCT__ "SNESKSPEW_PreSolve" 3375 static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 3376 { 3377 PetscErrorCode ierr; 3378 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 3379 PetscReal rtol=PETSC_DEFAULT,stol; 3380 3381 PetscFunctionBegin; 3382 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3383 if (!snes->iter) { /* first time in, so use the original user rtol */ 3384 rtol = kctx->rtol_0; 3385 } else { 3386 if (kctx->version == 1) { 3387 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 3388 if (rtol < 0.0) rtol = -rtol; 3389 stol = pow(kctx->rtol_last,kctx->alpha2); 3390 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3391 } else if (kctx->version == 2) { 3392 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3393 stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 3394 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3395 } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 3396 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3397 /* safeguard: avoid sharp decrease of rtol */ 3398 stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 3399 stol = PetscMax(rtol,stol); 3400 rtol = PetscMin(kctx->rtol_0,stol); 3401 /* safeguard: avoid oversolving */ 3402 stol = kctx->gamma*(snes->ttol)/snes->norm; 3403 stol = PetscMax(rtol,stol); 3404 rtol = PetscMin(kctx->rtol_0,stol); 3405 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 3406 } 3407 /* safeguard: avoid rtol greater than one */ 3408 rtol = PetscMin(rtol,kctx->rtol_max); 3409 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 3410 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 3411 PetscFunctionReturn(0); 3412 } 3413 3414 #undef __FUNCT__ 3415 #define __FUNCT__ "SNESKSPEW_PostSolve" 3416 static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 3417 { 3418 PetscErrorCode ierr; 3419 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 3420 PCSide pcside; 3421 Vec lres; 3422 3423 PetscFunctionBegin; 3424 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3425 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 3426 ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 3427 if (kctx->version == 1) { 3428 ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 3429 if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 3430 /* KSP residual is true linear residual */ 3431 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 3432 } else { 3433 /* KSP residual is preconditioned residual */ 3434 /* compute true linear residual norm */ 3435 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 3436 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 3437 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 3438 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 3439 ierr = VecDestroy(&lres);CHKERRQ(ierr); 3440 } 3441 } 3442 PetscFunctionReturn(0); 3443 } 3444 3445 #undef __FUNCT__ 3446 #define __FUNCT__ "SNES_KSPSolve" 3447 PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 3448 { 3449 PetscErrorCode ierr; 3450 3451 PetscFunctionBegin; 3452 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3453 ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3454 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3455 PetscFunctionReturn(0); 3456 } 3457 3458 #undef __FUNCT__ 3459 #define __FUNCT__ "SNESSetDM" 3460 /*@ 3461 SNESSetDM - Sets the DM that may be used by some preconditioners 3462 3463 Logically Collective on SNES 3464 3465 Input Parameters: 3466 + snes - the preconditioner context 3467 - dm - the dm 3468 3469 Level: intermediate 3470 3471 3472 .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 3473 @*/ 3474 PetscErrorCode SNESSetDM(SNES snes,DM dm) 3475 { 3476 PetscErrorCode ierr; 3477 KSP ksp; 3478 3479 PetscFunctionBegin; 3480 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3481 if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 3482 ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 3483 snes->dm = dm; 3484 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3485 ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3486 ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 3487 if (snes->pc) { 3488 ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 3489 } 3490 PetscFunctionReturn(0); 3491 } 3492 3493 #undef __FUNCT__ 3494 #define __FUNCT__ "SNESGetDM" 3495 /*@ 3496 SNESGetDM - Gets the DM that may be used by some preconditioners 3497 3498 Not Collective but DM obtained is parallel on SNES 3499 3500 Input Parameter: 3501 . snes - the preconditioner context 3502 3503 Output Parameter: 3504 . dm - the dm 3505 3506 Level: intermediate 3507 3508 3509 .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 3510 @*/ 3511 PetscErrorCode SNESGetDM(SNES snes,DM *dm) 3512 { 3513 PetscFunctionBegin; 3514 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3515 *dm = snes->dm; 3516 PetscFunctionReturn(0); 3517 } 3518 3519 #undef __FUNCT__ 3520 #define __FUNCT__ "SNESSetPC" 3521 /*@ 3522 SNESSetPC - Sets the nonlinear preconditioner to be used. 3523 3524 Collective on SNES 3525 3526 Input Parameters: 3527 + snes - iterative context obtained from SNESCreate() 3528 - pc - the preconditioner object 3529 3530 Notes: 3531 Use SNESGetPC() to retrieve the preconditioner context (for example, 3532 to configure it using the API). 3533 3534 Level: developer 3535 3536 .keywords: SNES, set, precondition 3537 .seealso: SNESGetPC() 3538 @*/ 3539 PetscErrorCode SNESSetPC(SNES snes, SNES pc) 3540 { 3541 PetscErrorCode ierr; 3542 3543 PetscFunctionBegin; 3544 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3545 PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 3546 PetscCheckSameComm(snes, 1, pc, 2); 3547 ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 3548 ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 3549 snes->pc = pc; 3550 ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 3551 PetscFunctionReturn(0); 3552 } 3553 3554 #undef __FUNCT__ 3555 #define __FUNCT__ "SNESGetPC" 3556 /*@ 3557 SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 3558 3559 Not Collective 3560 3561 Input Parameter: 3562 . snes - iterative context obtained from SNESCreate() 3563 3564 Output Parameter: 3565 . pc - preconditioner context 3566 3567 Level: developer 3568 3569 .keywords: SNES, get, preconditioner 3570 .seealso: SNESSetPC() 3571 @*/ 3572 PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 3573 { 3574 PetscErrorCode ierr; 3575 3576 PetscFunctionBegin; 3577 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3578 PetscValidPointer(pc, 2); 3579 if (!snes->pc) { 3580 ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 3581 ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 3582 ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 3583 } 3584 *pc = snes->pc; 3585 PetscFunctionReturn(0); 3586 } 3587 3588 #if defined(PETSC_HAVE_MATLAB_ENGINE) 3589 #include <mex.h> 3590 3591 typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 3592 3593 #undef __FUNCT__ 3594 #define __FUNCT__ "SNESComputeFunction_Matlab" 3595 /* 3596 SNESComputeFunction_Matlab - Calls the function that has been set with 3597 SNESSetFunctionMatlab(). 3598 3599 Collective on SNES 3600 3601 Input Parameters: 3602 + snes - the SNES context 3603 - x - input vector 3604 3605 Output Parameter: 3606 . y - function vector, as set by SNESSetFunction() 3607 3608 Notes: 3609 SNESComputeFunction() is typically used within nonlinear solvers 3610 implementations, so most users would not generally call this routine 3611 themselves. 3612 3613 Level: developer 3614 3615 .keywords: SNES, nonlinear, compute, function 3616 3617 .seealso: SNESSetFunction(), SNESGetFunction() 3618 */ 3619 PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 3620 { 3621 PetscErrorCode ierr; 3622 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3623 int nlhs = 1,nrhs = 5; 3624 mxArray *plhs[1],*prhs[5]; 3625 long long int lx = 0,ly = 0,ls = 0; 3626 3627 PetscFunctionBegin; 3628 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3629 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3630 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3631 PetscCheckSameComm(snes,1,x,2); 3632 PetscCheckSameComm(snes,1,y,3); 3633 3634 /* call Matlab function in ctx with arguments x and y */ 3635 3636 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3637 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3638 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 3639 prhs[0] = mxCreateDoubleScalar((double)ls); 3640 prhs[1] = mxCreateDoubleScalar((double)lx); 3641 prhs[2] = mxCreateDoubleScalar((double)ly); 3642 prhs[3] = mxCreateString(sctx->funcname); 3643 prhs[4] = sctx->ctx; 3644 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 3645 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3646 mxDestroyArray(prhs[0]); 3647 mxDestroyArray(prhs[1]); 3648 mxDestroyArray(prhs[2]); 3649 mxDestroyArray(prhs[3]); 3650 mxDestroyArray(plhs[0]); 3651 PetscFunctionReturn(0); 3652 } 3653 3654 3655 #undef __FUNCT__ 3656 #define __FUNCT__ "SNESSetFunctionMatlab" 3657 /* 3658 SNESSetFunctionMatlab - Sets the function evaluation routine and function 3659 vector for use by the SNES routines in solving systems of nonlinear 3660 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3661 3662 Logically Collective on SNES 3663 3664 Input Parameters: 3665 + snes - the SNES context 3666 . r - vector to store function value 3667 - func - function evaluation routine 3668 3669 Calling sequence of func: 3670 $ func (SNES snes,Vec x,Vec f,void *ctx); 3671 3672 3673 Notes: 3674 The Newton-like methods typically solve linear systems of the form 3675 $ f'(x) x = -f(x), 3676 where f'(x) denotes the Jacobian matrix and f(x) is the function. 3677 3678 Level: beginner 3679 3680 .keywords: SNES, nonlinear, set, function 3681 3682 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3683 */ 3684 PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 3685 { 3686 PetscErrorCode ierr; 3687 SNESMatlabContext *sctx; 3688 3689 PetscFunctionBegin; 3690 /* currently sctx is memory bleed */ 3691 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3692 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3693 /* 3694 This should work, but it doesn't 3695 sctx->ctx = ctx; 3696 mexMakeArrayPersistent(sctx->ctx); 3697 */ 3698 sctx->ctx = mxDuplicateArray(ctx); 3699 ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 3700 PetscFunctionReturn(0); 3701 } 3702 3703 #undef __FUNCT__ 3704 #define __FUNCT__ "SNESComputeJacobian_Matlab" 3705 /* 3706 SNESComputeJacobian_Matlab - Calls the function that has been set with 3707 SNESSetJacobianMatlab(). 3708 3709 Collective on SNES 3710 3711 Input Parameters: 3712 + snes - the SNES context 3713 . x - input vector 3714 . A, B - the matrices 3715 - ctx - user context 3716 3717 Output Parameter: 3718 . flag - structure of the matrix 3719 3720 Level: developer 3721 3722 .keywords: SNES, nonlinear, compute, function 3723 3724 .seealso: SNESSetFunction(), SNESGetFunction() 3725 @*/ 3726 PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 3727 { 3728 PetscErrorCode ierr; 3729 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3730 int nlhs = 2,nrhs = 6; 3731 mxArray *plhs[2],*prhs[6]; 3732 long long int lx = 0,lA = 0,ls = 0, lB = 0; 3733 3734 PetscFunctionBegin; 3735 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3736 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3737 3738 /* call Matlab function in ctx with arguments x and y */ 3739 3740 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3741 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3742 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 3743 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 3744 prhs[0] = mxCreateDoubleScalar((double)ls); 3745 prhs[1] = mxCreateDoubleScalar((double)lx); 3746 prhs[2] = mxCreateDoubleScalar((double)lA); 3747 prhs[3] = mxCreateDoubleScalar((double)lB); 3748 prhs[4] = mxCreateString(sctx->funcname); 3749 prhs[5] = sctx->ctx; 3750 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 3751 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3752 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 3753 mxDestroyArray(prhs[0]); 3754 mxDestroyArray(prhs[1]); 3755 mxDestroyArray(prhs[2]); 3756 mxDestroyArray(prhs[3]); 3757 mxDestroyArray(prhs[4]); 3758 mxDestroyArray(plhs[0]); 3759 mxDestroyArray(plhs[1]); 3760 PetscFunctionReturn(0); 3761 } 3762 3763 3764 #undef __FUNCT__ 3765 #define __FUNCT__ "SNESSetJacobianMatlab" 3766 /* 3767 SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 3768 vector for use by the SNES routines in solving systems of nonlinear 3769 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3770 3771 Logically Collective on SNES 3772 3773 Input Parameters: 3774 + snes - the SNES context 3775 . A,B - Jacobian matrices 3776 . func - function evaluation routine 3777 - ctx - user context 3778 3779 Calling sequence of func: 3780 $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 3781 3782 3783 Level: developer 3784 3785 .keywords: SNES, nonlinear, set, function 3786 3787 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3788 */ 3789 PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 3790 { 3791 PetscErrorCode ierr; 3792 SNESMatlabContext *sctx; 3793 3794 PetscFunctionBegin; 3795 /* currently sctx is memory bleed */ 3796 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3797 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3798 /* 3799 This should work, but it doesn't 3800 sctx->ctx = ctx; 3801 mexMakeArrayPersistent(sctx->ctx); 3802 */ 3803 sctx->ctx = mxDuplicateArray(ctx); 3804 ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 3805 PetscFunctionReturn(0); 3806 } 3807 3808 #undef __FUNCT__ 3809 #define __FUNCT__ "SNESMonitor_Matlab" 3810 /* 3811 SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 3812 3813 Collective on SNES 3814 3815 .seealso: SNESSetFunction(), SNESGetFunction() 3816 @*/ 3817 PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 3818 { 3819 PetscErrorCode ierr; 3820 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3821 int nlhs = 1,nrhs = 6; 3822 mxArray *plhs[1],*prhs[6]; 3823 long long int lx = 0,ls = 0; 3824 Vec x=snes->vec_sol; 3825 3826 PetscFunctionBegin; 3827 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3828 3829 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3830 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3831 prhs[0] = mxCreateDoubleScalar((double)ls); 3832 prhs[1] = mxCreateDoubleScalar((double)it); 3833 prhs[2] = mxCreateDoubleScalar((double)fnorm); 3834 prhs[3] = mxCreateDoubleScalar((double)lx); 3835 prhs[4] = mxCreateString(sctx->funcname); 3836 prhs[5] = sctx->ctx; 3837 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 3838 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3839 mxDestroyArray(prhs[0]); 3840 mxDestroyArray(prhs[1]); 3841 mxDestroyArray(prhs[2]); 3842 mxDestroyArray(prhs[3]); 3843 mxDestroyArray(prhs[4]); 3844 mxDestroyArray(plhs[0]); 3845 PetscFunctionReturn(0); 3846 } 3847 3848 3849 #undef __FUNCT__ 3850 #define __FUNCT__ "SNESMonitorSetMatlab" 3851 /* 3852 SNESMonitorSetMatlab - Sets the monitor function from MATLAB 3853 3854 Level: developer 3855 3856 .keywords: SNES, nonlinear, set, function 3857 3858 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3859 */ 3860 PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 3861 { 3862 PetscErrorCode ierr; 3863 SNESMatlabContext *sctx; 3864 3865 PetscFunctionBegin; 3866 /* currently sctx is memory bleed */ 3867 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3868 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3869 /* 3870 This should work, but it doesn't 3871 sctx->ctx = ctx; 3872 mexMakeArrayPersistent(sctx->ctx); 3873 */ 3874 sctx->ctx = mxDuplicateArray(ctx); 3875 ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 3876 PetscFunctionReturn(0); 3877 } 3878 3879 #endif 3880