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