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