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