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