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