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