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