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