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