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