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