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