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) { 1570 if (snes->vec_rhs) { 1571 ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 1572 } else if (snes->vec_sol) { 1573 ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 1574 } else if (snes->dm) { 1575 ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1576 } 1577 } 1578 if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 1579 if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 1580 1581 if (!snes->vec_sol_update /* && snes->vec_sol */) { 1582 ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 1583 ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 1584 } 1585 1586 if (!snes->ops->computejacobian && snes->dm) { 1587 Mat J; 1588 ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1589 ierr = SNESSetJacobian(snes,J,J,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 1590 ierr = MatDestroy(&J);CHKERRQ(ierr); 1591 } else if (snes->ops->computejacobian == MatMFFDComputeJacobian) { 1592 Mat J; 1593 ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 1594 ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 1595 ierr = MatSetFromOptions(J);CHKERRQ(ierr); 1596 ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 1597 ierr = MatDestroy(&J);CHKERRQ(ierr); 1598 } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 1599 Mat J,B; 1600 ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 1601 ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 1602 ierr = MatSetFromOptions(J);CHKERRQ(ierr); 1603 ierr = DMGetMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 1604 ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,snes->funP);CHKERRQ(ierr); 1605 ierr = MatDestroy(&J);CHKERRQ(ierr); 1606 ierr = MatDestroy(&B);CHKERRQ(ierr); 1607 } else if (snes->dm && !snes->jacobian_pre){ 1608 Mat J; 1609 ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1610 ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1611 ierr = MatDestroy(&J);CHKERRQ(ierr); 1612 } 1613 if (!snes->ops->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction() or call SNESSetDM()"); 1614 if (!snes->vec_func) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a vector when calling SNESSetFunction() or call SNESSetDM()"); 1615 1616 if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 1617 1618 if (snes->ops->usercompute && !snes->user) { 1619 ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 1620 } 1621 1622 if (snes->ops->setup) { 1623 ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 1624 } 1625 1626 snes->setupcalled = PETSC_TRUE; 1627 PetscFunctionReturn(0); 1628 } 1629 1630 #undef __FUNCT__ 1631 #define __FUNCT__ "SNESReset" 1632 /*@ 1633 SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 1634 1635 Collective on SNES 1636 1637 Input Parameter: 1638 . snes - iterative context obtained from SNESCreate() 1639 1640 Level: intermediate 1641 1642 Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 1643 1644 .keywords: SNES, destroy 1645 1646 .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 1647 @*/ 1648 PetscErrorCode SNESReset(SNES snes) 1649 { 1650 PetscErrorCode ierr; 1651 1652 PetscFunctionBegin; 1653 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1654 if (snes->ops->userdestroy && snes->user) { 1655 ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 1656 snes->user = PETSC_NULL; 1657 } 1658 if (snes->ops->computejacobian == SNESDefaultComputeJacobianColor && snes->dm) { 1659 ierr = MatFDColoringDestroy((MatFDColoring*)&snes->jacP);CHKERRQ(ierr); 1660 snes->ops->computejacobian = PETSC_NULL; 1661 } 1662 1663 if (snes->ops->reset) { 1664 ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 1665 } 1666 if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 1667 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 1668 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 1669 ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 1670 ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 1671 ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 1672 ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 1673 if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 1674 if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);} 1675 snes->nwork = snes->nvwork = 0; 1676 snes->setupcalled = PETSC_FALSE; 1677 PetscFunctionReturn(0); 1678 } 1679 1680 #undef __FUNCT__ 1681 #define __FUNCT__ "SNESDestroy" 1682 /*@ 1683 SNESDestroy - Destroys the nonlinear solver context that was created 1684 with SNESCreate(). 1685 1686 Collective on SNES 1687 1688 Input Parameter: 1689 . snes - the SNES context 1690 1691 Level: beginner 1692 1693 .keywords: SNES, nonlinear, destroy 1694 1695 .seealso: SNESCreate(), SNESSolve() 1696 @*/ 1697 PetscErrorCode SNESDestroy(SNES *snes) 1698 { 1699 PetscErrorCode ierr; 1700 1701 PetscFunctionBegin; 1702 if (!*snes) PetscFunctionReturn(0); 1703 PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 1704 if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 1705 1706 ierr = SNESReset((*snes));CHKERRQ(ierr); 1707 1708 /* if memory was published with AMS then destroy it */ 1709 ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 1710 if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 1711 1712 ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 1713 ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 1714 1715 ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 1716 if ((*snes)->ops->convergeddestroy) { 1717 ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 1718 } 1719 if ((*snes)->conv_malloc) { 1720 ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 1721 ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 1722 } 1723 ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 1724 ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 1725 PetscFunctionReturn(0); 1726 } 1727 1728 /* ----------- Routines to set solver parameters ---------- */ 1729 1730 #undef __FUNCT__ 1731 #define __FUNCT__ "SNESSetLagPreconditioner" 1732 /*@ 1733 SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 1734 1735 Logically Collective on SNES 1736 1737 Input Parameters: 1738 + snes - the SNES context 1739 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1740 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1741 1742 Options Database Keys: 1743 . -snes_lag_preconditioner <lag> 1744 1745 Notes: 1746 The default is 1 1747 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1748 If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 1749 1750 Level: intermediate 1751 1752 .keywords: SNES, nonlinear, set, convergence, tolerances 1753 1754 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1755 1756 @*/ 1757 PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 1758 { 1759 PetscFunctionBegin; 1760 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1761 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1762 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1763 PetscValidLogicalCollectiveInt(snes,lag,2); 1764 snes->lagpreconditioner = lag; 1765 PetscFunctionReturn(0); 1766 } 1767 1768 #undef __FUNCT__ 1769 #define __FUNCT__ "SNESSetGridSequence" 1770 /*@ 1771 SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 1772 1773 Logically Collective on SNES 1774 1775 Input Parameters: 1776 + snes - the SNES context 1777 - steps - the number of refinements to do, defaults to 0 1778 1779 Options Database Keys: 1780 . -snes_grid_sequence <steps> 1781 1782 Level: intermediate 1783 1784 .keywords: SNES, nonlinear, set, convergence, tolerances 1785 1786 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1787 1788 @*/ 1789 PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 1790 { 1791 PetscFunctionBegin; 1792 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1793 PetscValidLogicalCollectiveInt(snes,steps,2); 1794 snes->gridsequence = steps; 1795 PetscFunctionReturn(0); 1796 } 1797 1798 #undef __FUNCT__ 1799 #define __FUNCT__ "SNESGetLagPreconditioner" 1800 /*@ 1801 SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 1802 1803 Not Collective 1804 1805 Input Parameter: 1806 . snes - the SNES context 1807 1808 Output Parameter: 1809 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1810 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1811 1812 Options Database Keys: 1813 . -snes_lag_preconditioner <lag> 1814 1815 Notes: 1816 The default is 1 1817 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1818 1819 Level: intermediate 1820 1821 .keywords: SNES, nonlinear, set, convergence, tolerances 1822 1823 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 1824 1825 @*/ 1826 PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 1827 { 1828 PetscFunctionBegin; 1829 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1830 *lag = snes->lagpreconditioner; 1831 PetscFunctionReturn(0); 1832 } 1833 1834 #undef __FUNCT__ 1835 #define __FUNCT__ "SNESSetLagJacobian" 1836 /*@ 1837 SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 1838 often the preconditioner is rebuilt. 1839 1840 Logically Collective on SNES 1841 1842 Input Parameters: 1843 + snes - the SNES context 1844 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1845 the Jacobian is built etc. -2 means rebuild at next chance but then never again 1846 1847 Options Database Keys: 1848 . -snes_lag_jacobian <lag> 1849 1850 Notes: 1851 The default is 1 1852 The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1853 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 1854 at the next Newton step but never again (unless it is reset to another value) 1855 1856 Level: intermediate 1857 1858 .keywords: SNES, nonlinear, set, convergence, tolerances 1859 1860 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 1861 1862 @*/ 1863 PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 1864 { 1865 PetscFunctionBegin; 1866 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1867 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1868 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1869 PetscValidLogicalCollectiveInt(snes,lag,2); 1870 snes->lagjacobian = lag; 1871 PetscFunctionReturn(0); 1872 } 1873 1874 #undef __FUNCT__ 1875 #define __FUNCT__ "SNESGetLagJacobian" 1876 /*@ 1877 SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 1878 1879 Not Collective 1880 1881 Input Parameter: 1882 . snes - the SNES context 1883 1884 Output Parameter: 1885 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1886 the Jacobian is built etc. 1887 1888 Options Database Keys: 1889 . -snes_lag_jacobian <lag> 1890 1891 Notes: 1892 The default is 1 1893 The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1894 1895 Level: intermediate 1896 1897 .keywords: SNES, nonlinear, set, convergence, tolerances 1898 1899 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 1900 1901 @*/ 1902 PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 1903 { 1904 PetscFunctionBegin; 1905 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1906 *lag = snes->lagjacobian; 1907 PetscFunctionReturn(0); 1908 } 1909 1910 #undef __FUNCT__ 1911 #define __FUNCT__ "SNESSetTolerances" 1912 /*@ 1913 SNESSetTolerances - Sets various parameters used in convergence tests. 1914 1915 Logically Collective on SNES 1916 1917 Input Parameters: 1918 + snes - the SNES context 1919 . abstol - absolute convergence tolerance 1920 . rtol - relative convergence tolerance 1921 . stol - convergence tolerance in terms of the norm 1922 of the change in the solution between steps 1923 . maxit - maximum number of iterations 1924 - maxf - maximum number of function evaluations 1925 1926 Options Database Keys: 1927 + -snes_atol <abstol> - Sets abstol 1928 . -snes_rtol <rtol> - Sets rtol 1929 . -snes_stol <stol> - Sets stol 1930 . -snes_max_it <maxit> - Sets maxit 1931 - -snes_max_funcs <maxf> - Sets maxf 1932 1933 Notes: 1934 The default maximum number of iterations is 50. 1935 The default maximum number of function evaluations is 1000. 1936 1937 Level: intermediate 1938 1939 .keywords: SNES, nonlinear, set, convergence, tolerances 1940 1941 .seealso: SNESSetTrustRegionTolerance() 1942 @*/ 1943 PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 1944 { 1945 PetscFunctionBegin; 1946 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1947 PetscValidLogicalCollectiveReal(snes,abstol,2); 1948 PetscValidLogicalCollectiveReal(snes,rtol,3); 1949 PetscValidLogicalCollectiveReal(snes,stol,4); 1950 PetscValidLogicalCollectiveInt(snes,maxit,5); 1951 PetscValidLogicalCollectiveInt(snes,maxf,6); 1952 1953 if (abstol != PETSC_DEFAULT) snes->abstol = abstol; 1954 if (rtol != PETSC_DEFAULT) snes->rtol = rtol; 1955 if (stol != PETSC_DEFAULT) snes->xtol = stol; 1956 if (maxit != PETSC_DEFAULT) snes->max_its = maxit; 1957 if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf; 1958 PetscFunctionReturn(0); 1959 } 1960 1961 #undef __FUNCT__ 1962 #define __FUNCT__ "SNESGetTolerances" 1963 /*@ 1964 SNESGetTolerances - Gets various parameters used in convergence tests. 1965 1966 Not Collective 1967 1968 Input Parameters: 1969 + snes - the SNES context 1970 . atol - absolute convergence tolerance 1971 . rtol - relative convergence tolerance 1972 . stol - convergence tolerance in terms of the norm 1973 of the change in the solution between steps 1974 . maxit - maximum number of iterations 1975 - maxf - maximum number of function evaluations 1976 1977 Notes: 1978 The user can specify PETSC_NULL for any parameter that is not needed. 1979 1980 Level: intermediate 1981 1982 .keywords: SNES, nonlinear, get, convergence, tolerances 1983 1984 .seealso: SNESSetTolerances() 1985 @*/ 1986 PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 1987 { 1988 PetscFunctionBegin; 1989 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1990 if (atol) *atol = snes->abstol; 1991 if (rtol) *rtol = snes->rtol; 1992 if (stol) *stol = snes->xtol; 1993 if (maxit) *maxit = snes->max_its; 1994 if (maxf) *maxf = snes->max_funcs; 1995 PetscFunctionReturn(0); 1996 } 1997 1998 #undef __FUNCT__ 1999 #define __FUNCT__ "SNESSetTrustRegionTolerance" 2000 /*@ 2001 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 2002 2003 Logically Collective on SNES 2004 2005 Input Parameters: 2006 + snes - the SNES context 2007 - tol - tolerance 2008 2009 Options Database Key: 2010 . -snes_trtol <tol> - Sets tol 2011 2012 Level: intermediate 2013 2014 .keywords: SNES, nonlinear, set, trust region, tolerance 2015 2016 .seealso: SNESSetTolerances() 2017 @*/ 2018 PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 2019 { 2020 PetscFunctionBegin; 2021 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2022 PetscValidLogicalCollectiveReal(snes,tol,2); 2023 snes->deltatol = tol; 2024 PetscFunctionReturn(0); 2025 } 2026 2027 /* 2028 Duplicate the lg monitors for SNES from KSP; for some reason with 2029 dynamic libraries things don't work under Sun4 if we just use 2030 macros instead of functions 2031 */ 2032 #undef __FUNCT__ 2033 #define __FUNCT__ "SNESMonitorLG" 2034 PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2035 { 2036 PetscErrorCode ierr; 2037 2038 PetscFunctionBegin; 2039 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2040 ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2041 PetscFunctionReturn(0); 2042 } 2043 2044 #undef __FUNCT__ 2045 #define __FUNCT__ "SNESMonitorLGCreate" 2046 PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2047 { 2048 PetscErrorCode ierr; 2049 2050 PetscFunctionBegin; 2051 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2052 PetscFunctionReturn(0); 2053 } 2054 2055 #undef __FUNCT__ 2056 #define __FUNCT__ "SNESMonitorLGDestroy" 2057 PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2058 { 2059 PetscErrorCode ierr; 2060 2061 PetscFunctionBegin; 2062 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2063 PetscFunctionReturn(0); 2064 } 2065 2066 extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2067 #undef __FUNCT__ 2068 #define __FUNCT__ "SNESMonitorLGRange" 2069 PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2070 { 2071 PetscDrawLG lg; 2072 PetscErrorCode ierr; 2073 PetscReal x,y,per; 2074 PetscViewer v = (PetscViewer)monctx; 2075 static PetscReal prev; /* should be in the context */ 2076 PetscDraw draw; 2077 PetscFunctionBegin; 2078 if (!monctx) { 2079 MPI_Comm comm; 2080 2081 ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2082 v = PETSC_VIEWER_DRAW_(comm); 2083 } 2084 ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2085 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2086 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2087 ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2088 x = (PetscReal) n; 2089 if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2090 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2091 if (n < 20 || !(n % 5)) { 2092 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2093 } 2094 2095 ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2096 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2097 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2098 ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2099 ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2100 x = (PetscReal) n; 2101 y = 100.0*per; 2102 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2103 if (n < 20 || !(n % 5)) { 2104 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2105 } 2106 2107 ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2108 if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2109 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2110 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2111 x = (PetscReal) n; 2112 y = (prev - rnorm)/prev; 2113 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2114 if (n < 20 || !(n % 5)) { 2115 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2116 } 2117 2118 ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2119 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2120 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2121 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2122 x = (PetscReal) n; 2123 y = (prev - rnorm)/(prev*per); 2124 if (n > 2) { /*skip initial crazy value */ 2125 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2126 } 2127 if (n < 20 || !(n % 5)) { 2128 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2129 } 2130 prev = rnorm; 2131 PetscFunctionReturn(0); 2132 } 2133 2134 #undef __FUNCT__ 2135 #define __FUNCT__ "SNESMonitorLGRangeCreate" 2136 PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2137 { 2138 PetscErrorCode ierr; 2139 2140 PetscFunctionBegin; 2141 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2142 PetscFunctionReturn(0); 2143 } 2144 2145 #undef __FUNCT__ 2146 #define __FUNCT__ "SNESMonitorLGRangeDestroy" 2147 PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2148 { 2149 PetscErrorCode ierr; 2150 2151 PetscFunctionBegin; 2152 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2153 PetscFunctionReturn(0); 2154 } 2155 2156 #undef __FUNCT__ 2157 #define __FUNCT__ "SNESMonitor" 2158 /* 2159 Runs the user provided monitor routines, if they exists. 2160 */ 2161 PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 2162 { 2163 PetscErrorCode ierr; 2164 PetscInt i,n = snes->numbermonitors; 2165 2166 PetscFunctionBegin; 2167 for (i=0; i<n; i++) { 2168 ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 2169 } 2170 PetscFunctionReturn(0); 2171 } 2172 2173 /* ------------ Routines to set performance monitoring options ----------- */ 2174 2175 #undef __FUNCT__ 2176 #define __FUNCT__ "SNESMonitorSet" 2177 /*@C 2178 SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 2179 iteration of the nonlinear solver to display the iteration's 2180 progress. 2181 2182 Logically Collective on SNES 2183 2184 Input Parameters: 2185 + snes - the SNES context 2186 . func - monitoring routine 2187 . mctx - [optional] user-defined context for private data for the 2188 monitor routine (use PETSC_NULL if no context is desired) 2189 - monitordestroy - [optional] routine that frees monitor context 2190 (may be PETSC_NULL) 2191 2192 Calling sequence of func: 2193 $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2194 2195 + snes - the SNES context 2196 . its - iteration number 2197 . norm - 2-norm function value (may be estimated) 2198 - mctx - [optional] monitoring context 2199 2200 Options Database Keys: 2201 + -snes_monitor - sets SNESMonitorDefault() 2202 . -snes_monitor_draw - sets line graph monitor, 2203 uses SNESMonitorLGCreate() 2204 - -snes_monitor_cancel - cancels all monitors that have 2205 been hardwired into a code by 2206 calls to SNESMonitorSet(), but 2207 does not cancel those set via 2208 the options database. 2209 2210 Notes: 2211 Several different monitoring routines may be set by calling 2212 SNESMonitorSet() multiple times; all will be called in the 2213 order in which they were set. 2214 2215 Fortran notes: Only a single monitor function can be set for each SNES object 2216 2217 Level: intermediate 2218 2219 .keywords: SNES, nonlinear, set, monitor 2220 2221 .seealso: SNESMonitorDefault(), SNESMonitorCancel() 2222 @*/ 2223 PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 2224 { 2225 PetscInt i; 2226 PetscErrorCode ierr; 2227 2228 PetscFunctionBegin; 2229 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2230 if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2231 for (i=0; i<snes->numbermonitors;i++) { 2232 if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2233 if (monitordestroy) { 2234 ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2235 } 2236 PetscFunctionReturn(0); 2237 } 2238 } 2239 snes->monitor[snes->numbermonitors] = monitor; 2240 snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2241 snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 2242 PetscFunctionReturn(0); 2243 } 2244 2245 #undef __FUNCT__ 2246 #define __FUNCT__ "SNESMonitorCancel" 2247 /*@C 2248 SNESMonitorCancel - Clears all the monitor functions for a SNES object. 2249 2250 Logically Collective on SNES 2251 2252 Input Parameters: 2253 . snes - the SNES context 2254 2255 Options Database Key: 2256 . -snes_monitor_cancel - cancels all monitors that have been hardwired 2257 into a code by calls to SNESMonitorSet(), but does not cancel those 2258 set via the options database 2259 2260 Notes: 2261 There is no way to clear one specific monitor from a SNES object. 2262 2263 Level: intermediate 2264 2265 .keywords: SNES, nonlinear, set, monitor 2266 2267 .seealso: SNESMonitorDefault(), SNESMonitorSet() 2268 @*/ 2269 PetscErrorCode SNESMonitorCancel(SNES snes) 2270 { 2271 PetscErrorCode ierr; 2272 PetscInt i; 2273 2274 PetscFunctionBegin; 2275 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2276 for (i=0; i<snes->numbermonitors; i++) { 2277 if (snes->monitordestroy[i]) { 2278 ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2279 } 2280 } 2281 snes->numbermonitors = 0; 2282 PetscFunctionReturn(0); 2283 } 2284 2285 #undef __FUNCT__ 2286 #define __FUNCT__ "SNESSetConvergenceTest" 2287 /*@C 2288 SNESSetConvergenceTest - Sets the function that is to be used 2289 to test for convergence of the nonlinear iterative solution. 2290 2291 Logically Collective on SNES 2292 2293 Input Parameters: 2294 + snes - the SNES context 2295 . func - routine to test for convergence 2296 . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 2297 - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 2298 2299 Calling sequence of func: 2300 $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2301 2302 + snes - the SNES context 2303 . it - current iteration (0 is the first and is before any Newton step) 2304 . cctx - [optional] convergence context 2305 . reason - reason for convergence/divergence 2306 . xnorm - 2-norm of current iterate 2307 . gnorm - 2-norm of current step 2308 - f - 2-norm of function 2309 2310 Level: advanced 2311 2312 .keywords: SNES, nonlinear, set, convergence, test 2313 2314 .seealso: SNESDefaultConverged(), SNESSkipConverged() 2315 @*/ 2316 PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 2317 { 2318 PetscErrorCode ierr; 2319 2320 PetscFunctionBegin; 2321 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2322 if (!func) func = SNESSkipConverged; 2323 if (snes->ops->convergeddestroy) { 2324 ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 2325 } 2326 snes->ops->converged = func; 2327 snes->ops->convergeddestroy = destroy; 2328 snes->cnvP = cctx; 2329 PetscFunctionReturn(0); 2330 } 2331 2332 #undef __FUNCT__ 2333 #define __FUNCT__ "SNESGetConvergedReason" 2334 /*@ 2335 SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2336 2337 Not Collective 2338 2339 Input Parameter: 2340 . snes - the SNES context 2341 2342 Output Parameter: 2343 . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2344 manual pages for the individual convergence tests for complete lists 2345 2346 Level: intermediate 2347 2348 Notes: Can only be called after the call the SNESSolve() is complete. 2349 2350 .keywords: SNES, nonlinear, set, convergence, test 2351 2352 .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2353 @*/ 2354 PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2355 { 2356 PetscFunctionBegin; 2357 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2358 PetscValidPointer(reason,2); 2359 *reason = snes->reason; 2360 PetscFunctionReturn(0); 2361 } 2362 2363 #undef __FUNCT__ 2364 #define __FUNCT__ "SNESSetConvergenceHistory" 2365 /*@ 2366 SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2367 2368 Logically Collective on SNES 2369 2370 Input Parameters: 2371 + snes - iterative context obtained from SNESCreate() 2372 . a - array to hold history, this array will contain the function norms computed at each step 2373 . its - integer array holds the number of linear iterations for each solve. 2374 . na - size of a and its 2375 - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2376 else it continues storing new values for new nonlinear solves after the old ones 2377 2378 Notes: 2379 If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2380 default array of length 10000 is allocated. 2381 2382 This routine is useful, e.g., when running a code for purposes 2383 of accurate performance monitoring, when no I/O should be done 2384 during the section of code that is being timed. 2385 2386 Level: intermediate 2387 2388 .keywords: SNES, set, convergence, history 2389 2390 .seealso: SNESGetConvergenceHistory() 2391 2392 @*/ 2393 PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2394 { 2395 PetscErrorCode ierr; 2396 2397 PetscFunctionBegin; 2398 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2399 if (na) PetscValidScalarPointer(a,2); 2400 if (its) PetscValidIntPointer(its,3); 2401 if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2402 if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2403 ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2404 ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2405 snes->conv_malloc = PETSC_TRUE; 2406 } 2407 snes->conv_hist = a; 2408 snes->conv_hist_its = its; 2409 snes->conv_hist_max = na; 2410 snes->conv_hist_len = 0; 2411 snes->conv_hist_reset = reset; 2412 PetscFunctionReturn(0); 2413 } 2414 2415 #if defined(PETSC_HAVE_MATLAB_ENGINE) 2416 #include <engine.h> /* MATLAB include file */ 2417 #include <mex.h> /* MATLAB include file */ 2418 EXTERN_C_BEGIN 2419 #undef __FUNCT__ 2420 #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2421 mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2422 { 2423 mxArray *mat; 2424 PetscInt i; 2425 PetscReal *ar; 2426 2427 PetscFunctionBegin; 2428 mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2429 ar = (PetscReal*) mxGetData(mat); 2430 for (i=0; i<snes->conv_hist_len; i++) { 2431 ar[i] = snes->conv_hist[i]; 2432 } 2433 PetscFunctionReturn(mat); 2434 } 2435 EXTERN_C_END 2436 #endif 2437 2438 2439 #undef __FUNCT__ 2440 #define __FUNCT__ "SNESGetConvergenceHistory" 2441 /*@C 2442 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 2443 2444 Not Collective 2445 2446 Input Parameter: 2447 . snes - iterative context obtained from SNESCreate() 2448 2449 Output Parameters: 2450 . a - array to hold history 2451 . its - integer array holds the number of linear iterations (or 2452 negative if not converged) for each solve. 2453 - na - size of a and its 2454 2455 Notes: 2456 The calling sequence for this routine in Fortran is 2457 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 2458 2459 This routine is useful, e.g., when running a code for purposes 2460 of accurate performance monitoring, when no I/O should be done 2461 during the section of code that is being timed. 2462 2463 Level: intermediate 2464 2465 .keywords: SNES, get, convergence, history 2466 2467 .seealso: SNESSetConvergencHistory() 2468 2469 @*/ 2470 PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 2471 { 2472 PetscFunctionBegin; 2473 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2474 if (a) *a = snes->conv_hist; 2475 if (its) *its = snes->conv_hist_its; 2476 if (na) *na = snes->conv_hist_len; 2477 PetscFunctionReturn(0); 2478 } 2479 2480 #undef __FUNCT__ 2481 #define __FUNCT__ "SNESSetUpdate" 2482 /*@C 2483 SNESSetUpdate - Sets the general-purpose update function called 2484 at the beginning of every iteration of the nonlinear solve. Specifically 2485 it is called just before the Jacobian is "evaluated". 2486 2487 Logically Collective on SNES 2488 2489 Input Parameters: 2490 . snes - The nonlinear solver context 2491 . func - The function 2492 2493 Calling sequence of func: 2494 . func (SNES snes, PetscInt step); 2495 2496 . step - The current step of the iteration 2497 2498 Level: advanced 2499 2500 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() 2501 This is not used by most users. 2502 2503 .keywords: SNES, update 2504 2505 .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 2506 @*/ 2507 PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 2508 { 2509 PetscFunctionBegin; 2510 PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 2511 snes->ops->update = func; 2512 PetscFunctionReturn(0); 2513 } 2514 2515 #undef __FUNCT__ 2516 #define __FUNCT__ "SNESDefaultUpdate" 2517 /*@ 2518 SNESDefaultUpdate - The default update function which does nothing. 2519 2520 Not collective 2521 2522 Input Parameters: 2523 . snes - The nonlinear solver context 2524 . step - The current step of the iteration 2525 2526 Level: intermediate 2527 2528 .keywords: SNES, update 2529 .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 2530 @*/ 2531 PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 2532 { 2533 PetscFunctionBegin; 2534 PetscFunctionReturn(0); 2535 } 2536 2537 #undef __FUNCT__ 2538 #define __FUNCT__ "SNESScaleStep_Private" 2539 /* 2540 SNESScaleStep_Private - Scales a step so that its length is less than the 2541 positive parameter delta. 2542 2543 Input Parameters: 2544 + snes - the SNES context 2545 . y - approximate solution of linear system 2546 . fnorm - 2-norm of current function 2547 - delta - trust region size 2548 2549 Output Parameters: 2550 + gpnorm - predicted function norm at the new point, assuming local 2551 linearization. The value is zero if the step lies within the trust 2552 region, and exceeds zero otherwise. 2553 - ynorm - 2-norm of the step 2554 2555 Note: 2556 For non-trust region methods such as SNESLS, the parameter delta 2557 is set to be the maximum allowable step size. 2558 2559 .keywords: SNES, nonlinear, scale, step 2560 */ 2561 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 2562 { 2563 PetscReal nrm; 2564 PetscScalar cnorm; 2565 PetscErrorCode ierr; 2566 2567 PetscFunctionBegin; 2568 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2569 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 2570 PetscCheckSameComm(snes,1,y,2); 2571 2572 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 2573 if (nrm > *delta) { 2574 nrm = *delta/nrm; 2575 *gpnorm = (1.0 - nrm)*(*fnorm); 2576 cnorm = nrm; 2577 ierr = VecScale(y,cnorm);CHKERRQ(ierr); 2578 *ynorm = *delta; 2579 } else { 2580 *gpnorm = 0.0; 2581 *ynorm = nrm; 2582 } 2583 PetscFunctionReturn(0); 2584 } 2585 2586 #undef __FUNCT__ 2587 #define __FUNCT__ "SNESSolve" 2588 /*@C 2589 SNESSolve - Solves a nonlinear system F(x) = b. 2590 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 2591 2592 Collective on SNES 2593 2594 Input Parameters: 2595 + snes - the SNES context 2596 . b - the constant part of the equation, or PETSC_NULL to use zero. 2597 - x - the solution vector. 2598 2599 Notes: 2600 The user should initialize the vector,x, with the initial guess 2601 for the nonlinear solve prior to calling SNESSolve. In particular, 2602 to employ an initial guess of zero, the user should explicitly set 2603 this vector to zero by calling VecSet(). 2604 2605 Level: beginner 2606 2607 .keywords: SNES, nonlinear, solve 2608 2609 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian() 2610 @*/ 2611 PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 2612 { 2613 PetscErrorCode ierr; 2614 PetscBool flg; 2615 char filename[PETSC_MAX_PATH_LEN]; 2616 PetscViewer viewer; 2617 PetscInt grid; 2618 2619 PetscFunctionBegin; 2620 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2621 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2622 PetscCheckSameComm(snes,1,x,3); 2623 if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 2624 if (b) PetscCheckSameComm(snes,1,b,2); 2625 2626 for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 2627 for (grid=0; grid<snes->gridsequence+1; grid++) { 2628 2629 /* set solution vector */ 2630 if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 2631 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 2632 snes->vec_sol = x; 2633 /* set afine vector if provided */ 2634 if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 2635 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 2636 snes->vec_rhs = b; 2637 2638 ierr = SNESSetUp(snes);CHKERRQ(ierr); 2639 2640 if (!grid && snes->ops->computeinitialguess) { 2641 ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 2642 } 2643 2644 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 2645 snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 2646 2647 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 2648 ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 2649 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 2650 if (snes->domainerror){ 2651 snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 2652 snes->domainerror = PETSC_FALSE; 2653 } 2654 if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 2655 2656 ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 2657 if (flg && !PetscPreLoadingOn) { 2658 ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 2659 ierr = SNESView(snes,viewer);CHKERRQ(ierr); 2660 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2661 } 2662 2663 flg = PETSC_FALSE; 2664 ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 2665 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 2666 if (snes->printreason) { 2667 ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 2668 if (snes->reason > 0) { 2669 ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 2670 } else { 2671 ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 2672 } 2673 ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 2674 } 2675 2676 if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 2677 if (grid < snes->gridsequence) { 2678 DM fine; 2679 Vec xnew; 2680 Mat interp; 2681 2682 ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 2683 ierr = DMGetInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 2684 ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 2685 ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 2686 ierr = MatDestroy(&interp);CHKERRQ(ierr); 2687 x = xnew; 2688 2689 ierr = SNESReset(snes);CHKERRQ(ierr); 2690 ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 2691 ierr = DMDestroy(&fine);CHKERRQ(ierr); 2692 ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 2693 } 2694 } 2695 PetscFunctionReturn(0); 2696 } 2697 2698 /* --------- Internal routines for SNES Package --------- */ 2699 2700 #undef __FUNCT__ 2701 #define __FUNCT__ "SNESSetType" 2702 /*@C 2703 SNESSetType - Sets the method for the nonlinear solver. 2704 2705 Collective on SNES 2706 2707 Input Parameters: 2708 + snes - the SNES context 2709 - type - a known method 2710 2711 Options Database Key: 2712 . -snes_type <type> - Sets the method; use -help for a list 2713 of available methods (for instance, ls or tr) 2714 2715 Notes: 2716 See "petsc/include/petscsnes.h" for available methods (for instance) 2717 + SNESLS - Newton's method with line search 2718 (systems of nonlinear equations) 2719 . SNESTR - Newton's method with trust region 2720 (systems of nonlinear equations) 2721 2722 Normally, it is best to use the SNESSetFromOptions() command and then 2723 set the SNES solver type from the options database rather than by using 2724 this routine. Using the options database provides the user with 2725 maximum flexibility in evaluating the many nonlinear solvers. 2726 The SNESSetType() routine is provided for those situations where it 2727 is necessary to set the nonlinear solver independently of the command 2728 line or options database. This might be the case, for example, when 2729 the choice of solver changes during the execution of the program, 2730 and the user's application is taking responsibility for choosing the 2731 appropriate method. 2732 2733 Level: intermediate 2734 2735 .keywords: SNES, set, type 2736 2737 .seealso: SNESType, SNESCreate() 2738 2739 @*/ 2740 PetscErrorCode SNESSetType(SNES snes,const SNESType type) 2741 { 2742 PetscErrorCode ierr,(*r)(SNES); 2743 PetscBool match; 2744 2745 PetscFunctionBegin; 2746 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2747 PetscValidCharPointer(type,2); 2748 2749 ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 2750 if (match) PetscFunctionReturn(0); 2751 2752 ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 2753 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 2754 /* Destroy the previous private SNES context */ 2755 if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 2756 /* Reinitialize function pointers in SNESOps structure */ 2757 snes->ops->setup = 0; 2758 snes->ops->solve = 0; 2759 snes->ops->view = 0; 2760 snes->ops->setfromoptions = 0; 2761 snes->ops->destroy = 0; 2762 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 2763 snes->setupcalled = PETSC_FALSE; 2764 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 2765 ierr = (*r)(snes);CHKERRQ(ierr); 2766 #if defined(PETSC_HAVE_AMS) 2767 if (PetscAMSPublishAll) { 2768 ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 2769 } 2770 #endif 2771 PetscFunctionReturn(0); 2772 } 2773 2774 2775 /* --------------------------------------------------------------------- */ 2776 #undef __FUNCT__ 2777 #define __FUNCT__ "SNESRegisterDestroy" 2778 /*@ 2779 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 2780 registered by SNESRegisterDynamic(). 2781 2782 Not Collective 2783 2784 Level: advanced 2785 2786 .keywords: SNES, nonlinear, register, destroy 2787 2788 .seealso: SNESRegisterAll(), SNESRegisterAll() 2789 @*/ 2790 PetscErrorCode SNESRegisterDestroy(void) 2791 { 2792 PetscErrorCode ierr; 2793 2794 PetscFunctionBegin; 2795 ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 2796 SNESRegisterAllCalled = PETSC_FALSE; 2797 PetscFunctionReturn(0); 2798 } 2799 2800 #undef __FUNCT__ 2801 #define __FUNCT__ "SNESGetType" 2802 /*@C 2803 SNESGetType - Gets the SNES method type and name (as a string). 2804 2805 Not Collective 2806 2807 Input Parameter: 2808 . snes - nonlinear solver context 2809 2810 Output Parameter: 2811 . type - SNES method (a character string) 2812 2813 Level: intermediate 2814 2815 .keywords: SNES, nonlinear, get, type, name 2816 @*/ 2817 PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 2818 { 2819 PetscFunctionBegin; 2820 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2821 PetscValidPointer(type,2); 2822 *type = ((PetscObject)snes)->type_name; 2823 PetscFunctionReturn(0); 2824 } 2825 2826 #undef __FUNCT__ 2827 #define __FUNCT__ "SNESGetSolution" 2828 /*@ 2829 SNESGetSolution - Returns the vector where the approximate solution is 2830 stored. 2831 2832 Not Collective, but Vec is parallel if SNES is parallel 2833 2834 Input Parameter: 2835 . snes - the SNES context 2836 2837 Output Parameter: 2838 . x - the solution 2839 2840 Level: intermediate 2841 2842 .keywords: SNES, nonlinear, get, solution 2843 2844 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 2845 @*/ 2846 PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 2847 { 2848 PetscFunctionBegin; 2849 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2850 PetscValidPointer(x,2); 2851 *x = snes->vec_sol; 2852 PetscFunctionReturn(0); 2853 } 2854 2855 #undef __FUNCT__ 2856 #define __FUNCT__ "SNESGetSolutionUpdate" 2857 /*@ 2858 SNESGetSolutionUpdate - Returns the vector where the solution update is 2859 stored. 2860 2861 Not Collective, but Vec is parallel if SNES is parallel 2862 2863 Input Parameter: 2864 . snes - the SNES context 2865 2866 Output Parameter: 2867 . x - the solution update 2868 2869 Level: advanced 2870 2871 .keywords: SNES, nonlinear, get, solution, update 2872 2873 .seealso: SNESGetSolution(), SNESGetFunction() 2874 @*/ 2875 PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 2876 { 2877 PetscFunctionBegin; 2878 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2879 PetscValidPointer(x,2); 2880 *x = snes->vec_sol_update; 2881 PetscFunctionReturn(0); 2882 } 2883 2884 #undef __FUNCT__ 2885 #define __FUNCT__ "SNESGetFunction" 2886 /*@C 2887 SNESGetFunction - Returns the vector where the function is stored. 2888 2889 Not Collective, but Vec is parallel if SNES is parallel 2890 2891 Input Parameter: 2892 . snes - the SNES context 2893 2894 Output Parameter: 2895 + r - the function (or PETSC_NULL) 2896 . func - the function (or PETSC_NULL) 2897 - ctx - the function context (or PETSC_NULL) 2898 2899 Level: advanced 2900 2901 .keywords: SNES, nonlinear, get, function 2902 2903 .seealso: SNESSetFunction(), SNESGetSolution() 2904 @*/ 2905 PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 2906 { 2907 PetscFunctionBegin; 2908 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2909 if (r) *r = snes->vec_func; 2910 if (func) *func = snes->ops->computefunction; 2911 if (ctx) *ctx = snes->funP; 2912 PetscFunctionReturn(0); 2913 } 2914 2915 #undef __FUNCT__ 2916 #define __FUNCT__ "SNESSetOptionsPrefix" 2917 /*@C 2918 SNESSetOptionsPrefix - Sets the prefix used for searching for all 2919 SNES options in the database. 2920 2921 Logically Collective on SNES 2922 2923 Input Parameter: 2924 + snes - the SNES context 2925 - prefix - the prefix to prepend to all option names 2926 2927 Notes: 2928 A hyphen (-) must NOT be given at the beginning of the prefix name. 2929 The first character of all runtime options is AUTOMATICALLY the hyphen. 2930 2931 Level: advanced 2932 2933 .keywords: SNES, set, options, prefix, database 2934 2935 .seealso: SNESSetFromOptions() 2936 @*/ 2937 PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 2938 { 2939 PetscErrorCode ierr; 2940 2941 PetscFunctionBegin; 2942 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2943 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2944 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 2945 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2946 PetscFunctionReturn(0); 2947 } 2948 2949 #undef __FUNCT__ 2950 #define __FUNCT__ "SNESAppendOptionsPrefix" 2951 /*@C 2952 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 2953 SNES options in the database. 2954 2955 Logically Collective on SNES 2956 2957 Input Parameters: 2958 + snes - the SNES context 2959 - prefix - the prefix to prepend to all option names 2960 2961 Notes: 2962 A hyphen (-) must NOT be given at the beginning of the prefix name. 2963 The first character of all runtime options is AUTOMATICALLY the hyphen. 2964 2965 Level: advanced 2966 2967 .keywords: SNES, append, options, prefix, database 2968 2969 .seealso: SNESGetOptionsPrefix() 2970 @*/ 2971 PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 2972 { 2973 PetscErrorCode ierr; 2974 2975 PetscFunctionBegin; 2976 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2977 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2978 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 2979 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2980 PetscFunctionReturn(0); 2981 } 2982 2983 #undef __FUNCT__ 2984 #define __FUNCT__ "SNESGetOptionsPrefix" 2985 /*@C 2986 SNESGetOptionsPrefix - Sets the prefix used for searching for all 2987 SNES options in the database. 2988 2989 Not Collective 2990 2991 Input Parameter: 2992 . snes - the SNES context 2993 2994 Output Parameter: 2995 . prefix - pointer to the prefix string used 2996 2997 Notes: On the fortran side, the user should pass in a string 'prefix' of 2998 sufficient length to hold the prefix. 2999 3000 Level: advanced 3001 3002 .keywords: SNES, get, options, prefix, database 3003 3004 .seealso: SNESAppendOptionsPrefix() 3005 @*/ 3006 PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 3007 { 3008 PetscErrorCode ierr; 3009 3010 PetscFunctionBegin; 3011 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3012 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 3013 PetscFunctionReturn(0); 3014 } 3015 3016 3017 #undef __FUNCT__ 3018 #define __FUNCT__ "SNESRegister" 3019 /*@C 3020 SNESRegister - See SNESRegisterDynamic() 3021 3022 Level: advanced 3023 @*/ 3024 PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3025 { 3026 char fullname[PETSC_MAX_PATH_LEN]; 3027 PetscErrorCode ierr; 3028 3029 PetscFunctionBegin; 3030 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3031 ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3032 PetscFunctionReturn(0); 3033 } 3034 3035 #undef __FUNCT__ 3036 #define __FUNCT__ "SNESTestLocalMin" 3037 PetscErrorCode SNESTestLocalMin(SNES snes) 3038 { 3039 PetscErrorCode ierr; 3040 PetscInt N,i,j; 3041 Vec u,uh,fh; 3042 PetscScalar value; 3043 PetscReal norm; 3044 3045 PetscFunctionBegin; 3046 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3047 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3048 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3049 3050 /* currently only works for sequential */ 3051 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3052 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3053 for (i=0; i<N; i++) { 3054 ierr = VecCopy(u,uh);CHKERRQ(ierr); 3055 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3056 for (j=-10; j<11; j++) { 3057 value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3058 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3059 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3060 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 3061 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3062 value = -value; 3063 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3064 } 3065 } 3066 ierr = VecDestroy(&uh);CHKERRQ(ierr); 3067 ierr = VecDestroy(&fh);CHKERRQ(ierr); 3068 PetscFunctionReturn(0); 3069 } 3070 3071 #undef __FUNCT__ 3072 #define __FUNCT__ "SNESKSPSetUseEW" 3073 /*@ 3074 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 3075 computing relative tolerance for linear solvers within an inexact 3076 Newton method. 3077 3078 Logically Collective on SNES 3079 3080 Input Parameters: 3081 + snes - SNES context 3082 - flag - PETSC_TRUE or PETSC_FALSE 3083 3084 Options Database: 3085 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 3086 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 3087 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 3088 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 3089 . -snes_ksp_ew_gamma <gamma> - Sets gamma 3090 . -snes_ksp_ew_alpha <alpha> - Sets alpha 3091 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 3092 - -snes_ksp_ew_threshold <threshold> - Sets threshold 3093 3094 Notes: 3095 Currently, the default is to use a constant relative tolerance for 3096 the inner linear solvers. Alternatively, one can use the 3097 Eisenstat-Walker method, where the relative convergence tolerance 3098 is reset at each Newton iteration according progress of the nonlinear 3099 solver. 3100 3101 Level: advanced 3102 3103 Reference: 3104 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 3105 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 3106 3107 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 3108 3109 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 3110 @*/ 3111 PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 3112 { 3113 PetscFunctionBegin; 3114 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3115 PetscValidLogicalCollectiveBool(snes,flag,2); 3116 snes->ksp_ewconv = flag; 3117 PetscFunctionReturn(0); 3118 } 3119 3120 #undef __FUNCT__ 3121 #define __FUNCT__ "SNESKSPGetUseEW" 3122 /*@ 3123 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 3124 for computing relative tolerance for linear solvers within an 3125 inexact Newton method. 3126 3127 Not Collective 3128 3129 Input Parameter: 3130 . snes - SNES context 3131 3132 Output Parameter: 3133 . flag - PETSC_TRUE or PETSC_FALSE 3134 3135 Notes: 3136 Currently, the default is to use a constant relative tolerance for 3137 the inner linear solvers. Alternatively, one can use the 3138 Eisenstat-Walker method, where the relative convergence tolerance 3139 is reset at each Newton iteration according progress of the nonlinear 3140 solver. 3141 3142 Level: advanced 3143 3144 Reference: 3145 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 3146 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 3147 3148 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 3149 3150 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 3151 @*/ 3152 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 3153 { 3154 PetscFunctionBegin; 3155 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3156 PetscValidPointer(flag,2); 3157 *flag = snes->ksp_ewconv; 3158 PetscFunctionReturn(0); 3159 } 3160 3161 #undef __FUNCT__ 3162 #define __FUNCT__ "SNESKSPSetParametersEW" 3163 /*@ 3164 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 3165 convergence criteria for the linear solvers within an inexact 3166 Newton method. 3167 3168 Logically Collective on SNES 3169 3170 Input Parameters: 3171 + snes - SNES context 3172 . version - version 1, 2 (default is 2) or 3 3173 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 3174 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 3175 . gamma - multiplicative factor for version 2 rtol computation 3176 (0 <= gamma2 <= 1) 3177 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 3178 . alpha2 - power for safeguard 3179 - threshold - threshold for imposing safeguard (0 < threshold < 1) 3180 3181 Note: 3182 Version 3 was contributed by Luis Chacon, June 2006. 3183 3184 Use PETSC_DEFAULT to retain the default for any of the parameters. 3185 3186 Level: advanced 3187 3188 Reference: 3189 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 3190 inexact Newton method", Utah State University Math. Stat. Dept. Res. 3191 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 3192 3193 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 3194 3195 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 3196 @*/ 3197 PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 3198 PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 3199 { 3200 SNESKSPEW *kctx; 3201 PetscFunctionBegin; 3202 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3203 kctx = (SNESKSPEW*)snes->kspconvctx; 3204 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3205 PetscValidLogicalCollectiveInt(snes,version,2); 3206 PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3207 PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3208 PetscValidLogicalCollectiveReal(snes,gamma,5); 3209 PetscValidLogicalCollectiveReal(snes,alpha,6); 3210 PetscValidLogicalCollectiveReal(snes,alpha2,7); 3211 PetscValidLogicalCollectiveReal(snes,threshold,8); 3212 3213 if (version != PETSC_DEFAULT) kctx->version = version; 3214 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 3215 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 3216 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 3217 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 3218 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 3219 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 3220 3221 if (kctx->version < 1 || kctx->version > 3) { 3222 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 3223 } 3224 if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3225 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 3226 } 3227 if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3228 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 3229 } 3230 if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3231 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 3232 } 3233 if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3234 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 3235 } 3236 if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3237 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 3238 } 3239 PetscFunctionReturn(0); 3240 } 3241 3242 #undef __FUNCT__ 3243 #define __FUNCT__ "SNESKSPGetParametersEW" 3244 /*@ 3245 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 3246 convergence criteria for the linear solvers within an inexact 3247 Newton method. 3248 3249 Not Collective 3250 3251 Input Parameters: 3252 snes - SNES context 3253 3254 Output Parameters: 3255 + version - version 1, 2 (default is 2) or 3 3256 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 3257 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 3258 . gamma - multiplicative factor for version 2 rtol computation 3259 (0 <= gamma2 <= 1) 3260 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 3261 . alpha2 - power for safeguard 3262 - threshold - threshold for imposing safeguard (0 < threshold < 1) 3263 3264 Level: advanced 3265 3266 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 3267 3268 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 3269 @*/ 3270 PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 3271 PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 3272 { 3273 SNESKSPEW *kctx; 3274 PetscFunctionBegin; 3275 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3276 kctx = (SNESKSPEW*)snes->kspconvctx; 3277 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3278 if(version) *version = kctx->version; 3279 if(rtol_0) *rtol_0 = kctx->rtol_0; 3280 if(rtol_max) *rtol_max = kctx->rtol_max; 3281 if(gamma) *gamma = kctx->gamma; 3282 if(alpha) *alpha = kctx->alpha; 3283 if(alpha2) *alpha2 = kctx->alpha2; 3284 if(threshold) *threshold = kctx->threshold; 3285 PetscFunctionReturn(0); 3286 } 3287 3288 #undef __FUNCT__ 3289 #define __FUNCT__ "SNESKSPEW_PreSolve" 3290 static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 3291 { 3292 PetscErrorCode ierr; 3293 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 3294 PetscReal rtol=PETSC_DEFAULT,stol; 3295 3296 PetscFunctionBegin; 3297 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3298 if (!snes->iter) { /* first time in, so use the original user rtol */ 3299 rtol = kctx->rtol_0; 3300 } else { 3301 if (kctx->version == 1) { 3302 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 3303 if (rtol < 0.0) rtol = -rtol; 3304 stol = pow(kctx->rtol_last,kctx->alpha2); 3305 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3306 } else if (kctx->version == 2) { 3307 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3308 stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 3309 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3310 } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 3311 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3312 /* safeguard: avoid sharp decrease of rtol */ 3313 stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 3314 stol = PetscMax(rtol,stol); 3315 rtol = PetscMin(kctx->rtol_0,stol); 3316 /* safeguard: avoid oversolving */ 3317 stol = kctx->gamma*(snes->ttol)/snes->norm; 3318 stol = PetscMax(rtol,stol); 3319 rtol = PetscMin(kctx->rtol_0,stol); 3320 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 3321 } 3322 /* safeguard: avoid rtol greater than one */ 3323 rtol = PetscMin(rtol,kctx->rtol_max); 3324 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 3325 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 3326 PetscFunctionReturn(0); 3327 } 3328 3329 #undef __FUNCT__ 3330 #define __FUNCT__ "SNESKSPEW_PostSolve" 3331 static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 3332 { 3333 PetscErrorCode ierr; 3334 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 3335 PCSide pcside; 3336 Vec lres; 3337 3338 PetscFunctionBegin; 3339 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3340 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 3341 ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 3342 if (kctx->version == 1) { 3343 ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 3344 if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 3345 /* KSP residual is true linear residual */ 3346 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 3347 } else { 3348 /* KSP residual is preconditioned residual */ 3349 /* compute true linear residual norm */ 3350 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 3351 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 3352 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 3353 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 3354 ierr = VecDestroy(&lres);CHKERRQ(ierr); 3355 } 3356 } 3357 PetscFunctionReturn(0); 3358 } 3359 3360 #undef __FUNCT__ 3361 #define __FUNCT__ "SNES_KSPSolve" 3362 PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 3363 { 3364 PetscErrorCode ierr; 3365 3366 PetscFunctionBegin; 3367 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3368 ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3369 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3370 PetscFunctionReturn(0); 3371 } 3372 3373 #undef __FUNCT__ 3374 #define __FUNCT__ "SNESSetDM" 3375 /*@ 3376 SNESSetDM - Sets the DM that may be used by some preconditioners 3377 3378 Logically Collective on SNES 3379 3380 Input Parameters: 3381 + snes - the preconditioner context 3382 - dm - the dm 3383 3384 Level: intermediate 3385 3386 3387 .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 3388 @*/ 3389 PetscErrorCode SNESSetDM(SNES snes,DM dm) 3390 { 3391 PetscErrorCode ierr; 3392 KSP ksp; 3393 3394 PetscFunctionBegin; 3395 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3396 if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 3397 ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 3398 snes->dm = dm; 3399 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3400 ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3401 ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 3402 PetscFunctionReturn(0); 3403 } 3404 3405 #undef __FUNCT__ 3406 #define __FUNCT__ "SNESGetDM" 3407 /*@ 3408 SNESGetDM - Gets the DM that may be used by some preconditioners 3409 3410 Not Collective but DM obtained is parallel on SNES 3411 3412 Input Parameter: 3413 . snes - the preconditioner context 3414 3415 Output Parameter: 3416 . dm - the dm 3417 3418 Level: intermediate 3419 3420 3421 .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 3422 @*/ 3423 PetscErrorCode SNESGetDM(SNES snes,DM *dm) 3424 { 3425 PetscFunctionBegin; 3426 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3427 *dm = snes->dm; 3428 PetscFunctionReturn(0); 3429 } 3430 3431 #undef __FUNCT__ 3432 #define __FUNCT__ "SNESSetPC" 3433 /*@ 3434 SNESSetPC - Sets the preconditioner to be used. 3435 3436 Collective on SNES 3437 3438 Input Parameters: 3439 + snes - iterative context obtained from SNESCreate() 3440 - pc - the preconditioner object 3441 3442 Notes: 3443 Use SNESGetPC() to retrieve the preconditioner context (for example, 3444 to configure it using the API). 3445 3446 Level: developer 3447 3448 .keywords: SNES, set, precondition 3449 .seealso: SNESGetPC() 3450 @*/ 3451 PetscErrorCode SNESSetPC(SNES snes, SNES pc) 3452 { 3453 PetscErrorCode ierr; 3454 3455 PetscFunctionBegin; 3456 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3457 PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 3458 PetscCheckSameComm(snes, 1, pc, 2); 3459 ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 3460 ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 3461 snes->pc = pc; 3462 ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 3463 PetscFunctionReturn(0); 3464 } 3465 3466 #undef __FUNCT__ 3467 #define __FUNCT__ "SNESGetPC" 3468 /*@ 3469 SNESGetPC - Returns a pointer to the preconditioner context set with SNESSetPC(). 3470 3471 Not Collective 3472 3473 Input Parameter: 3474 . snes - iterative context obtained from SNESCreate() 3475 3476 Output Parameter: 3477 . pc - preconditioner context 3478 3479 Level: developer 3480 3481 .keywords: SNES, get, preconditioner 3482 .seealso: SNESSetPC() 3483 @*/ 3484 PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 3485 { 3486 PetscErrorCode ierr; 3487 3488 PetscFunctionBegin; 3489 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3490 PetscValidPointer(pc, 2); 3491 if (!snes->pc) { 3492 ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 3493 ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 3494 ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 3495 } 3496 *pc = snes->pc; 3497 PetscFunctionReturn(0); 3498 } 3499 3500 #if defined(PETSC_HAVE_MATLAB_ENGINE) 3501 #include <mex.h> 3502 3503 typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 3504 3505 #undef __FUNCT__ 3506 #define __FUNCT__ "SNESComputeFunction_Matlab" 3507 /* 3508 SNESComputeFunction_Matlab - Calls the function that has been set with 3509 SNESSetFunctionMatlab(). 3510 3511 Collective on SNES 3512 3513 Input Parameters: 3514 + snes - the SNES context 3515 - x - input vector 3516 3517 Output Parameter: 3518 . y - function vector, as set by SNESSetFunction() 3519 3520 Notes: 3521 SNESComputeFunction() is typically used within nonlinear solvers 3522 implementations, so most users would not generally call this routine 3523 themselves. 3524 3525 Level: developer 3526 3527 .keywords: SNES, nonlinear, compute, function 3528 3529 .seealso: SNESSetFunction(), SNESGetFunction() 3530 */ 3531 PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 3532 { 3533 PetscErrorCode ierr; 3534 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3535 int nlhs = 1,nrhs = 5; 3536 mxArray *plhs[1],*prhs[5]; 3537 long long int lx = 0,ly = 0,ls = 0; 3538 3539 PetscFunctionBegin; 3540 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3541 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3542 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3543 PetscCheckSameComm(snes,1,x,2); 3544 PetscCheckSameComm(snes,1,y,3); 3545 3546 /* call Matlab function in ctx with arguments x and y */ 3547 3548 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3549 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3550 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 3551 prhs[0] = mxCreateDoubleScalar((double)ls); 3552 prhs[1] = mxCreateDoubleScalar((double)lx); 3553 prhs[2] = mxCreateDoubleScalar((double)ly); 3554 prhs[3] = mxCreateString(sctx->funcname); 3555 prhs[4] = sctx->ctx; 3556 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 3557 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3558 mxDestroyArray(prhs[0]); 3559 mxDestroyArray(prhs[1]); 3560 mxDestroyArray(prhs[2]); 3561 mxDestroyArray(prhs[3]); 3562 mxDestroyArray(plhs[0]); 3563 PetscFunctionReturn(0); 3564 } 3565 3566 3567 #undef __FUNCT__ 3568 #define __FUNCT__ "SNESSetFunctionMatlab" 3569 /* 3570 SNESSetFunctionMatlab - Sets the function evaluation routine and function 3571 vector for use by the SNES routines in solving systems of nonlinear 3572 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3573 3574 Logically Collective on SNES 3575 3576 Input Parameters: 3577 + snes - the SNES context 3578 . r - vector to store function value 3579 - func - function evaluation routine 3580 3581 Calling sequence of func: 3582 $ func (SNES snes,Vec x,Vec f,void *ctx); 3583 3584 3585 Notes: 3586 The Newton-like methods typically solve linear systems of the form 3587 $ f'(x) x = -f(x), 3588 where f'(x) denotes the Jacobian matrix and f(x) is the function. 3589 3590 Level: beginner 3591 3592 .keywords: SNES, nonlinear, set, function 3593 3594 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3595 */ 3596 PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 3597 { 3598 PetscErrorCode ierr; 3599 SNESMatlabContext *sctx; 3600 3601 PetscFunctionBegin; 3602 /* currently sctx is memory bleed */ 3603 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3604 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3605 /* 3606 This should work, but it doesn't 3607 sctx->ctx = ctx; 3608 mexMakeArrayPersistent(sctx->ctx); 3609 */ 3610 sctx->ctx = mxDuplicateArray(ctx); 3611 ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 3612 PetscFunctionReturn(0); 3613 } 3614 3615 #undef __FUNCT__ 3616 #define __FUNCT__ "SNESComputeJacobian_Matlab" 3617 /* 3618 SNESComputeJacobian_Matlab - Calls the function that has been set with 3619 SNESSetJacobianMatlab(). 3620 3621 Collective on SNES 3622 3623 Input Parameters: 3624 + snes - the SNES context 3625 . x - input vector 3626 . A, B - the matrices 3627 - ctx - user context 3628 3629 Output Parameter: 3630 . flag - structure of the matrix 3631 3632 Level: developer 3633 3634 .keywords: SNES, nonlinear, compute, function 3635 3636 .seealso: SNESSetFunction(), SNESGetFunction() 3637 @*/ 3638 PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 3639 { 3640 PetscErrorCode ierr; 3641 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3642 int nlhs = 2,nrhs = 6; 3643 mxArray *plhs[2],*prhs[6]; 3644 long long int lx = 0,lA = 0,ls = 0, lB = 0; 3645 3646 PetscFunctionBegin; 3647 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3648 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3649 3650 /* call Matlab function in ctx with arguments x and y */ 3651 3652 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3653 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3654 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 3655 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 3656 prhs[0] = mxCreateDoubleScalar((double)ls); 3657 prhs[1] = mxCreateDoubleScalar((double)lx); 3658 prhs[2] = mxCreateDoubleScalar((double)lA); 3659 prhs[3] = mxCreateDoubleScalar((double)lB); 3660 prhs[4] = mxCreateString(sctx->funcname); 3661 prhs[5] = sctx->ctx; 3662 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 3663 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3664 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 3665 mxDestroyArray(prhs[0]); 3666 mxDestroyArray(prhs[1]); 3667 mxDestroyArray(prhs[2]); 3668 mxDestroyArray(prhs[3]); 3669 mxDestroyArray(prhs[4]); 3670 mxDestroyArray(plhs[0]); 3671 mxDestroyArray(plhs[1]); 3672 PetscFunctionReturn(0); 3673 } 3674 3675 3676 #undef __FUNCT__ 3677 #define __FUNCT__ "SNESSetJacobianMatlab" 3678 /* 3679 SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 3680 vector for use by the SNES routines in solving systems of nonlinear 3681 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3682 3683 Logically Collective on SNES 3684 3685 Input Parameters: 3686 + snes - the SNES context 3687 . A,B - Jacobian matrices 3688 . func - function evaluation routine 3689 - ctx - user context 3690 3691 Calling sequence of func: 3692 $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 3693 3694 3695 Level: developer 3696 3697 .keywords: SNES, nonlinear, set, function 3698 3699 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3700 */ 3701 PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 3702 { 3703 PetscErrorCode ierr; 3704 SNESMatlabContext *sctx; 3705 3706 PetscFunctionBegin; 3707 /* currently sctx is memory bleed */ 3708 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3709 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3710 /* 3711 This should work, but it doesn't 3712 sctx->ctx = ctx; 3713 mexMakeArrayPersistent(sctx->ctx); 3714 */ 3715 sctx->ctx = mxDuplicateArray(ctx); 3716 ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 3717 PetscFunctionReturn(0); 3718 } 3719 3720 #undef __FUNCT__ 3721 #define __FUNCT__ "SNESMonitor_Matlab" 3722 /* 3723 SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 3724 3725 Collective on SNES 3726 3727 .seealso: SNESSetFunction(), SNESGetFunction() 3728 @*/ 3729 PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 3730 { 3731 PetscErrorCode ierr; 3732 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3733 int nlhs = 1,nrhs = 6; 3734 mxArray *plhs[1],*prhs[6]; 3735 long long int lx = 0,ls = 0; 3736 Vec x=snes->vec_sol; 3737 3738 PetscFunctionBegin; 3739 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3740 3741 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3742 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3743 prhs[0] = mxCreateDoubleScalar((double)ls); 3744 prhs[1] = mxCreateDoubleScalar((double)it); 3745 prhs[2] = mxCreateDoubleScalar((double)fnorm); 3746 prhs[3] = mxCreateDoubleScalar((double)lx); 3747 prhs[4] = mxCreateString(sctx->funcname); 3748 prhs[5] = sctx->ctx; 3749 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 3750 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3751 mxDestroyArray(prhs[0]); 3752 mxDestroyArray(prhs[1]); 3753 mxDestroyArray(prhs[2]); 3754 mxDestroyArray(prhs[3]); 3755 mxDestroyArray(prhs[4]); 3756 mxDestroyArray(plhs[0]); 3757 PetscFunctionReturn(0); 3758 } 3759 3760 3761 #undef __FUNCT__ 3762 #define __FUNCT__ "SNESMonitorSetMatlab" 3763 /* 3764 SNESMonitorSetMatlab - Sets the monitor function from MATLAB 3765 3766 Level: developer 3767 3768 .keywords: SNES, nonlinear, set, function 3769 3770 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3771 */ 3772 PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 3773 { 3774 PetscErrorCode ierr; 3775 SNESMatlabContext *sctx; 3776 3777 PetscFunctionBegin; 3778 /* currently sctx is memory bleed */ 3779 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3780 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3781 /* 3782 This should work, but it doesn't 3783 sctx->ctx = ctx; 3784 mexMakeArrayPersistent(sctx->ctx); 3785 */ 3786 sctx->ctx = mxDuplicateArray(ctx); 3787 ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 3788 PetscFunctionReturn(0); 3789 } 3790 3791 #endif 3792