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