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