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__ "SNESSetErrorIfNotConverged" 13 /*@ 14 SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 15 16 Logically Collective on SNES 17 18 Input Parameters: 19 + snes - iterative context obtained from SNESCreate() 20 - flg - PETSC_TRUE indicates you want the error generated 21 22 Options database keys: 23 . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 24 25 Level: intermediate 26 27 Notes: 28 Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 29 to determine if it has converged. 30 31 .keywords: SNES, set, initial guess, nonzero 32 33 .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 34 @*/ 35 PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 36 { 37 PetscFunctionBegin; 38 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39 PetscValidLogicalCollectiveBool(snes,flg,2); 40 snes->errorifnotconverged = flg; 41 PetscFunctionReturn(0); 42 } 43 44 #undef __FUNCT__ 45 #define __FUNCT__ "SNESGetErrorIfNotConverged" 46 /*@ 47 SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 48 49 Not Collective 50 51 Input Parameter: 52 . snes - iterative context obtained from SNESCreate() 53 54 Output Parameter: 55 . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 56 57 Level: intermediate 58 59 .keywords: SNES, set, initial guess, nonzero 60 61 .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 62 @*/ 63 PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 64 { 65 PetscFunctionBegin; 66 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 67 PetscValidPointer(flag,2); 68 *flag = snes->errorifnotconverged; 69 PetscFunctionReturn(0); 70 } 71 72 #undef __FUNCT__ 73 #define __FUNCT__ "SNESSetFunctionDomainError" 74 /*@ 75 SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 76 in the functions domain. For example, negative pressure. 77 78 Logically Collective on SNES 79 80 Input Parameters: 81 . SNES - the SNES context 82 83 Level: advanced 84 85 .keywords: SNES, view 86 87 .seealso: SNESCreate(), SNESSetFunction() 88 @*/ 89 PetscErrorCode SNESSetFunctionDomainError(SNES snes) 90 { 91 PetscFunctionBegin; 92 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 93 snes->domainerror = PETSC_TRUE; 94 PetscFunctionReturn(0); 95 } 96 97 #undef __FUNCT__ 98 #define __FUNCT__ "SNESView" 99 /*@C 100 SNESView - Prints the SNES data structure. 101 102 Collective on SNES 103 104 Input Parameters: 105 + SNES - the SNES context 106 - viewer - visualization context 107 108 Options Database Key: 109 . -snes_view - Calls SNESView() at end of SNESSolve() 110 111 Notes: 112 The available visualization contexts include 113 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 114 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 115 output where only the first processor opens 116 the file. All other processors send their 117 data to the first processor to print. 118 119 The user can open an alternative visualization context with 120 PetscViewerASCIIOpen() - output to a specified file. 121 122 Level: beginner 123 124 .keywords: SNES, view 125 126 .seealso: PetscViewerASCIIOpen() 127 @*/ 128 PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 129 { 130 SNESKSPEW *kctx; 131 PetscErrorCode ierr; 132 KSP ksp; 133 PetscBool iascii,isstring; 134 135 PetscFunctionBegin; 136 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 137 if (!viewer) { 138 ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 139 } 140 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 141 PetscCheckSameComm(snes,1,viewer,2); 142 143 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 144 ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 145 if (iascii) { 146 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 147 if (snes->ops->view) { 148 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 149 ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 150 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 151 } 152 ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 153 ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 154 snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr); 155 ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 156 ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 157 if (snes->ksp_ewconv) { 158 kctx = (SNESKSPEW *)snes->kspconvctx; 159 if (kctx) { 160 ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 161 ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 162 ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 163 } 164 } 165 if (snes->lagpreconditioner == -1) { 166 ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 167 } else if (snes->lagpreconditioner > 1) { 168 ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 169 } 170 if (snes->lagjacobian == -1) { 171 ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 172 } else if (snes->lagjacobian > 1) { 173 ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D Newton iterations\n",snes->lagjacobian);CHKERRQ(ierr); 174 } 175 } else if (isstring) { 176 const char *type; 177 ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 178 ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 179 } 180 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 181 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 182 ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 183 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 184 PetscFunctionReturn(0); 185 } 186 187 /* 188 We retain a list of functions that also take SNES command 189 line options. These are called at the end SNESSetFromOptions() 190 */ 191 #define MAXSETFROMOPTIONS 5 192 static PetscInt numberofsetfromoptions; 193 static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 194 195 #undef __FUNCT__ 196 #define __FUNCT__ "SNESAddOptionsChecker" 197 /*@C 198 SNESAddOptionsChecker - Adds an additional function to check for SNES options. 199 200 Not Collective 201 202 Input Parameter: 203 . snescheck - function that checks for options 204 205 Level: developer 206 207 .seealso: SNESSetFromOptions() 208 @*/ 209 PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 210 { 211 PetscFunctionBegin; 212 if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 213 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 214 } 215 othersetfromoptions[numberofsetfromoptions++] = snescheck; 216 PetscFunctionReturn(0); 217 } 218 219 extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 220 221 #undef __FUNCT__ 222 #define __FUNCT__ "SNESSetUpMatrixFree_Private" 223 static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 224 { 225 Mat J; 226 KSP ksp; 227 PC pc; 228 PetscBool match; 229 PetscErrorCode ierr; 230 231 PetscFunctionBegin; 232 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 233 234 if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 235 Mat A = snes->jacobian, B = snes->jacobian_pre; 236 ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 237 } 238 239 if (version == 1) { 240 ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 241 ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 242 ierr = MatSetFromOptions(J);CHKERRQ(ierr); 243 } else if (version == 2) { 244 if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 245 #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL_LONG_DOUBLE) 246 ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 247 #else 248 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 249 #endif 250 } else { 251 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 252 } 253 254 ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 255 if (hasOperator) { 256 /* This version replaces the user provided Jacobian matrix with a 257 matrix-free version but still employs the user-provided preconditioner matrix. */ 258 ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 259 } else { 260 /* This version replaces both the user-provided Jacobian and the user- 261 provided preconditioner matrix with the default matrix free version. */ 262 ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 263 /* Force no preconditioner */ 264 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 265 ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 266 ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 267 if (!match) { 268 ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 269 ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 270 } 271 } 272 ierr = MatDestroy(J);CHKERRQ(ierr); 273 274 PetscFunctionReturn(0); 275 } 276 277 #undef __FUNCT__ 278 #define __FUNCT__ "SNESSetFromOptions" 279 /*@ 280 SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 281 282 Collective on SNES 283 284 Input Parameter: 285 . snes - the SNES context 286 287 Options Database Keys: 288 + -snes_type <type> - ls, tr, umls, umtr, test 289 . -snes_stol - convergence tolerance in terms of the norm 290 of the change in the solution between steps 291 . -snes_atol <abstol> - absolute tolerance of residual norm 292 . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 293 . -snes_max_it <max_it> - maximum number of iterations 294 . -snes_max_funcs <max_funcs> - maximum number of function evaluations 295 . -snes_max_fail <max_fail> - maximum number of failures 296 . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 297 . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 298 . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 299 . -snes_trtol <trtol> - trust region tolerance 300 . -snes_no_convergence_test - skip convergence test in nonlinear 301 solver; hence iterations will continue until max_it 302 or some other criterion is reached. Saves expense 303 of convergence test 304 . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 305 filename given prints to stdout 306 . -snes_monitor_solution - plots solution at each iteration 307 . -snes_monitor_residual - plots residual (not its norm) at each iteration 308 . -snes_monitor_solution_update - plots update to solution at each iteration 309 . -snes_monitor_draw - plots residual norm at each iteration 310 . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 311 . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 312 - -snes_converged_reason - print the reason for convergence/divergence after each solve 313 314 Options Database for Eisenstat-Walker method: 315 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 316 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 317 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 318 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 319 . -snes_ksp_ew_gamma <gamma> - Sets gamma 320 . -snes_ksp_ew_alpha <alpha> - Sets alpha 321 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 322 - -snes_ksp_ew_threshold <threshold> - Sets threshold 323 324 Notes: 325 To see all options, run your program with the -help option or consult 326 the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 327 328 Level: beginner 329 330 .keywords: SNES, nonlinear, set, options, database 331 332 .seealso: SNESSetOptionsPrefix() 333 @*/ 334 PetscErrorCode SNESSetFromOptions(SNES snes) 335 { 336 PetscBool flg,mf,mf_operator; 337 PetscInt i,indx,lag,mf_version; 338 MatStructure matflag; 339 const char *deft = SNESLS; 340 const char *convtests[] = {"default","skip"}; 341 SNESKSPEW *kctx = NULL; 342 char type[256], monfilename[PETSC_MAX_PATH_LEN]; 343 PetscViewerASCIIMonitor monviewer; 344 PetscErrorCode ierr; 345 346 PetscFunctionBegin; 347 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 348 349 if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 350 ierr = PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");CHKERRQ(ierr); 351 if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 352 ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 353 if (flg) { 354 ierr = SNESSetType(snes,type);CHKERRQ(ierr); 355 } else if (!((PetscObject)snes)->type_name) { 356 ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 357 } 358 /* not used here, but called so will go into help messaage */ 359 ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 360 361 ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr); 362 ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 363 364 ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 365 ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 366 ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 367 ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 368 ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 369 ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 370 371 ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 372 if (flg) { 373 ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 374 } 375 ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 376 if (flg) { 377 ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 378 } 379 380 ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 381 if (flg) { 382 switch (indx) { 383 case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 384 case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 385 } 386 } 387 388 ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 389 390 kctx = (SNESKSPEW *)snes->kspconvctx; 391 392 ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 393 394 ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 395 ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 396 ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 397 ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 398 ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 399 ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 400 ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 401 402 flg = PETSC_FALSE; 403 ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 404 if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 405 406 ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 407 if (flg) { 408 ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr); 409 ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr); 410 } 411 412 ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 413 if (flg) { 414 ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 415 } 416 417 ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 418 if (flg) { 419 ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr); 420 ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 421 } 422 423 ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 424 if (flg) { 425 ierr = PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);CHKERRQ(ierr); 426 ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);CHKERRQ(ierr); 427 } 428 429 flg = PETSC_FALSE; 430 ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 431 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 432 flg = PETSC_FALSE; 433 ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 434 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 435 flg = PETSC_FALSE; 436 ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 437 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 438 flg = PETSC_FALSE; 439 ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 440 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 441 flg = PETSC_FALSE; 442 ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 443 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 444 445 flg = PETSC_FALSE; 446 ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 447 if (flg) { 448 ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr); 449 ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 450 } 451 452 mf = mf_operator = PETSC_FALSE; 453 flg = PETSC_FALSE; 454 ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 455 if (flg && mf_operator) mf = PETSC_TRUE; 456 flg = PETSC_FALSE; 457 ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 458 if (!flg && mf_operator) mf = PETSC_TRUE; 459 mf_version = 1; 460 ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 461 462 for(i = 0; i < numberofsetfromoptions; i++) { 463 ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 464 } 465 466 if (snes->ops->setfromoptions) { 467 ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 468 } 469 470 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 471 ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 472 ierr = PetscOptionsEnd();CHKERRQ(ierr); 473 474 if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 475 476 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 477 ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 478 ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 479 ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 480 481 PetscFunctionReturn(0); 482 } 483 484 485 #undef __FUNCT__ 486 #define __FUNCT__ "SNESSetApplicationContext" 487 /*@ 488 SNESSetApplicationContext - Sets the optional user-defined context for 489 the nonlinear solvers. 490 491 Logically Collective on SNES 492 493 Input Parameters: 494 + snes - the SNES context 495 - usrP - optional user context 496 497 Level: intermediate 498 499 .keywords: SNES, nonlinear, set, application, context 500 501 .seealso: SNESGetApplicationContext() 502 @*/ 503 PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 504 { 505 PetscFunctionBegin; 506 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 507 snes->user = usrP; 508 PetscFunctionReturn(0); 509 } 510 511 #undef __FUNCT__ 512 #define __FUNCT__ "SNESGetApplicationContext" 513 /*@C 514 SNESGetApplicationContext - Gets the user-defined context for the 515 nonlinear solvers. 516 517 Not Collective 518 519 Input Parameter: 520 . snes - SNES context 521 522 Output Parameter: 523 . usrP - user context 524 525 Level: intermediate 526 527 .keywords: SNES, nonlinear, get, application, context 528 529 .seealso: SNESSetApplicationContext() 530 @*/ 531 PetscErrorCode SNESGetApplicationContext(SNES snes,void **usrP) 532 { 533 PetscFunctionBegin; 534 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 535 *usrP = snes->user; 536 PetscFunctionReturn(0); 537 } 538 539 #undef __FUNCT__ 540 #define __FUNCT__ "SNESGetIterationNumber" 541 /*@ 542 SNESGetIterationNumber - Gets the number of nonlinear iterations completed 543 at this time. 544 545 Not Collective 546 547 Input Parameter: 548 . snes - SNES context 549 550 Output Parameter: 551 . iter - iteration number 552 553 Notes: 554 For example, during the computation of iteration 2 this would return 1. 555 556 This is useful for using lagged Jacobians (where one does not recompute the 557 Jacobian at each SNES iteration). For example, the code 558 .vb 559 ierr = SNESGetIterationNumber(snes,&it); 560 if (!(it % 2)) { 561 [compute Jacobian here] 562 } 563 .ve 564 can be used in your ComputeJacobian() function to cause the Jacobian to be 565 recomputed every second SNES iteration. 566 567 Level: intermediate 568 569 .keywords: SNES, nonlinear, get, iteration, number, 570 571 .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 572 @*/ 573 PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 574 { 575 PetscFunctionBegin; 576 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 577 PetscValidIntPointer(iter,2); 578 *iter = snes->iter; 579 PetscFunctionReturn(0); 580 } 581 582 #undef __FUNCT__ 583 #define __FUNCT__ "SNESGetFunctionNorm" 584 /*@ 585 SNESGetFunctionNorm - Gets the norm of the current function that was set 586 with SNESSSetFunction(). 587 588 Collective on SNES 589 590 Input Parameter: 591 . snes - SNES context 592 593 Output Parameter: 594 . fnorm - 2-norm of function 595 596 Level: intermediate 597 598 .keywords: SNES, nonlinear, get, function, norm 599 600 .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 601 @*/ 602 PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 603 { 604 PetscFunctionBegin; 605 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 606 PetscValidScalarPointer(fnorm,2); 607 *fnorm = snes->norm; 608 PetscFunctionReturn(0); 609 } 610 611 #undef __FUNCT__ 612 #define __FUNCT__ "SNESGetNonlinearStepFailures" 613 /*@ 614 SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 615 attempted by the nonlinear solver. 616 617 Not Collective 618 619 Input Parameter: 620 . snes - SNES context 621 622 Output Parameter: 623 . nfails - number of unsuccessful steps attempted 624 625 Notes: 626 This counter is reset to zero for each successive call to SNESSolve(). 627 628 Level: intermediate 629 630 .keywords: SNES, nonlinear, get, number, unsuccessful, steps 631 632 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 633 SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 634 @*/ 635 PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 636 { 637 PetscFunctionBegin; 638 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 639 PetscValidIntPointer(nfails,2); 640 *nfails = snes->numFailures; 641 PetscFunctionReturn(0); 642 } 643 644 #undef __FUNCT__ 645 #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 646 /*@ 647 SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 648 attempted by the nonlinear solver before it gives up. 649 650 Not Collective 651 652 Input Parameters: 653 + snes - SNES context 654 - maxFails - maximum of unsuccessful steps 655 656 Level: intermediate 657 658 .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 659 660 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 661 SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 662 @*/ 663 PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 664 { 665 PetscFunctionBegin; 666 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 667 snes->maxFailures = maxFails; 668 PetscFunctionReturn(0); 669 } 670 671 #undef __FUNCT__ 672 #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 673 /*@ 674 SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 675 attempted by the nonlinear solver before it gives up. 676 677 Not Collective 678 679 Input Parameter: 680 . snes - SNES context 681 682 Output Parameter: 683 . maxFails - maximum of unsuccessful steps 684 685 Level: intermediate 686 687 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 688 689 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 690 SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 691 692 @*/ 693 PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 694 { 695 PetscFunctionBegin; 696 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 697 PetscValidIntPointer(maxFails,2); 698 *maxFails = snes->maxFailures; 699 PetscFunctionReturn(0); 700 } 701 702 #undef __FUNCT__ 703 #define __FUNCT__ "SNESGetNumberFunctionEvals" 704 /*@ 705 SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 706 done by SNES. 707 708 Not Collective 709 710 Input Parameter: 711 . snes - SNES context 712 713 Output Parameter: 714 . nfuncs - number of evaluations 715 716 Level: intermediate 717 718 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 719 720 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 721 @*/ 722 PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 723 { 724 PetscFunctionBegin; 725 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 726 PetscValidIntPointer(nfuncs,2); 727 *nfuncs = snes->nfuncs; 728 PetscFunctionReturn(0); 729 } 730 731 #undef __FUNCT__ 732 #define __FUNCT__ "SNESGetLinearSolveFailures" 733 /*@ 734 SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 735 linear solvers. 736 737 Not Collective 738 739 Input Parameter: 740 . snes - SNES context 741 742 Output Parameter: 743 . nfails - number of failed solves 744 745 Notes: 746 This counter is reset to zero for each successive call to SNESSolve(). 747 748 Level: intermediate 749 750 .keywords: SNES, nonlinear, get, number, unsuccessful, steps 751 752 .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 753 @*/ 754 PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 755 { 756 PetscFunctionBegin; 757 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 758 PetscValidIntPointer(nfails,2); 759 *nfails = snes->numLinearSolveFailures; 760 PetscFunctionReturn(0); 761 } 762 763 #undef __FUNCT__ 764 #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 765 /*@ 766 SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 767 allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 768 769 Logically Collective on SNES 770 771 Input Parameters: 772 + snes - SNES context 773 - maxFails - maximum allowed linear solve failures 774 775 Level: intermediate 776 777 Notes: By default this is 0; that is SNES returns on the first failed linear solve 778 779 .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 780 781 .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 782 @*/ 783 PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 784 { 785 PetscFunctionBegin; 786 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 787 PetscValidLogicalCollectiveInt(snes,maxFails,2); 788 snes->maxLinearSolveFailures = maxFails; 789 PetscFunctionReturn(0); 790 } 791 792 #undef __FUNCT__ 793 #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 794 /*@ 795 SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 796 are allowed before SNES terminates 797 798 Not Collective 799 800 Input Parameter: 801 . snes - SNES context 802 803 Output Parameter: 804 . maxFails - maximum of unsuccessful solves allowed 805 806 Level: intermediate 807 808 Notes: By default this is 1; that is SNES returns on the first failed linear solve 809 810 .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 811 812 .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 813 @*/ 814 PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 815 { 816 PetscFunctionBegin; 817 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 818 PetscValidIntPointer(maxFails,2); 819 *maxFails = snes->maxLinearSolveFailures; 820 PetscFunctionReturn(0); 821 } 822 823 #undef __FUNCT__ 824 #define __FUNCT__ "SNESGetLinearSolveIterations" 825 /*@ 826 SNESGetLinearSolveIterations - Gets the total number of linear iterations 827 used by the nonlinear solver. 828 829 Not Collective 830 831 Input Parameter: 832 . snes - SNES context 833 834 Output Parameter: 835 . lits - number of linear iterations 836 837 Notes: 838 This counter is reset to zero for each successive call to SNESSolve(). 839 840 Level: intermediate 841 842 .keywords: SNES, nonlinear, get, number, linear, iterations 843 844 .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 845 @*/ 846 PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 847 { 848 PetscFunctionBegin; 849 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 850 PetscValidIntPointer(lits,2); 851 *lits = snes->linear_its; 852 PetscFunctionReturn(0); 853 } 854 855 #undef __FUNCT__ 856 #define __FUNCT__ "SNESGetKSP" 857 /*@ 858 SNESGetKSP - Returns the KSP context for a SNES solver. 859 860 Not Collective, but if SNES object is parallel, then KSP object is parallel 861 862 Input Parameter: 863 . snes - the SNES context 864 865 Output Parameter: 866 . ksp - the KSP context 867 868 Notes: 869 The user can then directly manipulate the KSP context to set various 870 options, etc. Likewise, the user can then extract and manipulate the 871 PC contexts as well. 872 873 Level: beginner 874 875 .keywords: SNES, nonlinear, get, KSP, context 876 877 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 878 @*/ 879 PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 880 { 881 PetscErrorCode ierr; 882 883 PetscFunctionBegin; 884 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 885 PetscValidPointer(ksp,2); 886 887 if (!snes->ksp) { 888 ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 889 ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 890 ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 891 } 892 *ksp = snes->ksp; 893 PetscFunctionReturn(0); 894 } 895 896 #undef __FUNCT__ 897 #define __FUNCT__ "SNESSetKSP" 898 /*@ 899 SNESSetKSP - Sets a KSP context for the SNES object to use 900 901 Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 902 903 Input Parameters: 904 + snes - the SNES context 905 - ksp - the KSP context 906 907 Notes: 908 The SNES object already has its KSP object, you can obtain with SNESGetKSP() 909 so this routine is rarely needed. 910 911 The KSP object that is already in the SNES object has its reference count 912 decreased by one. 913 914 Level: developer 915 916 .keywords: SNES, nonlinear, get, KSP, context 917 918 .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 919 @*/ 920 PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 921 { 922 PetscErrorCode ierr; 923 924 PetscFunctionBegin; 925 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 926 PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 927 PetscCheckSameComm(snes,1,ksp,2); 928 ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 929 if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 930 snes->ksp = ksp; 931 PetscFunctionReturn(0); 932 } 933 934 #if 0 935 #undef __FUNCT__ 936 #define __FUNCT__ "SNESPublish_Petsc" 937 static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 938 { 939 PetscFunctionBegin; 940 PetscFunctionReturn(0); 941 } 942 #endif 943 944 /* -----------------------------------------------------------*/ 945 #undef __FUNCT__ 946 #define __FUNCT__ "SNESCreate" 947 /*@ 948 SNESCreate - Creates a nonlinear solver context. 949 950 Collective on MPI_Comm 951 952 Input Parameters: 953 . comm - MPI communicator 954 955 Output Parameter: 956 . outsnes - the new SNES context 957 958 Options Database Keys: 959 + -snes_mf - Activates default matrix-free Jacobian-vector products, 960 and no preconditioning matrix 961 . -snes_mf_operator - Activates default matrix-free Jacobian-vector 962 products, and a user-provided preconditioning matrix 963 as set by SNESSetJacobian() 964 - -snes_fd - Uses (slow!) finite differences to compute Jacobian 965 966 Level: beginner 967 968 .keywords: SNES, nonlinear, create, context 969 970 .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 971 972 @*/ 973 PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 974 { 975 PetscErrorCode ierr; 976 SNES snes; 977 SNESKSPEW *kctx; 978 979 PetscFunctionBegin; 980 PetscValidPointer(outsnes,2); 981 *outsnes = PETSC_NULL; 982 #ifndef PETSC_USE_DYNAMIC_LIBRARIES 983 ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 984 #endif 985 986 ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 987 988 snes->ops->converged = SNESDefaultConverged; 989 snes->max_its = 50; 990 snes->max_funcs = 10000; 991 snes->norm = 0.0; 992 snes->rtol = 1.e-8; 993 snes->ttol = 0.0; 994 snes->abstol = 1.e-50; 995 snes->xtol = 1.e-8; 996 snes->deltatol = 1.e-12; 997 snes->nfuncs = 0; 998 snes->numFailures = 0; 999 snes->maxFailures = 1; 1000 snes->linear_its = 0; 1001 snes->lagjacobian = 1; 1002 snes->lagpreconditioner = 1; 1003 snes->numbermonitors = 0; 1004 snes->data = 0; 1005 snes->setupcalled = PETSC_FALSE; 1006 snes->ksp_ewconv = PETSC_FALSE; 1007 snes->nwork = 0; 1008 snes->work = 0; 1009 snes->nvwork = 0; 1010 snes->vwork = 0; 1011 snes->conv_hist_len = 0; 1012 snes->conv_hist_max = 0; 1013 snes->conv_hist = PETSC_NULL; 1014 snes->conv_hist_its = PETSC_NULL; 1015 snes->conv_hist_reset = PETSC_TRUE; 1016 snes->reason = SNES_CONVERGED_ITERATING; 1017 1018 snes->numLinearSolveFailures = 0; 1019 snes->maxLinearSolveFailures = 1; 1020 1021 /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 1022 ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 1023 snes->kspconvctx = (void*)kctx; 1024 kctx->version = 2; 1025 kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 1026 this was too large for some test cases */ 1027 kctx->rtol_last = 0.0; 1028 kctx->rtol_max = .9; 1029 kctx->gamma = 1.0; 1030 kctx->alpha = .5*(1.0 + sqrt(5.0)); 1031 kctx->alpha2 = kctx->alpha; 1032 kctx->threshold = .1; 1033 kctx->lresid_last = 0.0; 1034 kctx->norm_last = 0.0; 1035 1036 *outsnes = snes; 1037 PetscFunctionReturn(0); 1038 } 1039 1040 #undef __FUNCT__ 1041 #define __FUNCT__ "SNESSetFunction" 1042 /*@C 1043 SNESSetFunction - Sets the function evaluation routine and function 1044 vector for use by the SNES routines in solving systems of nonlinear 1045 equations. 1046 1047 Logically Collective on SNES 1048 1049 Input Parameters: 1050 + snes - the SNES context 1051 . r - vector to store function value 1052 . func - function evaluation routine 1053 - ctx - [optional] user-defined context for private data for the 1054 function evaluation routine (may be PETSC_NULL) 1055 1056 Calling sequence of func: 1057 $ func (SNES snes,Vec x,Vec f,void *ctx); 1058 1059 . f - function vector 1060 - ctx - optional user-defined function context 1061 1062 Notes: 1063 The Newton-like methods typically solve linear systems of the form 1064 $ f'(x) x = -f(x), 1065 where f'(x) denotes the Jacobian matrix and f(x) is the function. 1066 1067 Level: beginner 1068 1069 .keywords: SNES, nonlinear, set, function 1070 1071 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1072 @*/ 1073 PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 1074 { 1075 PetscErrorCode ierr; 1076 PetscFunctionBegin; 1077 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1078 if (r) { 1079 PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1080 PetscCheckSameComm(snes,1,r,2); 1081 ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 1082 if (snes->vec_func) {ierr = VecDestroy(snes->vec_func);CHKERRQ(ierr);} 1083 snes->vec_func = r; 1084 } else if (!snes->vec_func && snes->dm) { 1085 ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1086 } 1087 if (func) snes->ops->computefunction = func; 1088 if (ctx) snes->funP = ctx; 1089 PetscFunctionReturn(0); 1090 } 1091 1092 /* --------------------------------------------------------------- */ 1093 #undef __FUNCT__ 1094 #define __FUNCT__ "SNESGetRhs" 1095 /*@C 1096 SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 1097 it assumes a zero right hand side. 1098 1099 Logically Collective on SNES 1100 1101 Input Parameter: 1102 . snes - the SNES context 1103 1104 Output Parameter: 1105 . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 1106 1107 Level: intermediate 1108 1109 .keywords: SNES, nonlinear, get, function, right hand side 1110 1111 .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 1112 @*/ 1113 PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 1114 { 1115 PetscFunctionBegin; 1116 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1117 PetscValidPointer(rhs,2); 1118 *rhs = snes->vec_rhs; 1119 PetscFunctionReturn(0); 1120 } 1121 1122 #undef __FUNCT__ 1123 #define __FUNCT__ "SNESComputeFunction" 1124 /*@ 1125 SNESComputeFunction - Calls the function that has been set with 1126 SNESSetFunction(). 1127 1128 Collective on SNES 1129 1130 Input Parameters: 1131 + snes - the SNES context 1132 - x - input vector 1133 1134 Output Parameter: 1135 . y - function vector, as set by SNESSetFunction() 1136 1137 Notes: 1138 SNESComputeFunction() is typically used within nonlinear solvers 1139 implementations, so most users would not generally call this routine 1140 themselves. 1141 1142 Level: developer 1143 1144 .keywords: SNES, nonlinear, compute, function 1145 1146 .seealso: SNESSetFunction(), SNESGetFunction() 1147 @*/ 1148 PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 1149 { 1150 PetscErrorCode ierr; 1151 1152 PetscFunctionBegin; 1153 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1154 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1155 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1156 PetscCheckSameComm(snes,1,x,2); 1157 PetscCheckSameComm(snes,1,y,3); 1158 1159 ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1160 if (snes->ops->computefunction) { 1161 PetscStackPush("SNES user function"); 1162 ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr); 1163 PetscStackPop; 1164 } else if (snes->vec_rhs) { 1165 ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1166 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve()."); 1167 if (snes->vec_rhs) { 1168 ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 1169 } 1170 snes->nfuncs++; 1171 ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1172 PetscFunctionReturn(0); 1173 } 1174 1175 #undef __FUNCT__ 1176 #define __FUNCT__ "SNESComputeJacobian" 1177 /*@ 1178 SNESComputeJacobian - Computes the Jacobian matrix that has been 1179 set with SNESSetJacobian(). 1180 1181 Collective on SNES and Mat 1182 1183 Input Parameters: 1184 + snes - the SNES context 1185 - x - input vector 1186 1187 Output Parameters: 1188 + A - Jacobian matrix 1189 . B - optional preconditioning matrix 1190 - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1191 1192 Options Database Keys: 1193 + -snes_lag_preconditioner <lag> 1194 - -snes_lag_jacobian <lag> 1195 1196 Notes: 1197 Most users should not need to explicitly call this routine, as it 1198 is used internally within the nonlinear solvers. 1199 1200 See KSPSetOperators() for important information about setting the 1201 flag parameter. 1202 1203 Level: developer 1204 1205 .keywords: SNES, compute, Jacobian, matrix 1206 1207 .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 1208 @*/ 1209 PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 1210 { 1211 PetscErrorCode ierr; 1212 PetscBool flag; 1213 1214 PetscFunctionBegin; 1215 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1216 PetscValidHeaderSpecific(X,VEC_CLASSID,2); 1217 PetscValidPointer(flg,5); 1218 PetscCheckSameComm(snes,1,X,2); 1219 if (!snes->ops->computejacobian) PetscFunctionReturn(0); 1220 1221 /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1222 1223 if (snes->lagjacobian == -2) { 1224 snes->lagjacobian = -1; 1225 ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1226 } else if (snes->lagjacobian == -1) { 1227 *flg = SAME_PRECONDITIONER; 1228 ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1229 ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1230 if (flag) { 1231 ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1232 ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1233 } 1234 PetscFunctionReturn(0); 1235 } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1236 *flg = SAME_PRECONDITIONER; 1237 ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1238 ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1239 if (flag) { 1240 ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1241 ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1242 } 1243 PetscFunctionReturn(0); 1244 } 1245 1246 *flg = DIFFERENT_NONZERO_PATTERN; 1247 ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1248 PetscStackPush("SNES user Jacobian function"); 1249 ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr); 1250 PetscStackPop; 1251 ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1252 1253 if (snes->lagpreconditioner == -2) { 1254 ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 1255 snes->lagpreconditioner = -1; 1256 } else if (snes->lagpreconditioner == -1) { 1257 *flg = SAME_PRECONDITIONER; 1258 ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1259 } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1260 *flg = SAME_PRECONDITIONER; 1261 ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1262 } 1263 1264 /* make sure user returned a correct Jacobian and preconditioner */ 1265 /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 1266 PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1267 PetscFunctionReturn(0); 1268 } 1269 1270 #undef __FUNCT__ 1271 #define __FUNCT__ "SNESSetJacobian" 1272 /*@C 1273 SNESSetJacobian - Sets the function to compute Jacobian as well as the 1274 location to store the matrix. 1275 1276 Logically Collective on SNES and Mat 1277 1278 Input Parameters: 1279 + snes - the SNES context 1280 . A - Jacobian matrix 1281 . B - preconditioner matrix (usually same as the Jacobian) 1282 . func - Jacobian evaluation routine 1283 - ctx - [optional] user-defined context for private data for the 1284 Jacobian evaluation routine (may be PETSC_NULL) 1285 1286 Calling sequence of func: 1287 $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 1288 1289 + x - input vector 1290 . A - Jacobian matrix 1291 . B - preconditioner matrix, usually the same as A 1292 . flag - flag indicating information about the preconditioner matrix 1293 structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 1294 - ctx - [optional] user-defined Jacobian context 1295 1296 Notes: 1297 See KSPSetOperators() for important information about setting the flag 1298 output parameter in the routine func(). Be sure to read this information! 1299 1300 The routine func() takes Mat * as the matrix arguments rather than Mat. 1301 This allows the Jacobian evaluation routine to replace A and/or B with a 1302 completely new new matrix structure (not just different matrix elements) 1303 when appropriate, for instance, if the nonzero structure is changing 1304 throughout the global iterations. 1305 1306 If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 1307 each matrix. 1308 1309 If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 1310 must be a MatFDColoring. 1311 1312 Level: beginner 1313 1314 .keywords: SNES, nonlinear, set, Jacobian, matrix 1315 1316 .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 1317 @*/ 1318 PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 1319 { 1320 PetscErrorCode ierr; 1321 1322 PetscFunctionBegin; 1323 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1324 if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 1325 if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 1326 if (A) PetscCheckSameComm(snes,1,A,2); 1327 if (B) PetscCheckSameComm(snes,1,B,3); 1328 if (func) snes->ops->computejacobian = func; 1329 if (ctx) snes->jacP = ctx; 1330 if (A) { 1331 ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 1332 if (snes->jacobian) {ierr = MatDestroy(snes->jacobian);CHKERRQ(ierr);} 1333 snes->jacobian = A; 1334 } 1335 if (B) { 1336 ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 1337 if (snes->jacobian_pre) {ierr = MatDestroy(snes->jacobian_pre);CHKERRQ(ierr);} 1338 snes->jacobian_pre = B; 1339 } 1340 PetscFunctionReturn(0); 1341 } 1342 1343 #undef __FUNCT__ 1344 #define __FUNCT__ "SNESGetJacobian" 1345 /*@C 1346 SNESGetJacobian - Returns the Jacobian matrix and optionally the user 1347 provided context for evaluating the Jacobian. 1348 1349 Not Collective, but Mat object will be parallel if SNES object is 1350 1351 Input Parameter: 1352 . snes - the nonlinear solver context 1353 1354 Output Parameters: 1355 + A - location to stash Jacobian matrix (or PETSC_NULL) 1356 . B - location to stash preconditioner matrix (or PETSC_NULL) 1357 . func - location to put Jacobian function (or PETSC_NULL) 1358 - ctx - location to stash Jacobian ctx (or PETSC_NULL) 1359 1360 Level: advanced 1361 1362 .seealso: SNESSetJacobian(), SNESComputeJacobian() 1363 @*/ 1364 PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 1365 { 1366 PetscFunctionBegin; 1367 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1368 if (A) *A = snes->jacobian; 1369 if (B) *B = snes->jacobian_pre; 1370 if (func) *func = snes->ops->computejacobian; 1371 if (ctx) *ctx = snes->jacP; 1372 PetscFunctionReturn(0); 1373 } 1374 1375 /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 1376 1377 #undef __FUNCT__ 1378 #define __FUNCT__ "SNESSetUp" 1379 /*@ 1380 SNESSetUp - Sets up the internal data structures for the later use 1381 of a nonlinear solver. 1382 1383 Collective on SNES 1384 1385 Input Parameters: 1386 . snes - the SNES context 1387 1388 Notes: 1389 For basic use of the SNES solvers the user need not explicitly call 1390 SNESSetUp(), since these actions will automatically occur during 1391 the call to SNESSolve(). However, if one wishes to control this 1392 phase separately, SNESSetUp() should be called after SNESCreate() 1393 and optional routines of the form SNESSetXXX(), but before SNESSolve(). 1394 1395 Level: advanced 1396 1397 .keywords: SNES, nonlinear, setup 1398 1399 .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 1400 @*/ 1401 PetscErrorCode SNESSetUp(SNES snes) 1402 { 1403 PetscErrorCode ierr; 1404 1405 PetscFunctionBegin; 1406 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1407 if (snes->setupcalled) PetscFunctionReturn(0); 1408 1409 if (!((PetscObject)snes)->type_name) { 1410 ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 1411 } 1412 1413 if (!snes->vec_func && !snes->vec_rhs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first"); 1414 if (!snes->ops->computefunction && !snes->vec_rhs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first"); 1415 if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 1416 if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 1417 1418 if (!snes->vec_func && snes->vec_rhs) { 1419 ierr = VecDuplicate(snes->vec_rhs, &snes->vec_func);CHKERRQ(ierr); 1420 } 1421 if (!snes->vec_sol_update /* && snes->vec_sol */) { 1422 ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 1423 ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 1424 } 1425 1426 if (!snes->ops->computejacobian && snes->dm) { 1427 Mat J; 1428 ISColoring coloring; 1429 MatFDColoring fd; 1430 1431 ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1432 ierr = DMGetColoring(snes->dm,IS_COLORING_GHOSTED,MATAIJ,&coloring);CHKERRQ(ierr); 1433 ierr = MatFDColoringCreate(J,coloring,&fd);CHKERRQ(ierr); 1434 ierr = MatFDColoringSetFunction(fd,(PetscErrorCode (*)(void))snes->ops->computefunction,snes->funP);CHKERRQ(ierr); 1435 ierr = SNESSetJacobian(snes,J,J,SNESDefaultComputeJacobianColor,fd);CHKERRQ(ierr); 1436 ierr = ISColoringDestroy(coloring);CHKERRQ(ierr); 1437 } 1438 if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 1439 1440 if (snes->ops->setup) { 1441 ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 1442 } 1443 1444 snes->setupcalled = PETSC_TRUE; 1445 PetscFunctionReturn(0); 1446 } 1447 1448 #undef __FUNCT__ 1449 #define __FUNCT__ "SNESDestroy" 1450 /*@ 1451 SNESDestroy - Destroys the nonlinear solver context that was created 1452 with SNESCreate(). 1453 1454 Collective on SNES 1455 1456 Input Parameter: 1457 . snes - the SNES context 1458 1459 Level: beginner 1460 1461 .keywords: SNES, nonlinear, destroy 1462 1463 .seealso: SNESCreate(), SNESSolve() 1464 @*/ 1465 PetscErrorCode SNESDestroy(SNES snes) 1466 { 1467 PetscErrorCode ierr; 1468 1469 PetscFunctionBegin; 1470 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1471 if (--((PetscObject)snes)->refct > 0) PetscFunctionReturn(0); 1472 1473 /* if memory was published with AMS then destroy it */ 1474 ierr = PetscObjectDepublish(snes);CHKERRQ(ierr); 1475 1476 if (snes->ops->destroy) {ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);} 1477 if (snes->dm) {ierr = DMDestroy(snes->dm);CHKERRQ(ierr);} 1478 if (snes->vec_rhs) {ierr = VecDestroy(snes->vec_rhs);CHKERRQ(ierr);} 1479 if (snes->vec_sol) {ierr = VecDestroy(snes->vec_sol);CHKERRQ(ierr);} 1480 if (snes->vec_sol_update) {ierr = VecDestroy(snes->vec_sol_update);CHKERRQ(ierr);} 1481 if (snes->vec_func) {ierr = VecDestroy(snes->vec_func);CHKERRQ(ierr);} 1482 if (snes->jacobian) {ierr = MatDestroy(snes->jacobian);CHKERRQ(ierr);} 1483 if (snes->jacobian_pre) {ierr = MatDestroy(snes->jacobian_pre);CHKERRQ(ierr);} 1484 if (snes->ksp) {ierr = KSPDestroy(snes->ksp);CHKERRQ(ierr);} 1485 if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 1486 if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);} 1487 ierr = SNESMonitorCancel(snes);CHKERRQ(ierr); 1488 ierr = PetscFree(snes->kspconvctx);CHKERRQ(ierr); 1489 if (snes->ops->convergeddestroy) {ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);} 1490 if (snes->conv_malloc) { 1491 ierr = PetscFree(snes->conv_hist);CHKERRQ(ierr); 1492 ierr = PetscFree(snes->conv_hist_its);CHKERRQ(ierr); 1493 } 1494 ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 1495 PetscFunctionReturn(0); 1496 } 1497 1498 /* ----------- Routines to set solver parameters ---------- */ 1499 1500 #undef __FUNCT__ 1501 #define __FUNCT__ "SNESSetLagPreconditioner" 1502 /*@ 1503 SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 1504 1505 Logically Collective on SNES 1506 1507 Input Parameters: 1508 + snes - the SNES context 1509 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1510 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1511 1512 Options Database Keys: 1513 . -snes_lag_preconditioner <lag> 1514 1515 Notes: 1516 The default is 1 1517 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1518 If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 1519 1520 Level: intermediate 1521 1522 .keywords: SNES, nonlinear, set, convergence, tolerances 1523 1524 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1525 1526 @*/ 1527 PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 1528 { 1529 PetscFunctionBegin; 1530 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1531 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1532 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1533 PetscValidLogicalCollectiveInt(snes,lag,2); 1534 snes->lagpreconditioner = lag; 1535 PetscFunctionReturn(0); 1536 } 1537 1538 #undef __FUNCT__ 1539 #define __FUNCT__ "SNESGetLagPreconditioner" 1540 /*@ 1541 SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 1542 1543 Not Collective 1544 1545 Input Parameter: 1546 . snes - the SNES context 1547 1548 Output Parameter: 1549 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1550 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1551 1552 Options Database Keys: 1553 . -snes_lag_preconditioner <lag> 1554 1555 Notes: 1556 The default is 1 1557 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1558 1559 Level: intermediate 1560 1561 .keywords: SNES, nonlinear, set, convergence, tolerances 1562 1563 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 1564 1565 @*/ 1566 PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 1567 { 1568 PetscFunctionBegin; 1569 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1570 *lag = snes->lagpreconditioner; 1571 PetscFunctionReturn(0); 1572 } 1573 1574 #undef __FUNCT__ 1575 #define __FUNCT__ "SNESSetLagJacobian" 1576 /*@ 1577 SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 1578 often the preconditioner is rebuilt. 1579 1580 Logically Collective on SNES 1581 1582 Input Parameters: 1583 + snes - the SNES context 1584 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1585 the Jacobian is built etc. -2 means rebuild at next chance but then never again 1586 1587 Options Database Keys: 1588 . -snes_lag_jacobian <lag> 1589 1590 Notes: 1591 The default is 1 1592 The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1593 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 1594 at the next Newton step but never again (unless it is reset to another value) 1595 1596 Level: intermediate 1597 1598 .keywords: SNES, nonlinear, set, convergence, tolerances 1599 1600 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 1601 1602 @*/ 1603 PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 1604 { 1605 PetscFunctionBegin; 1606 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1607 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1608 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1609 PetscValidLogicalCollectiveInt(snes,lag,2); 1610 snes->lagjacobian = lag; 1611 PetscFunctionReturn(0); 1612 } 1613 1614 #undef __FUNCT__ 1615 #define __FUNCT__ "SNESGetLagJacobian" 1616 /*@ 1617 SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 1618 1619 Not Collective 1620 1621 Input Parameter: 1622 . snes - the SNES context 1623 1624 Output Parameter: 1625 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1626 the Jacobian is built etc. 1627 1628 Options Database Keys: 1629 . -snes_lag_jacobian <lag> 1630 1631 Notes: 1632 The default is 1 1633 The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1634 1635 Level: intermediate 1636 1637 .keywords: SNES, nonlinear, set, convergence, tolerances 1638 1639 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 1640 1641 @*/ 1642 PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 1643 { 1644 PetscFunctionBegin; 1645 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1646 *lag = snes->lagjacobian; 1647 PetscFunctionReturn(0); 1648 } 1649 1650 #undef __FUNCT__ 1651 #define __FUNCT__ "SNESSetTolerances" 1652 /*@ 1653 SNESSetTolerances - Sets various parameters used in convergence tests. 1654 1655 Logically Collective on SNES 1656 1657 Input Parameters: 1658 + snes - the SNES context 1659 . abstol - absolute convergence tolerance 1660 . rtol - relative convergence tolerance 1661 . stol - convergence tolerance in terms of the norm 1662 of the change in the solution between steps 1663 . maxit - maximum number of iterations 1664 - maxf - maximum number of function evaluations 1665 1666 Options Database Keys: 1667 + -snes_atol <abstol> - Sets abstol 1668 . -snes_rtol <rtol> - Sets rtol 1669 . -snes_stol <stol> - Sets stol 1670 . -snes_max_it <maxit> - Sets maxit 1671 - -snes_max_funcs <maxf> - Sets maxf 1672 1673 Notes: 1674 The default maximum number of iterations is 50. 1675 The default maximum number of function evaluations is 1000. 1676 1677 Level: intermediate 1678 1679 .keywords: SNES, nonlinear, set, convergence, tolerances 1680 1681 .seealso: SNESSetTrustRegionTolerance() 1682 @*/ 1683 PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 1684 { 1685 PetscFunctionBegin; 1686 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1687 PetscValidLogicalCollectiveReal(snes,abstol,2); 1688 PetscValidLogicalCollectiveReal(snes,rtol,3); 1689 PetscValidLogicalCollectiveReal(snes,stol,4); 1690 PetscValidLogicalCollectiveInt(snes,maxit,5); 1691 PetscValidLogicalCollectiveInt(snes,maxf,6); 1692 1693 if (abstol != PETSC_DEFAULT) snes->abstol = abstol; 1694 if (rtol != PETSC_DEFAULT) snes->rtol = rtol; 1695 if (stol != PETSC_DEFAULT) snes->xtol = stol; 1696 if (maxit != PETSC_DEFAULT) snes->max_its = maxit; 1697 if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf; 1698 PetscFunctionReturn(0); 1699 } 1700 1701 #undef __FUNCT__ 1702 #define __FUNCT__ "SNESGetTolerances" 1703 /*@ 1704 SNESGetTolerances - Gets various parameters used in convergence tests. 1705 1706 Not Collective 1707 1708 Input Parameters: 1709 + snes - the SNES context 1710 . atol - absolute convergence tolerance 1711 . rtol - relative convergence tolerance 1712 . stol - convergence tolerance in terms of the norm 1713 of the change in the solution between steps 1714 . maxit - maximum number of iterations 1715 - maxf - maximum number of function evaluations 1716 1717 Notes: 1718 The user can specify PETSC_NULL for any parameter that is not needed. 1719 1720 Level: intermediate 1721 1722 .keywords: SNES, nonlinear, get, convergence, tolerances 1723 1724 .seealso: SNESSetTolerances() 1725 @*/ 1726 PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 1727 { 1728 PetscFunctionBegin; 1729 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1730 if (atol) *atol = snes->abstol; 1731 if (rtol) *rtol = snes->rtol; 1732 if (stol) *stol = snes->xtol; 1733 if (maxit) *maxit = snes->max_its; 1734 if (maxf) *maxf = snes->max_funcs; 1735 PetscFunctionReturn(0); 1736 } 1737 1738 #undef __FUNCT__ 1739 #define __FUNCT__ "SNESSetTrustRegionTolerance" 1740 /*@ 1741 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 1742 1743 Logically Collective on SNES 1744 1745 Input Parameters: 1746 + snes - the SNES context 1747 - tol - tolerance 1748 1749 Options Database Key: 1750 . -snes_trtol <tol> - Sets tol 1751 1752 Level: intermediate 1753 1754 .keywords: SNES, nonlinear, set, trust region, tolerance 1755 1756 .seealso: SNESSetTolerances() 1757 @*/ 1758 PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 1759 { 1760 PetscFunctionBegin; 1761 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1762 PetscValidLogicalCollectiveReal(snes,tol,2); 1763 snes->deltatol = tol; 1764 PetscFunctionReturn(0); 1765 } 1766 1767 /* 1768 Duplicate the lg monitors for SNES from KSP; for some reason with 1769 dynamic libraries things don't work under Sun4 if we just use 1770 macros instead of functions 1771 */ 1772 #undef __FUNCT__ 1773 #define __FUNCT__ "SNESMonitorLG" 1774 PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 1775 { 1776 PetscErrorCode ierr; 1777 1778 PetscFunctionBegin; 1779 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1780 ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 1781 PetscFunctionReturn(0); 1782 } 1783 1784 #undef __FUNCT__ 1785 #define __FUNCT__ "SNESMonitorLGCreate" 1786 PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 1787 { 1788 PetscErrorCode ierr; 1789 1790 PetscFunctionBegin; 1791 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 1792 PetscFunctionReturn(0); 1793 } 1794 1795 #undef __FUNCT__ 1796 #define __FUNCT__ "SNESMonitorLGDestroy" 1797 PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG draw) 1798 { 1799 PetscErrorCode ierr; 1800 1801 PetscFunctionBegin; 1802 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 1803 PetscFunctionReturn(0); 1804 } 1805 1806 extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 1807 #undef __FUNCT__ 1808 #define __FUNCT__ "SNESMonitorLGRange" 1809 PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 1810 { 1811 PetscDrawLG lg; 1812 PetscErrorCode ierr; 1813 PetscReal x,y,per; 1814 PetscViewer v = (PetscViewer)monctx; 1815 static PetscReal prev; /* should be in the context */ 1816 PetscDraw draw; 1817 PetscFunctionBegin; 1818 if (!monctx) { 1819 MPI_Comm comm; 1820 1821 ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 1822 v = PETSC_VIEWER_DRAW_(comm); 1823 } 1824 ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 1825 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1826 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 1827 ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 1828 x = (PetscReal) n; 1829 if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 1830 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1831 if (n < 20 || !(n % 5)) { 1832 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1833 } 1834 1835 ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 1836 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1837 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 1838 ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 1839 ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 1840 x = (PetscReal) n; 1841 y = 100.0*per; 1842 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1843 if (n < 20 || !(n % 5)) { 1844 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1845 } 1846 1847 ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 1848 if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1849 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 1850 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 1851 x = (PetscReal) n; 1852 y = (prev - rnorm)/prev; 1853 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1854 if (n < 20 || !(n % 5)) { 1855 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1856 } 1857 1858 ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 1859 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 1860 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 1861 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 1862 x = (PetscReal) n; 1863 y = (prev - rnorm)/(prev*per); 1864 if (n > 2) { /*skip initial crazy value */ 1865 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 1866 } 1867 if (n < 20 || !(n % 5)) { 1868 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 1869 } 1870 prev = rnorm; 1871 PetscFunctionReturn(0); 1872 } 1873 1874 #undef __FUNCT__ 1875 #define __FUNCT__ "SNESMonitorLGRangeCreate" 1876 PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 1877 { 1878 PetscErrorCode ierr; 1879 1880 PetscFunctionBegin; 1881 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 1882 PetscFunctionReturn(0); 1883 } 1884 1885 #undef __FUNCT__ 1886 #define __FUNCT__ "SNESMonitorLGRangeDestroy" 1887 PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG draw) 1888 { 1889 PetscErrorCode ierr; 1890 1891 PetscFunctionBegin; 1892 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 1893 PetscFunctionReturn(0); 1894 } 1895 1896 /* ------------ Routines to set performance monitoring options ----------- */ 1897 1898 #undef __FUNCT__ 1899 #define __FUNCT__ "SNESMonitorSet" 1900 /*@C 1901 SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 1902 iteration of the nonlinear solver to display the iteration's 1903 progress. 1904 1905 Logically Collective on SNES 1906 1907 Input Parameters: 1908 + snes - the SNES context 1909 . func - monitoring routine 1910 . mctx - [optional] user-defined context for private data for the 1911 monitor routine (use PETSC_NULL if no context is desired) 1912 - monitordestroy - [optional] routine that frees monitor context 1913 (may be PETSC_NULL) 1914 1915 Calling sequence of func: 1916 $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 1917 1918 + snes - the SNES context 1919 . its - iteration number 1920 . norm - 2-norm function value (may be estimated) 1921 - mctx - [optional] monitoring context 1922 1923 Options Database Keys: 1924 + -snes_monitor - sets SNESMonitorDefault() 1925 . -snes_monitor_draw - sets line graph monitor, 1926 uses SNESMonitorLGCreate() 1927 _ -snes_monitor_cancel - cancels all monitors that have 1928 been hardwired into a code by 1929 calls to SNESMonitorSet(), but 1930 does not cancel those set via 1931 the options database. 1932 1933 Notes: 1934 Several different monitoring routines may be set by calling 1935 SNESMonitorSet() multiple times; all will be called in the 1936 order in which they were set. 1937 1938 Fortran notes: Only a single monitor function can be set for each SNES object 1939 1940 Level: intermediate 1941 1942 .keywords: SNES, nonlinear, set, monitor 1943 1944 .seealso: SNESMonitorDefault(), SNESMonitorCancel() 1945 @*/ 1946 PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*)) 1947 { 1948 PetscInt i; 1949 1950 PetscFunctionBegin; 1951 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1952 if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 1953 for (i=0; i<snes->numbermonitors;i++) { 1954 if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) PetscFunctionReturn(0); 1955 1956 /* check if both default monitors that share common ASCII viewer */ 1957 if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) { 1958 if (mctx && snes->monitorcontext[i]) { 1959 PetscErrorCode ierr; 1960 PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx; 1961 PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i]; 1962 if (viewer1->viewer == viewer2->viewer) { 1963 ierr = (*monitordestroy)(mctx);CHKERRQ(ierr); 1964 PetscFunctionReturn(0); 1965 } 1966 } 1967 } 1968 } 1969 snes->monitor[snes->numbermonitors] = monitor; 1970 snes->monitordestroy[snes->numbermonitors] = monitordestroy; 1971 snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 1972 PetscFunctionReturn(0); 1973 } 1974 1975 #undef __FUNCT__ 1976 #define __FUNCT__ "SNESMonitorCancel" 1977 /*@C 1978 SNESMonitorCancel - Clears all the monitor functions for a SNES object. 1979 1980 Logically Collective on SNES 1981 1982 Input Parameters: 1983 . snes - the SNES context 1984 1985 Options Database Key: 1986 . -snes_monitor_cancel - cancels all monitors that have been hardwired 1987 into a code by calls to SNESMonitorSet(), but does not cancel those 1988 set via the options database 1989 1990 Notes: 1991 There is no way to clear one specific monitor from a SNES object. 1992 1993 Level: intermediate 1994 1995 .keywords: SNES, nonlinear, set, monitor 1996 1997 .seealso: SNESMonitorDefault(), SNESMonitorSet() 1998 @*/ 1999 PetscErrorCode SNESMonitorCancel(SNES snes) 2000 { 2001 PetscErrorCode ierr; 2002 PetscInt i; 2003 2004 PetscFunctionBegin; 2005 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2006 for (i=0; i<snes->numbermonitors; i++) { 2007 if (snes->monitordestroy[i]) { 2008 ierr = (*snes->monitordestroy[i])(snes->monitorcontext[i]);CHKERRQ(ierr); 2009 } 2010 } 2011 snes->numbermonitors = 0; 2012 PetscFunctionReturn(0); 2013 } 2014 2015 #undef __FUNCT__ 2016 #define __FUNCT__ "SNESSetConvergenceTest" 2017 /*@C 2018 SNESSetConvergenceTest - Sets the function that is to be used 2019 to test for convergence of the nonlinear iterative solution. 2020 2021 Logically Collective on SNES 2022 2023 Input Parameters: 2024 + snes - the SNES context 2025 . func - routine to test for convergence 2026 . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 2027 - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 2028 2029 Calling sequence of func: 2030 $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2031 2032 + snes - the SNES context 2033 . it - current iteration (0 is the first and is before any Newton step) 2034 . cctx - [optional] convergence context 2035 . reason - reason for convergence/divergence 2036 . xnorm - 2-norm of current iterate 2037 . gnorm - 2-norm of current step 2038 - f - 2-norm of function 2039 2040 Level: advanced 2041 2042 .keywords: SNES, nonlinear, set, convergence, test 2043 2044 .seealso: SNESDefaultConverged(), SNESSkipConverged() 2045 @*/ 2046 PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 2047 { 2048 PetscErrorCode ierr; 2049 2050 PetscFunctionBegin; 2051 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2052 if (!func) func = SNESSkipConverged; 2053 if (snes->ops->convergeddestroy) { 2054 ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 2055 } 2056 snes->ops->converged = func; 2057 snes->ops->convergeddestroy = destroy; 2058 snes->cnvP = cctx; 2059 PetscFunctionReturn(0); 2060 } 2061 2062 #undef __FUNCT__ 2063 #define __FUNCT__ "SNESGetConvergedReason" 2064 /*@ 2065 SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2066 2067 Not Collective 2068 2069 Input Parameter: 2070 . snes - the SNES context 2071 2072 Output Parameter: 2073 . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2074 manual pages for the individual convergence tests for complete lists 2075 2076 Level: intermediate 2077 2078 Notes: Can only be called after the call the SNESSolve() is complete. 2079 2080 .keywords: SNES, nonlinear, set, convergence, test 2081 2082 .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2083 @*/ 2084 PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2085 { 2086 PetscFunctionBegin; 2087 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2088 PetscValidPointer(reason,2); 2089 *reason = snes->reason; 2090 PetscFunctionReturn(0); 2091 } 2092 2093 #undef __FUNCT__ 2094 #define __FUNCT__ "SNESSetConvergenceHistory" 2095 /*@ 2096 SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2097 2098 Logically Collective on SNES 2099 2100 Input Parameters: 2101 + snes - iterative context obtained from SNESCreate() 2102 . a - array to hold history, this array will contain the function norms computed at each step 2103 . its - integer array holds the number of linear iterations for each solve. 2104 . na - size of a and its 2105 - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2106 else it continues storing new values for new nonlinear solves after the old ones 2107 2108 Notes: 2109 If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2110 default array of length 10000 is allocated. 2111 2112 This routine is useful, e.g., when running a code for purposes 2113 of accurate performance monitoring, when no I/O should be done 2114 during the section of code that is being timed. 2115 2116 Level: intermediate 2117 2118 .keywords: SNES, set, convergence, history 2119 2120 .seealso: SNESGetConvergenceHistory() 2121 2122 @*/ 2123 PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2124 { 2125 PetscErrorCode ierr; 2126 2127 PetscFunctionBegin; 2128 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2129 if (na) PetscValidScalarPointer(a,2); 2130 if (its) PetscValidIntPointer(its,3); 2131 if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2132 if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2133 ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2134 ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2135 snes->conv_malloc = PETSC_TRUE; 2136 } 2137 snes->conv_hist = a; 2138 snes->conv_hist_its = its; 2139 snes->conv_hist_max = na; 2140 snes->conv_hist_len = 0; 2141 snes->conv_hist_reset = reset; 2142 PetscFunctionReturn(0); 2143 } 2144 2145 #if defined(PETSC_HAVE_MATLAB_ENGINE) 2146 #include <engine.h> /* MATLAB include file */ 2147 #include <mex.h> /* MATLAB include file */ 2148 EXTERN_C_BEGIN 2149 #undef __FUNCT__ 2150 #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2151 mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2152 { 2153 mxArray *mat; 2154 PetscInt i; 2155 PetscReal *ar; 2156 2157 PetscFunctionBegin; 2158 mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2159 ar = (PetscReal*) mxGetData(mat); 2160 for (i=0; i<snes->conv_hist_len; i++) { 2161 ar[i] = snes->conv_hist[i]; 2162 } 2163 PetscFunctionReturn(mat); 2164 } 2165 EXTERN_C_END 2166 #endif 2167 2168 2169 #undef __FUNCT__ 2170 #define __FUNCT__ "SNESGetConvergenceHistory" 2171 /*@C 2172 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 2173 2174 Not Collective 2175 2176 Input Parameter: 2177 . snes - iterative context obtained from SNESCreate() 2178 2179 Output Parameters: 2180 . a - array to hold history 2181 . its - integer array holds the number of linear iterations (or 2182 negative if not converged) for each solve. 2183 - na - size of a and its 2184 2185 Notes: 2186 The calling sequence for this routine in Fortran is 2187 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 2188 2189 This routine is useful, e.g., when running a code for purposes 2190 of accurate performance monitoring, when no I/O should be done 2191 during the section of code that is being timed. 2192 2193 Level: intermediate 2194 2195 .keywords: SNES, get, convergence, history 2196 2197 .seealso: SNESSetConvergencHistory() 2198 2199 @*/ 2200 PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 2201 { 2202 PetscFunctionBegin; 2203 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2204 if (a) *a = snes->conv_hist; 2205 if (its) *its = snes->conv_hist_its; 2206 if (na) *na = snes->conv_hist_len; 2207 PetscFunctionReturn(0); 2208 } 2209 2210 #undef __FUNCT__ 2211 #define __FUNCT__ "SNESSetUpdate" 2212 /*@C 2213 SNESSetUpdate - Sets the general-purpose update function called 2214 at the beginning of every iteration of the nonlinear solve. Specifically 2215 it is called just before the Jacobian is "evaluated". 2216 2217 Logically Collective on SNES 2218 2219 Input Parameters: 2220 . snes - The nonlinear solver context 2221 . func - The function 2222 2223 Calling sequence of func: 2224 . func (SNES snes, PetscInt step); 2225 2226 . step - The current step of the iteration 2227 2228 Level: advanced 2229 2230 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() 2231 This is not used by most users. 2232 2233 .keywords: SNES, update 2234 2235 .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 2236 @*/ 2237 PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 2238 { 2239 PetscFunctionBegin; 2240 PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 2241 snes->ops->update = func; 2242 PetscFunctionReturn(0); 2243 } 2244 2245 #undef __FUNCT__ 2246 #define __FUNCT__ "SNESDefaultUpdate" 2247 /*@ 2248 SNESDefaultUpdate - The default update function which does nothing. 2249 2250 Not collective 2251 2252 Input Parameters: 2253 . snes - The nonlinear solver context 2254 . step - The current step of the iteration 2255 2256 Level: intermediate 2257 2258 .keywords: SNES, update 2259 .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 2260 @*/ 2261 PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 2262 { 2263 PetscFunctionBegin; 2264 PetscFunctionReturn(0); 2265 } 2266 2267 #undef __FUNCT__ 2268 #define __FUNCT__ "SNESScaleStep_Private" 2269 /* 2270 SNESScaleStep_Private - Scales a step so that its length is less than the 2271 positive parameter delta. 2272 2273 Input Parameters: 2274 + snes - the SNES context 2275 . y - approximate solution of linear system 2276 . fnorm - 2-norm of current function 2277 - delta - trust region size 2278 2279 Output Parameters: 2280 + gpnorm - predicted function norm at the new point, assuming local 2281 linearization. The value is zero if the step lies within the trust 2282 region, and exceeds zero otherwise. 2283 - ynorm - 2-norm of the step 2284 2285 Note: 2286 For non-trust region methods such as SNESLS, the parameter delta 2287 is set to be the maximum allowable step size. 2288 2289 .keywords: SNES, nonlinear, scale, step 2290 */ 2291 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 2292 { 2293 PetscReal nrm; 2294 PetscScalar cnorm; 2295 PetscErrorCode ierr; 2296 2297 PetscFunctionBegin; 2298 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2299 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 2300 PetscCheckSameComm(snes,1,y,2); 2301 2302 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 2303 if (nrm > *delta) { 2304 nrm = *delta/nrm; 2305 *gpnorm = (1.0 - nrm)*(*fnorm); 2306 cnorm = nrm; 2307 ierr = VecScale(y,cnorm);CHKERRQ(ierr); 2308 *ynorm = *delta; 2309 } else { 2310 *gpnorm = 0.0; 2311 *ynorm = nrm; 2312 } 2313 PetscFunctionReturn(0); 2314 } 2315 2316 #undef __FUNCT__ 2317 #define __FUNCT__ "SNESSolve" 2318 /*@C 2319 SNESSolve - Solves a nonlinear system F(x) = b. 2320 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 2321 2322 Collective on SNES 2323 2324 Input Parameters: 2325 + snes - the SNES context 2326 . b - the constant part of the equation, or PETSC_NULL to use zero. 2327 - x - the solution vector. 2328 2329 Notes: 2330 The user should initialize the vector,x, with the initial guess 2331 for the nonlinear solve prior to calling SNESSolve. In particular, 2332 to employ an initial guess of zero, the user should explicitly set 2333 this vector to zero by calling VecSet(). 2334 2335 Level: beginner 2336 2337 .keywords: SNES, nonlinear, solve 2338 2339 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian() 2340 @*/ 2341 PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 2342 { 2343 PetscErrorCode ierr; 2344 PetscBool flg; 2345 char filename[PETSC_MAX_PATH_LEN]; 2346 PetscViewer viewer; 2347 2348 PetscFunctionBegin; 2349 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2350 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2351 PetscCheckSameComm(snes,1,x,3); 2352 if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 2353 if (b) PetscCheckSameComm(snes,1,b,2); 2354 2355 /* set solution vector */ 2356 ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 2357 if (snes->vec_sol) { ierr = VecDestroy(snes->vec_sol);CHKERRQ(ierr); } 2358 snes->vec_sol = x; 2359 /* set afine vector if provided */ 2360 if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 2361 if (snes->vec_rhs) { ierr = VecDestroy(snes->vec_rhs);CHKERRQ(ierr); } 2362 snes->vec_rhs = b; 2363 2364 ierr = SNESSetUp(snes);CHKERRQ(ierr); 2365 2366 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 2367 snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 2368 2369 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 2370 ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 2371 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 2372 if (snes->domainerror){ 2373 snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 2374 snes->domainerror = PETSC_FALSE; 2375 } 2376 if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 2377 2378 ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 2379 if (flg && !PetscPreLoadingOn) { 2380 ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 2381 ierr = SNESView(snes,viewer);CHKERRQ(ierr); 2382 ierr = PetscViewerDestroy(viewer);CHKERRQ(ierr); 2383 } 2384 2385 flg = PETSC_FALSE; 2386 ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 2387 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 2388 if (snes->printreason) { 2389 if (snes->reason > 0) { 2390 ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 2391 } else { 2392 ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 2393 } 2394 } 2395 2396 if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 2397 PetscFunctionReturn(0); 2398 } 2399 2400 /* --------- Internal routines for SNES Package --------- */ 2401 2402 #undef __FUNCT__ 2403 #define __FUNCT__ "SNESSetType" 2404 /*@C 2405 SNESSetType - Sets the method for the nonlinear solver. 2406 2407 Collective on SNES 2408 2409 Input Parameters: 2410 + snes - the SNES context 2411 - type - a known method 2412 2413 Options Database Key: 2414 . -snes_type <type> - Sets the method; use -help for a list 2415 of available methods (for instance, ls or tr) 2416 2417 Notes: 2418 See "petsc/include/petscsnes.h" for available methods (for instance) 2419 + SNESLS - Newton's method with line search 2420 (systems of nonlinear equations) 2421 . SNESTR - Newton's method with trust region 2422 (systems of nonlinear equations) 2423 2424 Normally, it is best to use the SNESSetFromOptions() command and then 2425 set the SNES solver type from the options database rather than by using 2426 this routine. Using the options database provides the user with 2427 maximum flexibility in evaluating the many nonlinear solvers. 2428 The SNESSetType() routine is provided for those situations where it 2429 is necessary to set the nonlinear solver independently of the command 2430 line or options database. This might be the case, for example, when 2431 the choice of solver changes during the execution of the program, 2432 and the user's application is taking responsibility for choosing the 2433 appropriate method. 2434 2435 Level: intermediate 2436 2437 .keywords: SNES, set, type 2438 2439 .seealso: SNESType, SNESCreate() 2440 2441 @*/ 2442 PetscErrorCode SNESSetType(SNES snes,const SNESType type) 2443 { 2444 PetscErrorCode ierr,(*r)(SNES); 2445 PetscBool match; 2446 2447 PetscFunctionBegin; 2448 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2449 PetscValidCharPointer(type,2); 2450 2451 ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 2452 if (match) PetscFunctionReturn(0); 2453 2454 ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 2455 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 2456 /* Destroy the previous private SNES context */ 2457 if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 2458 /* Reinitialize function pointers in SNESOps structure */ 2459 snes->ops->setup = 0; 2460 snes->ops->solve = 0; 2461 snes->ops->view = 0; 2462 snes->ops->setfromoptions = 0; 2463 snes->ops->destroy = 0; 2464 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 2465 snes->setupcalled = PETSC_FALSE; 2466 ierr = (*r)(snes);CHKERRQ(ierr); 2467 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 2468 #if defined(PETSC_HAVE_AMS) 2469 if (PetscAMSPublishAll) { 2470 ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 2471 } 2472 #endif 2473 PetscFunctionReturn(0); 2474 } 2475 2476 2477 /* --------------------------------------------------------------------- */ 2478 #undef __FUNCT__ 2479 #define __FUNCT__ "SNESRegisterDestroy" 2480 /*@ 2481 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 2482 registered by SNESRegisterDynamic(). 2483 2484 Not Collective 2485 2486 Level: advanced 2487 2488 .keywords: SNES, nonlinear, register, destroy 2489 2490 .seealso: SNESRegisterAll(), SNESRegisterAll() 2491 @*/ 2492 PetscErrorCode SNESRegisterDestroy(void) 2493 { 2494 PetscErrorCode ierr; 2495 2496 PetscFunctionBegin; 2497 ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 2498 SNESRegisterAllCalled = PETSC_FALSE; 2499 PetscFunctionReturn(0); 2500 } 2501 2502 #undef __FUNCT__ 2503 #define __FUNCT__ "SNESGetType" 2504 /*@C 2505 SNESGetType - Gets the SNES method type and name (as a string). 2506 2507 Not Collective 2508 2509 Input Parameter: 2510 . snes - nonlinear solver context 2511 2512 Output Parameter: 2513 . type - SNES method (a character string) 2514 2515 Level: intermediate 2516 2517 .keywords: SNES, nonlinear, get, type, name 2518 @*/ 2519 PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 2520 { 2521 PetscFunctionBegin; 2522 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2523 PetscValidPointer(type,2); 2524 *type = ((PetscObject)snes)->type_name; 2525 PetscFunctionReturn(0); 2526 } 2527 2528 #undef __FUNCT__ 2529 #define __FUNCT__ "SNESGetSolution" 2530 /*@ 2531 SNESGetSolution - Returns the vector where the approximate solution is 2532 stored. 2533 2534 Not Collective, but Vec is parallel if SNES is parallel 2535 2536 Input Parameter: 2537 . snes - the SNES context 2538 2539 Output Parameter: 2540 . x - the solution 2541 2542 Level: intermediate 2543 2544 .keywords: SNES, nonlinear, get, solution 2545 2546 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 2547 @*/ 2548 PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 2549 { 2550 PetscFunctionBegin; 2551 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2552 PetscValidPointer(x,2); 2553 *x = snes->vec_sol; 2554 PetscFunctionReturn(0); 2555 } 2556 2557 #undef __FUNCT__ 2558 #define __FUNCT__ "SNESGetSolutionUpdate" 2559 /*@ 2560 SNESGetSolutionUpdate - Returns the vector where the solution update is 2561 stored. 2562 2563 Not Collective, but Vec is parallel if SNES is parallel 2564 2565 Input Parameter: 2566 . snes - the SNES context 2567 2568 Output Parameter: 2569 . x - the solution update 2570 2571 Level: advanced 2572 2573 .keywords: SNES, nonlinear, get, solution, update 2574 2575 .seealso: SNESGetSolution(), SNESGetFunction() 2576 @*/ 2577 PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 2578 { 2579 PetscFunctionBegin; 2580 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2581 PetscValidPointer(x,2); 2582 *x = snes->vec_sol_update; 2583 PetscFunctionReturn(0); 2584 } 2585 2586 #undef __FUNCT__ 2587 #define __FUNCT__ "SNESGetFunction" 2588 /*@C 2589 SNESGetFunction - Returns the vector where the function is stored. 2590 2591 Not Collective, but Vec is parallel if SNES is parallel 2592 2593 Input Parameter: 2594 . snes - the SNES context 2595 2596 Output Parameter: 2597 + r - the function (or PETSC_NULL) 2598 . func - the function (or PETSC_NULL) 2599 - ctx - the function context (or PETSC_NULL) 2600 2601 Level: advanced 2602 2603 .keywords: SNES, nonlinear, get, function 2604 2605 .seealso: SNESSetFunction(), SNESGetSolution() 2606 @*/ 2607 PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 2608 { 2609 PetscFunctionBegin; 2610 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2611 if (r) *r = snes->vec_func; 2612 if (func) *func = snes->ops->computefunction; 2613 if (ctx) *ctx = snes->funP; 2614 PetscFunctionReturn(0); 2615 } 2616 2617 #undef __FUNCT__ 2618 #define __FUNCT__ "SNESSetOptionsPrefix" 2619 /*@C 2620 SNESSetOptionsPrefix - Sets the prefix used for searching for all 2621 SNES options in the database. 2622 2623 Logically Collective on SNES 2624 2625 Input Parameter: 2626 + snes - the SNES context 2627 - prefix - the prefix to prepend to all option names 2628 2629 Notes: 2630 A hyphen (-) must NOT be given at the beginning of the prefix name. 2631 The first character of all runtime options is AUTOMATICALLY the hyphen. 2632 2633 Level: advanced 2634 2635 .keywords: SNES, set, options, prefix, database 2636 2637 .seealso: SNESSetFromOptions() 2638 @*/ 2639 PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 2640 { 2641 PetscErrorCode ierr; 2642 2643 PetscFunctionBegin; 2644 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2645 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2646 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 2647 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2648 PetscFunctionReturn(0); 2649 } 2650 2651 #undef __FUNCT__ 2652 #define __FUNCT__ "SNESAppendOptionsPrefix" 2653 /*@C 2654 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 2655 SNES options in the database. 2656 2657 Logically Collective on SNES 2658 2659 Input Parameters: 2660 + snes - the SNES context 2661 - prefix - the prefix to prepend to all option names 2662 2663 Notes: 2664 A hyphen (-) must NOT be given at the beginning of the prefix name. 2665 The first character of all runtime options is AUTOMATICALLY the hyphen. 2666 2667 Level: advanced 2668 2669 .keywords: SNES, append, options, prefix, database 2670 2671 .seealso: SNESGetOptionsPrefix() 2672 @*/ 2673 PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 2674 { 2675 PetscErrorCode ierr; 2676 2677 PetscFunctionBegin; 2678 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2679 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2680 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 2681 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2682 PetscFunctionReturn(0); 2683 } 2684 2685 #undef __FUNCT__ 2686 #define __FUNCT__ "SNESGetOptionsPrefix" 2687 /*@C 2688 SNESGetOptionsPrefix - Sets the prefix used for searching for all 2689 SNES options in the database. 2690 2691 Not Collective 2692 2693 Input Parameter: 2694 . snes - the SNES context 2695 2696 Output Parameter: 2697 . prefix - pointer to the prefix string used 2698 2699 Notes: On the fortran side, the user should pass in a string 'prefix' of 2700 sufficient length to hold the prefix. 2701 2702 Level: advanced 2703 2704 .keywords: SNES, get, options, prefix, database 2705 2706 .seealso: SNESAppendOptionsPrefix() 2707 @*/ 2708 PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 2709 { 2710 PetscErrorCode ierr; 2711 2712 PetscFunctionBegin; 2713 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2714 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2715 PetscFunctionReturn(0); 2716 } 2717 2718 2719 #undef __FUNCT__ 2720 #define __FUNCT__ "SNESRegister" 2721 /*@C 2722 SNESRegister - See SNESRegisterDynamic() 2723 2724 Level: advanced 2725 @*/ 2726 PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 2727 { 2728 char fullname[PETSC_MAX_PATH_LEN]; 2729 PetscErrorCode ierr; 2730 2731 PetscFunctionBegin; 2732 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 2733 ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 2734 PetscFunctionReturn(0); 2735 } 2736 2737 #undef __FUNCT__ 2738 #define __FUNCT__ "SNESTestLocalMin" 2739 PetscErrorCode SNESTestLocalMin(SNES snes) 2740 { 2741 PetscErrorCode ierr; 2742 PetscInt N,i,j; 2743 Vec u,uh,fh; 2744 PetscScalar value; 2745 PetscReal norm; 2746 2747 PetscFunctionBegin; 2748 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 2749 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 2750 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 2751 2752 /* currently only works for sequential */ 2753 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 2754 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 2755 for (i=0; i<N; i++) { 2756 ierr = VecCopy(u,uh);CHKERRQ(ierr); 2757 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 2758 for (j=-10; j<11; j++) { 2759 value = PetscSign(j)*exp(PetscAbs(j)-10.0); 2760 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2761 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 2762 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 2763 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 2764 value = -value; 2765 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 2766 } 2767 } 2768 ierr = VecDestroy(uh);CHKERRQ(ierr); 2769 ierr = VecDestroy(fh);CHKERRQ(ierr); 2770 PetscFunctionReturn(0); 2771 } 2772 2773 #undef __FUNCT__ 2774 #define __FUNCT__ "SNESKSPSetUseEW" 2775 /*@ 2776 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 2777 computing relative tolerance for linear solvers within an inexact 2778 Newton method. 2779 2780 Logically Collective on SNES 2781 2782 Input Parameters: 2783 + snes - SNES context 2784 - flag - PETSC_TRUE or PETSC_FALSE 2785 2786 Options Database: 2787 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 2788 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 2789 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 2790 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 2791 . -snes_ksp_ew_gamma <gamma> - Sets gamma 2792 . -snes_ksp_ew_alpha <alpha> - Sets alpha 2793 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 2794 - -snes_ksp_ew_threshold <threshold> - Sets threshold 2795 2796 Notes: 2797 Currently, the default is to use a constant relative tolerance for 2798 the inner linear solvers. Alternatively, one can use the 2799 Eisenstat-Walker method, where the relative convergence tolerance 2800 is reset at each Newton iteration according progress of the nonlinear 2801 solver. 2802 2803 Level: advanced 2804 2805 Reference: 2806 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2807 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2808 2809 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2810 2811 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 2812 @*/ 2813 PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 2814 { 2815 PetscFunctionBegin; 2816 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2817 PetscValidLogicalCollectiveBool(snes,flag,2); 2818 snes->ksp_ewconv = flag; 2819 PetscFunctionReturn(0); 2820 } 2821 2822 #undef __FUNCT__ 2823 #define __FUNCT__ "SNESKSPGetUseEW" 2824 /*@ 2825 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 2826 for computing relative tolerance for linear solvers within an 2827 inexact Newton method. 2828 2829 Not Collective 2830 2831 Input Parameter: 2832 . snes - SNES context 2833 2834 Output Parameter: 2835 . flag - PETSC_TRUE or PETSC_FALSE 2836 2837 Notes: 2838 Currently, the default is to use a constant relative tolerance for 2839 the inner linear solvers. Alternatively, one can use the 2840 Eisenstat-Walker method, where the relative convergence tolerance 2841 is reset at each Newton iteration according progress of the nonlinear 2842 solver. 2843 2844 Level: advanced 2845 2846 Reference: 2847 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2848 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 2849 2850 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 2851 2852 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 2853 @*/ 2854 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 2855 { 2856 PetscFunctionBegin; 2857 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2858 PetscValidPointer(flag,2); 2859 *flag = snes->ksp_ewconv; 2860 PetscFunctionReturn(0); 2861 } 2862 2863 #undef __FUNCT__ 2864 #define __FUNCT__ "SNESKSPSetParametersEW" 2865 /*@ 2866 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 2867 convergence criteria for the linear solvers within an inexact 2868 Newton method. 2869 2870 Logically Collective on SNES 2871 2872 Input Parameters: 2873 + snes - SNES context 2874 . version - version 1, 2 (default is 2) or 3 2875 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2876 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2877 . gamma - multiplicative factor for version 2 rtol computation 2878 (0 <= gamma2 <= 1) 2879 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2880 . alpha2 - power for safeguard 2881 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2882 2883 Note: 2884 Version 3 was contributed by Luis Chacon, June 2006. 2885 2886 Use PETSC_DEFAULT to retain the default for any of the parameters. 2887 2888 Level: advanced 2889 2890 Reference: 2891 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 2892 inexact Newton method", Utah State University Math. Stat. Dept. Res. 2893 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 2894 2895 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 2896 2897 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 2898 @*/ 2899 PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 2900 PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 2901 { 2902 SNESKSPEW *kctx; 2903 PetscFunctionBegin; 2904 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2905 kctx = (SNESKSPEW*)snes->kspconvctx; 2906 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2907 PetscValidLogicalCollectiveInt(snes,version,2); 2908 PetscValidLogicalCollectiveReal(snes,rtol_0,3); 2909 PetscValidLogicalCollectiveReal(snes,rtol_max,4); 2910 PetscValidLogicalCollectiveReal(snes,gamma,5); 2911 PetscValidLogicalCollectiveReal(snes,alpha,6); 2912 PetscValidLogicalCollectiveReal(snes,alpha2,7); 2913 PetscValidLogicalCollectiveReal(snes,threshold,8); 2914 2915 if (version != PETSC_DEFAULT) kctx->version = version; 2916 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 2917 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 2918 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 2919 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 2920 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 2921 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 2922 2923 if (kctx->version < 1 || kctx->version > 3) { 2924 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 2925 } 2926 if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 2927 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 2928 } 2929 if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 2930 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 2931 } 2932 if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 2933 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 2934 } 2935 if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 2936 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 2937 } 2938 if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 2939 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 2940 } 2941 PetscFunctionReturn(0); 2942 } 2943 2944 #undef __FUNCT__ 2945 #define __FUNCT__ "SNESKSPGetParametersEW" 2946 /*@ 2947 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 2948 convergence criteria for the linear solvers within an inexact 2949 Newton method. 2950 2951 Not Collective 2952 2953 Input Parameters: 2954 snes - SNES context 2955 2956 Output Parameters: 2957 + version - version 1, 2 (default is 2) or 3 2958 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 2959 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 2960 . gamma - multiplicative factor for version 2 rtol computation 2961 (0 <= gamma2 <= 1) 2962 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 2963 . alpha2 - power for safeguard 2964 - threshold - threshold for imposing safeguard (0 < threshold < 1) 2965 2966 Level: advanced 2967 2968 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 2969 2970 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 2971 @*/ 2972 PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 2973 PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 2974 { 2975 SNESKSPEW *kctx; 2976 PetscFunctionBegin; 2977 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2978 kctx = (SNESKSPEW*)snes->kspconvctx; 2979 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 2980 if(version) *version = kctx->version; 2981 if(rtol_0) *rtol_0 = kctx->rtol_0; 2982 if(rtol_max) *rtol_max = kctx->rtol_max; 2983 if(gamma) *gamma = kctx->gamma; 2984 if(alpha) *alpha = kctx->alpha; 2985 if(alpha2) *alpha2 = kctx->alpha2; 2986 if(threshold) *threshold = kctx->threshold; 2987 PetscFunctionReturn(0); 2988 } 2989 2990 #undef __FUNCT__ 2991 #define __FUNCT__ "SNESKSPEW_PreSolve" 2992 static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 2993 { 2994 PetscErrorCode ierr; 2995 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 2996 PetscReal rtol=PETSC_DEFAULT,stol; 2997 2998 PetscFunctionBegin; 2999 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3000 if (!snes->iter) { /* first time in, so use the original user rtol */ 3001 rtol = kctx->rtol_0; 3002 } else { 3003 if (kctx->version == 1) { 3004 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 3005 if (rtol < 0.0) rtol = -rtol; 3006 stol = pow(kctx->rtol_last,kctx->alpha2); 3007 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3008 } else if (kctx->version == 2) { 3009 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3010 stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 3011 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3012 } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 3013 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3014 /* safeguard: avoid sharp decrease of rtol */ 3015 stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 3016 stol = PetscMax(rtol,stol); 3017 rtol = PetscMin(kctx->rtol_0,stol); 3018 /* safeguard: avoid oversolving */ 3019 stol = kctx->gamma*(snes->ttol)/snes->norm; 3020 stol = PetscMax(rtol,stol); 3021 rtol = PetscMin(kctx->rtol_0,stol); 3022 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 3023 } 3024 /* safeguard: avoid rtol greater than one */ 3025 rtol = PetscMin(rtol,kctx->rtol_max); 3026 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 3027 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 3028 PetscFunctionReturn(0); 3029 } 3030 3031 #undef __FUNCT__ 3032 #define __FUNCT__ "SNESKSPEW_PostSolve" 3033 static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 3034 { 3035 PetscErrorCode ierr; 3036 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 3037 PCSide pcside; 3038 Vec lres; 3039 3040 PetscFunctionBegin; 3041 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3042 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 3043 ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 3044 if (kctx->version == 1) { 3045 ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 3046 if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 3047 /* KSP residual is true linear residual */ 3048 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 3049 } else { 3050 /* KSP residual is preconditioned residual */ 3051 /* compute true linear residual norm */ 3052 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 3053 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 3054 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 3055 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 3056 ierr = VecDestroy(lres);CHKERRQ(ierr); 3057 } 3058 } 3059 PetscFunctionReturn(0); 3060 } 3061 3062 #undef __FUNCT__ 3063 #define __FUNCT__ "SNES_KSPSolve" 3064 PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 3065 { 3066 PetscErrorCode ierr; 3067 3068 PetscFunctionBegin; 3069 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3070 ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3071 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3072 PetscFunctionReturn(0); 3073 } 3074 3075 #undef __FUNCT__ 3076 #define __FUNCT__ "SNESSetDM" 3077 /*@ 3078 SNESSetDM - Sets the DM that may be used by some preconditioners 3079 3080 Logically Collective on SNES 3081 3082 Input Parameters: 3083 + snes - the preconditioner context 3084 - dm - the dm 3085 3086 Level: intermediate 3087 3088 3089 .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 3090 @*/ 3091 PetscErrorCode SNESSetDM(SNES snes,DM dm) 3092 { 3093 PetscErrorCode ierr; 3094 KSP ksp; 3095 3096 PetscFunctionBegin; 3097 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3098 ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr); 3099 if (snes->dm) {ierr = DMDestroy(snes->dm);CHKERRQ(ierr);} 3100 snes->dm = dm; 3101 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3102 ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3103 ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 3104 PetscFunctionReturn(0); 3105 } 3106 3107 #undef __FUNCT__ 3108 #define __FUNCT__ "SNESGetDM" 3109 /*@ 3110 SNESGetDM - Gets the DM that may be used by some preconditioners 3111 3112 Not Collective but DM obtained is parallel on SNES 3113 3114 Input Parameter: 3115 . snes - the preconditioner context 3116 3117 Output Parameter: 3118 . dm - the dm 3119 3120 Level: intermediate 3121 3122 3123 .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 3124 @*/ 3125 PetscErrorCode SNESGetDM(SNES snes,DM *dm) 3126 { 3127 PetscFunctionBegin; 3128 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3129 *dm = snes->dm; 3130 PetscFunctionReturn(0); 3131 } 3132 3133 #if defined(PETSC_HAVE_MATLAB_ENGINE) 3134 #include <mex.h> 3135 3136 typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 3137 3138 #undef __FUNCT__ 3139 #define __FUNCT__ "SNESComputeFunction_Matlab" 3140 /* 3141 SNESComputeFunction_Matlab - Calls the function that has been set with 3142 SNESSetFunctionMatlab(). 3143 3144 Collective on SNES 3145 3146 Input Parameters: 3147 + snes - the SNES context 3148 - x - input vector 3149 3150 Output Parameter: 3151 . y - function vector, as set by SNESSetFunction() 3152 3153 Notes: 3154 SNESComputeFunction() is typically used within nonlinear solvers 3155 implementations, so most users would not generally call this routine 3156 themselves. 3157 3158 Level: developer 3159 3160 .keywords: SNES, nonlinear, compute, function 3161 3162 .seealso: SNESSetFunction(), SNESGetFunction() 3163 */ 3164 PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 3165 { 3166 PetscErrorCode ierr; 3167 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3168 int nlhs = 1,nrhs = 5; 3169 mxArray *plhs[1],*prhs[5]; 3170 long long int lx = 0,ly = 0,ls = 0; 3171 3172 PetscFunctionBegin; 3173 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3174 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3175 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3176 PetscCheckSameComm(snes,1,x,2); 3177 PetscCheckSameComm(snes,1,y,3); 3178 3179 /* call Matlab function in ctx with arguments x and y */ 3180 3181 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3182 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3183 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 3184 prhs[0] = mxCreateDoubleScalar((double)ls); 3185 prhs[1] = mxCreateDoubleScalar((double)lx); 3186 prhs[2] = mxCreateDoubleScalar((double)ly); 3187 prhs[3] = mxCreateString(sctx->funcname); 3188 prhs[4] = sctx->ctx; 3189 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 3190 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3191 mxDestroyArray(prhs[0]); 3192 mxDestroyArray(prhs[1]); 3193 mxDestroyArray(prhs[2]); 3194 mxDestroyArray(prhs[3]); 3195 mxDestroyArray(plhs[0]); 3196 PetscFunctionReturn(0); 3197 } 3198 3199 3200 #undef __FUNCT__ 3201 #define __FUNCT__ "SNESSetFunctionMatlab" 3202 /* 3203 SNESSetFunctionMatlab - Sets the function evaluation routine and function 3204 vector for use by the SNES routines in solving systems of nonlinear 3205 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3206 3207 Logically Collective on SNES 3208 3209 Input Parameters: 3210 + snes - the SNES context 3211 . r - vector to store function value 3212 - func - function evaluation routine 3213 3214 Calling sequence of func: 3215 $ func (SNES snes,Vec x,Vec f,void *ctx); 3216 3217 3218 Notes: 3219 The Newton-like methods typically solve linear systems of the form 3220 $ f'(x) x = -f(x), 3221 where f'(x) denotes the Jacobian matrix and f(x) is the function. 3222 3223 Level: beginner 3224 3225 .keywords: SNES, nonlinear, set, function 3226 3227 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3228 */ 3229 PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 3230 { 3231 PetscErrorCode ierr; 3232 SNESMatlabContext *sctx; 3233 3234 PetscFunctionBegin; 3235 /* currently sctx is memory bleed */ 3236 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3237 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3238 /* 3239 This should work, but it doesn't 3240 sctx->ctx = ctx; 3241 mexMakeArrayPersistent(sctx->ctx); 3242 */ 3243 sctx->ctx = mxDuplicateArray(ctx); 3244 ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 3245 PetscFunctionReturn(0); 3246 } 3247 3248 #undef __FUNCT__ 3249 #define __FUNCT__ "SNESComputeJacobian_Matlab" 3250 /* 3251 SNESComputeJacobian_Matlab - Calls the function that has been set with 3252 SNESSetJacobianMatlab(). 3253 3254 Collective on SNES 3255 3256 Input Parameters: 3257 + snes - the SNES context 3258 . x - input vector 3259 . A, B - the matrices 3260 - ctx - user context 3261 3262 Output Parameter: 3263 . flag - structure of the matrix 3264 3265 Level: developer 3266 3267 .keywords: SNES, nonlinear, compute, function 3268 3269 .seealso: SNESSetFunction(), SNESGetFunction() 3270 @*/ 3271 PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 3272 { 3273 PetscErrorCode ierr; 3274 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3275 int nlhs = 2,nrhs = 6; 3276 mxArray *plhs[2],*prhs[6]; 3277 long long int lx = 0,lA = 0,ls = 0, lB = 0; 3278 3279 PetscFunctionBegin; 3280 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3281 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3282 3283 /* call Matlab function in ctx with arguments x and y */ 3284 3285 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3286 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3287 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 3288 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 3289 prhs[0] = mxCreateDoubleScalar((double)ls); 3290 prhs[1] = mxCreateDoubleScalar((double)lx); 3291 prhs[2] = mxCreateDoubleScalar((double)lA); 3292 prhs[3] = mxCreateDoubleScalar((double)lB); 3293 prhs[4] = mxCreateString(sctx->funcname); 3294 prhs[5] = sctx->ctx; 3295 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 3296 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3297 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 3298 mxDestroyArray(prhs[0]); 3299 mxDestroyArray(prhs[1]); 3300 mxDestroyArray(prhs[2]); 3301 mxDestroyArray(prhs[3]); 3302 mxDestroyArray(prhs[4]); 3303 mxDestroyArray(plhs[0]); 3304 mxDestroyArray(plhs[1]); 3305 PetscFunctionReturn(0); 3306 } 3307 3308 3309 #undef __FUNCT__ 3310 #define __FUNCT__ "SNESSetJacobianMatlab" 3311 /* 3312 SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 3313 vector for use by the SNES routines in solving systems of nonlinear 3314 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3315 3316 Logically Collective on SNES 3317 3318 Input Parameters: 3319 + snes - the SNES context 3320 . A,B - Jacobian matrices 3321 . func - function evaluation routine 3322 - ctx - user context 3323 3324 Calling sequence of func: 3325 $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 3326 3327 3328 Level: developer 3329 3330 .keywords: SNES, nonlinear, set, function 3331 3332 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3333 */ 3334 PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 3335 { 3336 PetscErrorCode ierr; 3337 SNESMatlabContext *sctx; 3338 3339 PetscFunctionBegin; 3340 /* currently sctx is memory bleed */ 3341 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3342 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3343 /* 3344 This should work, but it doesn't 3345 sctx->ctx = ctx; 3346 mexMakeArrayPersistent(sctx->ctx); 3347 */ 3348 sctx->ctx = mxDuplicateArray(ctx); 3349 ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 3350 PetscFunctionReturn(0); 3351 } 3352 3353 #undef __FUNCT__ 3354 #define __FUNCT__ "SNESMonitor_Matlab" 3355 /* 3356 SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 3357 3358 Collective on SNES 3359 3360 .seealso: SNESSetFunction(), SNESGetFunction() 3361 @*/ 3362 PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 3363 { 3364 PetscErrorCode ierr; 3365 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3366 int nlhs = 1,nrhs = 6; 3367 mxArray *plhs[1],*prhs[6]; 3368 long long int lx = 0,ls = 0; 3369 Vec x=snes->vec_sol; 3370 3371 PetscFunctionBegin; 3372 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3373 3374 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3375 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3376 prhs[0] = mxCreateDoubleScalar((double)ls); 3377 prhs[1] = mxCreateDoubleScalar((double)it); 3378 prhs[2] = mxCreateDoubleScalar((double)fnorm); 3379 prhs[3] = mxCreateDoubleScalar((double)lx); 3380 prhs[4] = mxCreateString(sctx->funcname); 3381 prhs[5] = sctx->ctx; 3382 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 3383 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3384 mxDestroyArray(prhs[0]); 3385 mxDestroyArray(prhs[1]); 3386 mxDestroyArray(prhs[2]); 3387 mxDestroyArray(prhs[3]); 3388 mxDestroyArray(prhs[4]); 3389 mxDestroyArray(plhs[0]); 3390 PetscFunctionReturn(0); 3391 } 3392 3393 3394 #undef __FUNCT__ 3395 #define __FUNCT__ "SNESMonitorSetMatlab" 3396 /* 3397 SNESMonitorSetMatlab - Sets the monitor function from MATLAB 3398 3399 Level: developer 3400 3401 .keywords: SNES, nonlinear, set, function 3402 3403 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3404 */ 3405 PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 3406 { 3407 PetscErrorCode ierr; 3408 SNESMatlabContext *sctx; 3409 3410 PetscFunctionBegin; 3411 /* currently sctx is memory bleed */ 3412 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3413 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3414 /* 3415 This should work, but it doesn't 3416 sctx->ctx = ctx; 3417 mexMakeArrayPersistent(sctx->ctx); 3418 */ 3419 sctx->ctx = mxDuplicateArray(ctx); 3420 ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 3421 PetscFunctionReturn(0); 3422 } 3423 3424 #endif 3425