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