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