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