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