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 { 272 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 273 } 274 275 ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 276 if (hasOperator) { 277 /* This version replaces the user provided Jacobian matrix with a 278 matrix-free version but still employs the user-provided preconditioner matrix. */ 279 ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 280 } else { 281 /* This version replaces both the user-provided Jacobian and the user- 282 provided preconditioner matrix with the default matrix free version. */ 283 ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 284 /* Force no preconditioner */ 285 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 286 ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 287 ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 288 if (!match) { 289 ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 290 ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 291 } 292 } 293 ierr = MatDestroy(&J);CHKERRQ(ierr); 294 295 PetscFunctionReturn(0); 296 } 297 298 #undef __FUNCT__ 299 #define __FUNCT__ "SNESSetFromOptions" 300 /*@ 301 SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 302 303 Collective on SNES 304 305 Input Parameter: 306 . snes - the SNES context 307 308 Options Database Keys: 309 + -snes_type <type> - ls, tr, umls, umtr, test 310 . -snes_stol - convergence tolerance in terms of the norm 311 of the change in the solution between steps 312 . -snes_atol <abstol> - absolute tolerance of residual norm 313 . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 314 . -snes_max_it <max_it> - maximum number of iterations 315 . -snes_max_funcs <max_funcs> - maximum number of function evaluations 316 . -snes_max_fail <max_fail> - maximum number of failures 317 . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 318 . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 319 . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 320 . -snes_trtol <trtol> - trust region tolerance 321 . -snes_no_convergence_test - skip convergence test in nonlinear 322 solver; hence iterations will continue until max_it 323 or some other criterion is reached. Saves expense 324 of convergence test 325 . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 326 filename given prints to stdout 327 . -snes_monitor_solution - plots solution at each iteration 328 . -snes_monitor_residual - plots residual (not its norm) at each iteration 329 . -snes_monitor_solution_update - plots update to solution at each iteration 330 . -snes_monitor_draw - plots residual norm at each iteration 331 . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 332 . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 333 - -snes_converged_reason - print the reason for convergence/divergence after each solve 334 335 Options Database for Eisenstat-Walker method: 336 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 337 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 338 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 339 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 340 . -snes_ksp_ew_gamma <gamma> - Sets gamma 341 . -snes_ksp_ew_alpha <alpha> - Sets alpha 342 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 343 - -snes_ksp_ew_threshold <threshold> - Sets threshold 344 345 Notes: 346 To see all options, run your program with the -help option or consult 347 the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 348 349 Level: beginner 350 351 .keywords: SNES, nonlinear, set, options, database 352 353 .seealso: SNESSetOptionsPrefix() 354 @*/ 355 PetscErrorCode SNESSetFromOptions(SNES snes) 356 { 357 PetscBool flg,mf,mf_operator; 358 PetscInt i,indx,lag,mf_version,grids; 359 MatStructure matflag; 360 const char *deft = SNESLS; 361 const char *convtests[] = {"default","skip"}; 362 SNESKSPEW *kctx = NULL; 363 char type[256], monfilename[PETSC_MAX_PATH_LEN]; 364 PetscViewer monviewer; 365 PetscErrorCode ierr; 366 367 PetscFunctionBegin; 368 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 369 370 if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 371 ierr = PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");CHKERRQ(ierr); 372 if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 373 ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 374 if (flg) { 375 ierr = SNESSetType(snes,type);CHKERRQ(ierr); 376 } else if (!((PetscObject)snes)->type_name) { 377 ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 378 } 379 /* not used here, but called so will go into help messaage */ 380 ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 381 382 ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr); 383 ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 384 385 ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 386 ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 387 ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 388 ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 389 ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 390 ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 391 392 ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 393 if (flg) { 394 ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 395 } 396 ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 397 if (flg) { 398 ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 399 } 400 ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 401 if (flg) { 402 ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 403 } 404 405 ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 406 if (flg) { 407 switch (indx) { 408 case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 409 case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 410 } 411 } 412 413 ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 414 415 kctx = (SNESKSPEW *)snes->kspconvctx; 416 417 ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 418 419 ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 420 ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 421 ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 422 ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 423 ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 424 ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 425 ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 426 427 flg = PETSC_FALSE; 428 ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 429 if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 430 431 ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 432 if (flg) { 433 ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 434 ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 435 } 436 437 ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 438 if (flg) { 439 ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 440 } 441 442 ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 443 if (flg) { 444 ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 445 ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 446 } 447 448 ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 449 if (flg) { 450 ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 451 ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 452 } 453 454 flg = PETSC_FALSE; 455 ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 456 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 457 flg = PETSC_FALSE; 458 ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 459 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 460 flg = PETSC_FALSE; 461 ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 462 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 463 flg = PETSC_FALSE; 464 ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 465 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 466 flg = PETSC_FALSE; 467 ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 468 if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 469 470 flg = PETSC_FALSE; 471 ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 472 if (flg) { 473 ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr); 474 ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 475 } 476 477 mf = mf_operator = PETSC_FALSE; 478 flg = PETSC_FALSE; 479 ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 480 if (flg && mf_operator) mf = PETSC_TRUE; 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 *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 && snes->dm && !snes->vec_rhs) { 1570 ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1571 } 1572 if (!snes->vec_func && !snes->vec_rhs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first"); 1573 if (!snes->ops->computefunction && !snes->vec_rhs && !snes->dm) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() or SNESSetDM() first"); 1574 if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 1575 if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 1576 1577 if (!snes->vec_func && snes->vec_rhs) { 1578 ierr = VecDuplicate(snes->vec_rhs, &snes->vec_func);CHKERRQ(ierr); 1579 } 1580 if (!snes->vec_sol_update /* && snes->vec_sol */) { 1581 ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 1582 ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 1583 } 1584 1585 if (!snes->ops->computejacobian && snes->dm) { 1586 Mat J; 1587 ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1588 ierr = SNESSetJacobian(snes,J,J,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 1589 ierr = MatDestroy(&J);CHKERRQ(ierr); 1590 } else if (snes->dm && !snes->jacobian_pre){ 1591 Mat J; 1592 ierr = DMGetMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 1593 ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1594 ierr = MatDestroy(&J);CHKERRQ(ierr); 1595 } 1596 1597 if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 1598 1599 if (snes->ops->usercompute && !snes->user) { 1600 ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 1601 } 1602 1603 if (snes->ops->setup) { 1604 ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 1605 } 1606 1607 snes->setupcalled = PETSC_TRUE; 1608 PetscFunctionReturn(0); 1609 } 1610 1611 #undef __FUNCT__ 1612 #define __FUNCT__ "SNESReset" 1613 /*@ 1614 SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 1615 1616 Collective on SNES 1617 1618 Input Parameter: 1619 . snes - iterative context obtained from SNESCreate() 1620 1621 Level: intermediate 1622 1623 Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 1624 1625 .keywords: SNES, destroy 1626 1627 .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 1628 @*/ 1629 PetscErrorCode SNESReset(SNES snes) 1630 { 1631 PetscErrorCode ierr; 1632 1633 PetscFunctionBegin; 1634 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1635 if (snes->ops->userdestroy && snes->user) { 1636 ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 1637 snes->user = PETSC_NULL; 1638 } 1639 if (snes->ops->computejacobian == SNESDefaultComputeJacobianColor && snes->dm) { 1640 ierr = MatFDColoringDestroy((MatFDColoring*)&snes->jacP);CHKERRQ(ierr); 1641 snes->ops->computejacobian = PETSC_NULL; 1642 } 1643 1644 if (snes->ops->reset) { 1645 ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 1646 } 1647 if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 1648 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 1649 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 1650 ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 1651 ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 1652 ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 1653 ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 1654 if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 1655 if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);} 1656 snes->nwork = snes->nvwork = 0; 1657 snes->setupcalled = PETSC_FALSE; 1658 PetscFunctionReturn(0); 1659 } 1660 1661 #undef __FUNCT__ 1662 #define __FUNCT__ "SNESDestroy" 1663 /*@ 1664 SNESDestroy - Destroys the nonlinear solver context that was created 1665 with SNESCreate(). 1666 1667 Collective on SNES 1668 1669 Input Parameter: 1670 . snes - the SNES context 1671 1672 Level: beginner 1673 1674 .keywords: SNES, nonlinear, destroy 1675 1676 .seealso: SNESCreate(), SNESSolve() 1677 @*/ 1678 PetscErrorCode SNESDestroy(SNES *snes) 1679 { 1680 PetscErrorCode ierr; 1681 1682 PetscFunctionBegin; 1683 if (!*snes) PetscFunctionReturn(0); 1684 PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 1685 if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 1686 1687 ierr = SNESReset((*snes));CHKERRQ(ierr); 1688 1689 /* if memory was published with AMS then destroy it */ 1690 ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 1691 if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 1692 1693 ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 1694 ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 1695 1696 ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 1697 if ((*snes)->ops->convergeddestroy) { 1698 ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 1699 } 1700 if ((*snes)->conv_malloc) { 1701 ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 1702 ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 1703 } 1704 ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 1705 ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 1706 PetscFunctionReturn(0); 1707 } 1708 1709 /* ----------- Routines to set solver parameters ---------- */ 1710 1711 #undef __FUNCT__ 1712 #define __FUNCT__ "SNESSetLagPreconditioner" 1713 /*@ 1714 SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 1715 1716 Logically Collective on SNES 1717 1718 Input Parameters: 1719 + snes - the SNES context 1720 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1721 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1722 1723 Options Database Keys: 1724 . -snes_lag_preconditioner <lag> 1725 1726 Notes: 1727 The default is 1 1728 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1729 If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 1730 1731 Level: intermediate 1732 1733 .keywords: SNES, nonlinear, set, convergence, tolerances 1734 1735 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1736 1737 @*/ 1738 PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 1739 { 1740 PetscFunctionBegin; 1741 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1742 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1743 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1744 PetscValidLogicalCollectiveInt(snes,lag,2); 1745 snes->lagpreconditioner = lag; 1746 PetscFunctionReturn(0); 1747 } 1748 1749 #undef __FUNCT__ 1750 #define __FUNCT__ "SNESSetGridSequence" 1751 /*@ 1752 SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 1753 1754 Logically Collective on SNES 1755 1756 Input Parameters: 1757 + snes - the SNES context 1758 - steps - the number of refinements to do, defaults to 0 1759 1760 Options Database Keys: 1761 . -snes_grid_sequence <steps> 1762 1763 Level: intermediate 1764 1765 .keywords: SNES, nonlinear, set, convergence, tolerances 1766 1767 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 1768 1769 @*/ 1770 PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 1771 { 1772 PetscFunctionBegin; 1773 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1774 PetscValidLogicalCollectiveInt(snes,steps,2); 1775 snes->gridsequence = steps; 1776 PetscFunctionReturn(0); 1777 } 1778 1779 #undef __FUNCT__ 1780 #define __FUNCT__ "SNESGetLagPreconditioner" 1781 /*@ 1782 SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 1783 1784 Not Collective 1785 1786 Input Parameter: 1787 . snes - the SNES context 1788 1789 Output Parameter: 1790 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1791 the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 1792 1793 Options Database Keys: 1794 . -snes_lag_preconditioner <lag> 1795 1796 Notes: 1797 The default is 1 1798 The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1799 1800 Level: intermediate 1801 1802 .keywords: SNES, nonlinear, set, convergence, tolerances 1803 1804 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 1805 1806 @*/ 1807 PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 1808 { 1809 PetscFunctionBegin; 1810 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1811 *lag = snes->lagpreconditioner; 1812 PetscFunctionReturn(0); 1813 } 1814 1815 #undef __FUNCT__ 1816 #define __FUNCT__ "SNESSetLagJacobian" 1817 /*@ 1818 SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 1819 often the preconditioner is rebuilt. 1820 1821 Logically Collective on SNES 1822 1823 Input Parameters: 1824 + snes - the SNES context 1825 - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1826 the Jacobian is built etc. -2 means rebuild at next chance but then never again 1827 1828 Options Database Keys: 1829 . -snes_lag_jacobian <lag> 1830 1831 Notes: 1832 The default is 1 1833 The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1834 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 1835 at the next Newton step but never again (unless it is reset to another value) 1836 1837 Level: intermediate 1838 1839 .keywords: SNES, nonlinear, set, convergence, tolerances 1840 1841 .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 1842 1843 @*/ 1844 PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 1845 { 1846 PetscFunctionBegin; 1847 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1848 if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 1849 if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 1850 PetscValidLogicalCollectiveInt(snes,lag,2); 1851 snes->lagjacobian = lag; 1852 PetscFunctionReturn(0); 1853 } 1854 1855 #undef __FUNCT__ 1856 #define __FUNCT__ "SNESGetLagJacobian" 1857 /*@ 1858 SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 1859 1860 Not Collective 1861 1862 Input Parameter: 1863 . snes - the SNES context 1864 1865 Output Parameter: 1866 . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 1867 the Jacobian is built etc. 1868 1869 Options Database Keys: 1870 . -snes_lag_jacobian <lag> 1871 1872 Notes: 1873 The default is 1 1874 The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 1875 1876 Level: intermediate 1877 1878 .keywords: SNES, nonlinear, set, convergence, tolerances 1879 1880 .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 1881 1882 @*/ 1883 PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 1884 { 1885 PetscFunctionBegin; 1886 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1887 *lag = snes->lagjacobian; 1888 PetscFunctionReturn(0); 1889 } 1890 1891 #undef __FUNCT__ 1892 #define __FUNCT__ "SNESSetTolerances" 1893 /*@ 1894 SNESSetTolerances - Sets various parameters used in convergence tests. 1895 1896 Logically Collective on SNES 1897 1898 Input Parameters: 1899 + snes - the SNES context 1900 . abstol - absolute convergence tolerance 1901 . rtol - relative convergence tolerance 1902 . stol - convergence tolerance in terms of the norm 1903 of the change in the solution between steps 1904 . maxit - maximum number of iterations 1905 - maxf - maximum number of function evaluations 1906 1907 Options Database Keys: 1908 + -snes_atol <abstol> - Sets abstol 1909 . -snes_rtol <rtol> - Sets rtol 1910 . -snes_stol <stol> - Sets stol 1911 . -snes_max_it <maxit> - Sets maxit 1912 - -snes_max_funcs <maxf> - Sets maxf 1913 1914 Notes: 1915 The default maximum number of iterations is 50. 1916 The default maximum number of function evaluations is 1000. 1917 1918 Level: intermediate 1919 1920 .keywords: SNES, nonlinear, set, convergence, tolerances 1921 1922 .seealso: SNESSetTrustRegionTolerance() 1923 @*/ 1924 PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 1925 { 1926 PetscFunctionBegin; 1927 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1928 PetscValidLogicalCollectiveReal(snes,abstol,2); 1929 PetscValidLogicalCollectiveReal(snes,rtol,3); 1930 PetscValidLogicalCollectiveReal(snes,stol,4); 1931 PetscValidLogicalCollectiveInt(snes,maxit,5); 1932 PetscValidLogicalCollectiveInt(snes,maxf,6); 1933 1934 if (abstol != PETSC_DEFAULT) snes->abstol = abstol; 1935 if (rtol != PETSC_DEFAULT) snes->rtol = rtol; 1936 if (stol != PETSC_DEFAULT) snes->xtol = stol; 1937 if (maxit != PETSC_DEFAULT) snes->max_its = maxit; 1938 if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf; 1939 PetscFunctionReturn(0); 1940 } 1941 1942 #undef __FUNCT__ 1943 #define __FUNCT__ "SNESGetTolerances" 1944 /*@ 1945 SNESGetTolerances - Gets various parameters used in convergence tests. 1946 1947 Not Collective 1948 1949 Input Parameters: 1950 + snes - the SNES context 1951 . atol - absolute convergence tolerance 1952 . rtol - relative convergence tolerance 1953 . stol - convergence tolerance in terms of the norm 1954 of the change in the solution between steps 1955 . maxit - maximum number of iterations 1956 - maxf - maximum number of function evaluations 1957 1958 Notes: 1959 The user can specify PETSC_NULL for any parameter that is not needed. 1960 1961 Level: intermediate 1962 1963 .keywords: SNES, nonlinear, get, convergence, tolerances 1964 1965 .seealso: SNESSetTolerances() 1966 @*/ 1967 PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 1968 { 1969 PetscFunctionBegin; 1970 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1971 if (atol) *atol = snes->abstol; 1972 if (rtol) *rtol = snes->rtol; 1973 if (stol) *stol = snes->xtol; 1974 if (maxit) *maxit = snes->max_its; 1975 if (maxf) *maxf = snes->max_funcs; 1976 PetscFunctionReturn(0); 1977 } 1978 1979 #undef __FUNCT__ 1980 #define __FUNCT__ "SNESSetTrustRegionTolerance" 1981 /*@ 1982 SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 1983 1984 Logically Collective on SNES 1985 1986 Input Parameters: 1987 + snes - the SNES context 1988 - tol - tolerance 1989 1990 Options Database Key: 1991 . -snes_trtol <tol> - Sets tol 1992 1993 Level: intermediate 1994 1995 .keywords: SNES, nonlinear, set, trust region, tolerance 1996 1997 .seealso: SNESSetTolerances() 1998 @*/ 1999 PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 2000 { 2001 PetscFunctionBegin; 2002 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2003 PetscValidLogicalCollectiveReal(snes,tol,2); 2004 snes->deltatol = tol; 2005 PetscFunctionReturn(0); 2006 } 2007 2008 /* 2009 Duplicate the lg monitors for SNES from KSP; for some reason with 2010 dynamic libraries things don't work under Sun4 if we just use 2011 macros instead of functions 2012 */ 2013 #undef __FUNCT__ 2014 #define __FUNCT__ "SNESMonitorLG" 2015 PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2016 { 2017 PetscErrorCode ierr; 2018 2019 PetscFunctionBegin; 2020 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2021 ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2022 PetscFunctionReturn(0); 2023 } 2024 2025 #undef __FUNCT__ 2026 #define __FUNCT__ "SNESMonitorLGCreate" 2027 PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2028 { 2029 PetscErrorCode ierr; 2030 2031 PetscFunctionBegin; 2032 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2033 PetscFunctionReturn(0); 2034 } 2035 2036 #undef __FUNCT__ 2037 #define __FUNCT__ "SNESMonitorLGDestroy" 2038 PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2039 { 2040 PetscErrorCode ierr; 2041 2042 PetscFunctionBegin; 2043 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2044 PetscFunctionReturn(0); 2045 } 2046 2047 extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2048 #undef __FUNCT__ 2049 #define __FUNCT__ "SNESMonitorLGRange" 2050 PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2051 { 2052 PetscDrawLG lg; 2053 PetscErrorCode ierr; 2054 PetscReal x,y,per; 2055 PetscViewer v = (PetscViewer)monctx; 2056 static PetscReal prev; /* should be in the context */ 2057 PetscDraw draw; 2058 PetscFunctionBegin; 2059 if (!monctx) { 2060 MPI_Comm comm; 2061 2062 ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2063 v = PETSC_VIEWER_DRAW_(comm); 2064 } 2065 ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2066 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2067 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2068 ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2069 x = (PetscReal) n; 2070 if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2071 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2072 if (n < 20 || !(n % 5)) { 2073 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2074 } 2075 2076 ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2077 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2078 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2079 ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2080 ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2081 x = (PetscReal) n; 2082 y = 100.0*per; 2083 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2084 if (n < 20 || !(n % 5)) { 2085 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2086 } 2087 2088 ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2089 if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2090 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2091 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2092 x = (PetscReal) n; 2093 y = (prev - rnorm)/prev; 2094 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2095 if (n < 20 || !(n % 5)) { 2096 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2097 } 2098 2099 ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2100 if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2101 ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2102 ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2103 x = (PetscReal) n; 2104 y = (prev - rnorm)/(prev*per); 2105 if (n > 2) { /*skip initial crazy value */ 2106 ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2107 } 2108 if (n < 20 || !(n % 5)) { 2109 ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2110 } 2111 prev = rnorm; 2112 PetscFunctionReturn(0); 2113 } 2114 2115 #undef __FUNCT__ 2116 #define __FUNCT__ "SNESMonitorLGRangeCreate" 2117 PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2118 { 2119 PetscErrorCode ierr; 2120 2121 PetscFunctionBegin; 2122 ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2123 PetscFunctionReturn(0); 2124 } 2125 2126 #undef __FUNCT__ 2127 #define __FUNCT__ "SNESMonitorLGRangeDestroy" 2128 PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2129 { 2130 PetscErrorCode ierr; 2131 2132 PetscFunctionBegin; 2133 ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2134 PetscFunctionReturn(0); 2135 } 2136 2137 #undef __FUNCT__ 2138 #define __FUNCT__ "SNESMonitor" 2139 /* 2140 Runs the user provided monitor routines, if they exists. 2141 */ 2142 PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 2143 { 2144 PetscErrorCode ierr; 2145 PetscInt i,n = snes->numbermonitors; 2146 2147 PetscFunctionBegin; 2148 for (i=0; i<n; i++) { 2149 ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 2150 } 2151 PetscFunctionReturn(0); 2152 } 2153 2154 /* ------------ Routines to set performance monitoring options ----------- */ 2155 2156 #undef __FUNCT__ 2157 #define __FUNCT__ "SNESMonitorSet" 2158 /*@C 2159 SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 2160 iteration of the nonlinear solver to display the iteration's 2161 progress. 2162 2163 Logically Collective on SNES 2164 2165 Input Parameters: 2166 + snes - the SNES context 2167 . func - monitoring routine 2168 . mctx - [optional] user-defined context for private data for the 2169 monitor routine (use PETSC_NULL if no context is desired) 2170 - monitordestroy - [optional] routine that frees monitor context 2171 (may be PETSC_NULL) 2172 2173 Calling sequence of func: 2174 $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2175 2176 + snes - the SNES context 2177 . its - iteration number 2178 . norm - 2-norm function value (may be estimated) 2179 - mctx - [optional] monitoring context 2180 2181 Options Database Keys: 2182 + -snes_monitor - sets SNESMonitorDefault() 2183 . -snes_monitor_draw - sets line graph monitor, 2184 uses SNESMonitorLGCreate() 2185 - -snes_monitor_cancel - cancels all monitors that have 2186 been hardwired into a code by 2187 calls to SNESMonitorSet(), but 2188 does not cancel those set via 2189 the options database. 2190 2191 Notes: 2192 Several different monitoring routines may be set by calling 2193 SNESMonitorSet() multiple times; all will be called in the 2194 order in which they were set. 2195 2196 Fortran notes: Only a single monitor function can be set for each SNES object 2197 2198 Level: intermediate 2199 2200 .keywords: SNES, nonlinear, set, monitor 2201 2202 .seealso: SNESMonitorDefault(), SNESMonitorCancel() 2203 @*/ 2204 PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 2205 { 2206 PetscInt i; 2207 PetscErrorCode ierr; 2208 2209 PetscFunctionBegin; 2210 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2211 if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2212 for (i=0; i<snes->numbermonitors;i++) { 2213 if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2214 if (monitordestroy) { 2215 ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2216 } 2217 PetscFunctionReturn(0); 2218 } 2219 } 2220 snes->monitor[snes->numbermonitors] = monitor; 2221 snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2222 snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 2223 PetscFunctionReturn(0); 2224 } 2225 2226 #undef __FUNCT__ 2227 #define __FUNCT__ "SNESMonitorCancel" 2228 /*@C 2229 SNESMonitorCancel - Clears all the monitor functions for a SNES object. 2230 2231 Logically Collective on SNES 2232 2233 Input Parameters: 2234 . snes - the SNES context 2235 2236 Options Database Key: 2237 . -snes_monitor_cancel - cancels all monitors that have been hardwired 2238 into a code by calls to SNESMonitorSet(), but does not cancel those 2239 set via the options database 2240 2241 Notes: 2242 There is no way to clear one specific monitor from a SNES object. 2243 2244 Level: intermediate 2245 2246 .keywords: SNES, nonlinear, set, monitor 2247 2248 .seealso: SNESMonitorDefault(), SNESMonitorSet() 2249 @*/ 2250 PetscErrorCode SNESMonitorCancel(SNES snes) 2251 { 2252 PetscErrorCode ierr; 2253 PetscInt i; 2254 2255 PetscFunctionBegin; 2256 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2257 for (i=0; i<snes->numbermonitors; i++) { 2258 if (snes->monitordestroy[i]) { 2259 ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2260 } 2261 } 2262 snes->numbermonitors = 0; 2263 PetscFunctionReturn(0); 2264 } 2265 2266 #undef __FUNCT__ 2267 #define __FUNCT__ "SNESSetConvergenceTest" 2268 /*@C 2269 SNESSetConvergenceTest - Sets the function that is to be used 2270 to test for convergence of the nonlinear iterative solution. 2271 2272 Logically Collective on SNES 2273 2274 Input Parameters: 2275 + snes - the SNES context 2276 . func - routine to test for convergence 2277 . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 2278 - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 2279 2280 Calling sequence of func: 2281 $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2282 2283 + snes - the SNES context 2284 . it - current iteration (0 is the first and is before any Newton step) 2285 . cctx - [optional] convergence context 2286 . reason - reason for convergence/divergence 2287 . xnorm - 2-norm of current iterate 2288 . gnorm - 2-norm of current step 2289 - f - 2-norm of function 2290 2291 Level: advanced 2292 2293 .keywords: SNES, nonlinear, set, convergence, test 2294 2295 .seealso: SNESDefaultConverged(), SNESSkipConverged() 2296 @*/ 2297 PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 2298 { 2299 PetscErrorCode ierr; 2300 2301 PetscFunctionBegin; 2302 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2303 if (!func) func = SNESSkipConverged; 2304 if (snes->ops->convergeddestroy) { 2305 ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 2306 } 2307 snes->ops->converged = func; 2308 snes->ops->convergeddestroy = destroy; 2309 snes->cnvP = cctx; 2310 PetscFunctionReturn(0); 2311 } 2312 2313 #undef __FUNCT__ 2314 #define __FUNCT__ "SNESGetConvergedReason" 2315 /*@ 2316 SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2317 2318 Not Collective 2319 2320 Input Parameter: 2321 . snes - the SNES context 2322 2323 Output Parameter: 2324 . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2325 manual pages for the individual convergence tests for complete lists 2326 2327 Level: intermediate 2328 2329 Notes: Can only be called after the call the SNESSolve() is complete. 2330 2331 .keywords: SNES, nonlinear, set, convergence, test 2332 2333 .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2334 @*/ 2335 PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2336 { 2337 PetscFunctionBegin; 2338 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2339 PetscValidPointer(reason,2); 2340 *reason = snes->reason; 2341 PetscFunctionReturn(0); 2342 } 2343 2344 #undef __FUNCT__ 2345 #define __FUNCT__ "SNESSetConvergenceHistory" 2346 /*@ 2347 SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2348 2349 Logically Collective on SNES 2350 2351 Input Parameters: 2352 + snes - iterative context obtained from SNESCreate() 2353 . a - array to hold history, this array will contain the function norms computed at each step 2354 . its - integer array holds the number of linear iterations for each solve. 2355 . na - size of a and its 2356 - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2357 else it continues storing new values for new nonlinear solves after the old ones 2358 2359 Notes: 2360 If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2361 default array of length 10000 is allocated. 2362 2363 This routine is useful, e.g., when running a code for purposes 2364 of accurate performance monitoring, when no I/O should be done 2365 during the section of code that is being timed. 2366 2367 Level: intermediate 2368 2369 .keywords: SNES, set, convergence, history 2370 2371 .seealso: SNESGetConvergenceHistory() 2372 2373 @*/ 2374 PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2375 { 2376 PetscErrorCode ierr; 2377 2378 PetscFunctionBegin; 2379 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2380 if (na) PetscValidScalarPointer(a,2); 2381 if (its) PetscValidIntPointer(its,3); 2382 if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2383 if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2384 ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2385 ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2386 snes->conv_malloc = PETSC_TRUE; 2387 } 2388 snes->conv_hist = a; 2389 snes->conv_hist_its = its; 2390 snes->conv_hist_max = na; 2391 snes->conv_hist_len = 0; 2392 snes->conv_hist_reset = reset; 2393 PetscFunctionReturn(0); 2394 } 2395 2396 #if defined(PETSC_HAVE_MATLAB_ENGINE) 2397 #include <engine.h> /* MATLAB include file */ 2398 #include <mex.h> /* MATLAB include file */ 2399 EXTERN_C_BEGIN 2400 #undef __FUNCT__ 2401 #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2402 mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2403 { 2404 mxArray *mat; 2405 PetscInt i; 2406 PetscReal *ar; 2407 2408 PetscFunctionBegin; 2409 mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2410 ar = (PetscReal*) mxGetData(mat); 2411 for (i=0; i<snes->conv_hist_len; i++) { 2412 ar[i] = snes->conv_hist[i]; 2413 } 2414 PetscFunctionReturn(mat); 2415 } 2416 EXTERN_C_END 2417 #endif 2418 2419 2420 #undef __FUNCT__ 2421 #define __FUNCT__ "SNESGetConvergenceHistory" 2422 /*@C 2423 SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 2424 2425 Not Collective 2426 2427 Input Parameter: 2428 . snes - iterative context obtained from SNESCreate() 2429 2430 Output Parameters: 2431 . a - array to hold history 2432 . its - integer array holds the number of linear iterations (or 2433 negative if not converged) for each solve. 2434 - na - size of a and its 2435 2436 Notes: 2437 The calling sequence for this routine in Fortran is 2438 $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 2439 2440 This routine is useful, e.g., when running a code for purposes 2441 of accurate performance monitoring, when no I/O should be done 2442 during the section of code that is being timed. 2443 2444 Level: intermediate 2445 2446 .keywords: SNES, get, convergence, history 2447 2448 .seealso: SNESSetConvergencHistory() 2449 2450 @*/ 2451 PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 2452 { 2453 PetscFunctionBegin; 2454 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2455 if (a) *a = snes->conv_hist; 2456 if (its) *its = snes->conv_hist_its; 2457 if (na) *na = snes->conv_hist_len; 2458 PetscFunctionReturn(0); 2459 } 2460 2461 #undef __FUNCT__ 2462 #define __FUNCT__ "SNESSetUpdate" 2463 /*@C 2464 SNESSetUpdate - Sets the general-purpose update function called 2465 at the beginning of every iteration of the nonlinear solve. Specifically 2466 it is called just before the Jacobian is "evaluated". 2467 2468 Logically Collective on SNES 2469 2470 Input Parameters: 2471 . snes - The nonlinear solver context 2472 . func - The function 2473 2474 Calling sequence of func: 2475 . func (SNES snes, PetscInt step); 2476 2477 . step - The current step of the iteration 2478 2479 Level: advanced 2480 2481 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() 2482 This is not used by most users. 2483 2484 .keywords: SNES, update 2485 2486 .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 2487 @*/ 2488 PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 2489 { 2490 PetscFunctionBegin; 2491 PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 2492 snes->ops->update = func; 2493 PetscFunctionReturn(0); 2494 } 2495 2496 #undef __FUNCT__ 2497 #define __FUNCT__ "SNESDefaultUpdate" 2498 /*@ 2499 SNESDefaultUpdate - The default update function which does nothing. 2500 2501 Not collective 2502 2503 Input Parameters: 2504 . snes - The nonlinear solver context 2505 . step - The current step of the iteration 2506 2507 Level: intermediate 2508 2509 .keywords: SNES, update 2510 .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 2511 @*/ 2512 PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 2513 { 2514 PetscFunctionBegin; 2515 PetscFunctionReturn(0); 2516 } 2517 2518 #undef __FUNCT__ 2519 #define __FUNCT__ "SNESScaleStep_Private" 2520 /* 2521 SNESScaleStep_Private - Scales a step so that its length is less than the 2522 positive parameter delta. 2523 2524 Input Parameters: 2525 + snes - the SNES context 2526 . y - approximate solution of linear system 2527 . fnorm - 2-norm of current function 2528 - delta - trust region size 2529 2530 Output Parameters: 2531 + gpnorm - predicted function norm at the new point, assuming local 2532 linearization. The value is zero if the step lies within the trust 2533 region, and exceeds zero otherwise. 2534 - ynorm - 2-norm of the step 2535 2536 Note: 2537 For non-trust region methods such as SNESLS, the parameter delta 2538 is set to be the maximum allowable step size. 2539 2540 .keywords: SNES, nonlinear, scale, step 2541 */ 2542 PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 2543 { 2544 PetscReal nrm; 2545 PetscScalar cnorm; 2546 PetscErrorCode ierr; 2547 2548 PetscFunctionBegin; 2549 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2550 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 2551 PetscCheckSameComm(snes,1,y,2); 2552 2553 ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 2554 if (nrm > *delta) { 2555 nrm = *delta/nrm; 2556 *gpnorm = (1.0 - nrm)*(*fnorm); 2557 cnorm = nrm; 2558 ierr = VecScale(y,cnorm);CHKERRQ(ierr); 2559 *ynorm = *delta; 2560 } else { 2561 *gpnorm = 0.0; 2562 *ynorm = nrm; 2563 } 2564 PetscFunctionReturn(0); 2565 } 2566 2567 #undef __FUNCT__ 2568 #define __FUNCT__ "SNESSolve" 2569 /*@C 2570 SNESSolve - Solves a nonlinear system F(x) = b. 2571 Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 2572 2573 Collective on SNES 2574 2575 Input Parameters: 2576 + snes - the SNES context 2577 . b - the constant part of the equation, or PETSC_NULL to use zero. 2578 - x - the solution vector. 2579 2580 Notes: 2581 The user should initialize the vector,x, with the initial guess 2582 for the nonlinear solve prior to calling SNESSolve. In particular, 2583 to employ an initial guess of zero, the user should explicitly set 2584 this vector to zero by calling VecSet(). 2585 2586 Level: beginner 2587 2588 .keywords: SNES, nonlinear, solve 2589 2590 .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian() 2591 @*/ 2592 PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 2593 { 2594 PetscErrorCode ierr; 2595 PetscBool flg; 2596 char filename[PETSC_MAX_PATH_LEN]; 2597 PetscViewer viewer; 2598 PetscInt grid; 2599 2600 PetscFunctionBegin; 2601 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2602 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2603 PetscCheckSameComm(snes,1,x,3); 2604 if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 2605 if (b) PetscCheckSameComm(snes,1,b,2); 2606 2607 for (grid=0; grid<snes->gridsequence+1; grid++) { 2608 2609 /* set solution vector */ 2610 if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 2611 ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 2612 snes->vec_sol = x; 2613 /* set afine vector if provided */ 2614 if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 2615 ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 2616 snes->vec_rhs = b; 2617 2618 ierr = SNESSetUp(snes);CHKERRQ(ierr); 2619 2620 if (!grid && snes->ops->computeinitialguess) { 2621 ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 2622 } 2623 2624 if (snes->conv_hist_reset) snes->conv_hist_len = 0; 2625 snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 2626 2627 ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 2628 ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 2629 ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 2630 if (snes->domainerror){ 2631 snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 2632 snes->domainerror = PETSC_FALSE; 2633 } 2634 if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 2635 2636 ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 2637 if (flg && !PetscPreLoadingOn) { 2638 ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 2639 ierr = SNESView(snes,viewer);CHKERRQ(ierr); 2640 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 2641 } 2642 2643 flg = PETSC_FALSE; 2644 ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 2645 if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 2646 if (snes->printreason) { 2647 if (snes->reason > 0) { 2648 ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 2649 } else { 2650 ierr = PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 2651 } 2652 } 2653 2654 if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 2655 if (grid < snes->gridsequence) { 2656 DM fine; 2657 Vec xnew; 2658 Mat interp; 2659 2660 ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 2661 ierr = DMGetInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 2662 ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 2663 ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 2664 ierr = MatDestroy(&interp);CHKERRQ(ierr); 2665 x = xnew; 2666 2667 ierr = SNESReset(snes);CHKERRQ(ierr); 2668 ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 2669 ierr = DMDestroy(&fine);CHKERRQ(ierr); 2670 } 2671 } 2672 PetscFunctionReturn(0); 2673 } 2674 2675 /* --------- Internal routines for SNES Package --------- */ 2676 2677 #undef __FUNCT__ 2678 #define __FUNCT__ "SNESSetType" 2679 /*@C 2680 SNESSetType - Sets the method for the nonlinear solver. 2681 2682 Collective on SNES 2683 2684 Input Parameters: 2685 + snes - the SNES context 2686 - type - a known method 2687 2688 Options Database Key: 2689 . -snes_type <type> - Sets the method; use -help for a list 2690 of available methods (for instance, ls or tr) 2691 2692 Notes: 2693 See "petsc/include/petscsnes.h" for available methods (for instance) 2694 + SNESLS - Newton's method with line search 2695 (systems of nonlinear equations) 2696 . SNESTR - Newton's method with trust region 2697 (systems of nonlinear equations) 2698 2699 Normally, it is best to use the SNESSetFromOptions() command and then 2700 set the SNES solver type from the options database rather than by using 2701 this routine. Using the options database provides the user with 2702 maximum flexibility in evaluating the many nonlinear solvers. 2703 The SNESSetType() routine is provided for those situations where it 2704 is necessary to set the nonlinear solver independently of the command 2705 line or options database. This might be the case, for example, when 2706 the choice of solver changes during the execution of the program, 2707 and the user's application is taking responsibility for choosing the 2708 appropriate method. 2709 2710 Level: intermediate 2711 2712 .keywords: SNES, set, type 2713 2714 .seealso: SNESType, SNESCreate() 2715 2716 @*/ 2717 PetscErrorCode SNESSetType(SNES snes,const SNESType type) 2718 { 2719 PetscErrorCode ierr,(*r)(SNES); 2720 PetscBool match; 2721 2722 PetscFunctionBegin; 2723 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2724 PetscValidCharPointer(type,2); 2725 2726 ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 2727 if (match) PetscFunctionReturn(0); 2728 2729 ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 2730 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 2731 /* Destroy the previous private SNES context */ 2732 if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 2733 /* Reinitialize function pointers in SNESOps structure */ 2734 snes->ops->setup = 0; 2735 snes->ops->solve = 0; 2736 snes->ops->view = 0; 2737 snes->ops->setfromoptions = 0; 2738 snes->ops->destroy = 0; 2739 /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 2740 snes->setupcalled = PETSC_FALSE; 2741 ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 2742 ierr = (*r)(snes);CHKERRQ(ierr); 2743 #if defined(PETSC_HAVE_AMS) 2744 if (PetscAMSPublishAll) { 2745 ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 2746 } 2747 #endif 2748 PetscFunctionReturn(0); 2749 } 2750 2751 2752 /* --------------------------------------------------------------------- */ 2753 #undef __FUNCT__ 2754 #define __FUNCT__ "SNESRegisterDestroy" 2755 /*@ 2756 SNESRegisterDestroy - Frees the list of nonlinear solvers that were 2757 registered by SNESRegisterDynamic(). 2758 2759 Not Collective 2760 2761 Level: advanced 2762 2763 .keywords: SNES, nonlinear, register, destroy 2764 2765 .seealso: SNESRegisterAll(), SNESRegisterAll() 2766 @*/ 2767 PetscErrorCode SNESRegisterDestroy(void) 2768 { 2769 PetscErrorCode ierr; 2770 2771 PetscFunctionBegin; 2772 ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 2773 SNESRegisterAllCalled = PETSC_FALSE; 2774 PetscFunctionReturn(0); 2775 } 2776 2777 #undef __FUNCT__ 2778 #define __FUNCT__ "SNESGetType" 2779 /*@C 2780 SNESGetType - Gets the SNES method type and name (as a string). 2781 2782 Not Collective 2783 2784 Input Parameter: 2785 . snes - nonlinear solver context 2786 2787 Output Parameter: 2788 . type - SNES method (a character string) 2789 2790 Level: intermediate 2791 2792 .keywords: SNES, nonlinear, get, type, name 2793 @*/ 2794 PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 2795 { 2796 PetscFunctionBegin; 2797 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2798 PetscValidPointer(type,2); 2799 *type = ((PetscObject)snes)->type_name; 2800 PetscFunctionReturn(0); 2801 } 2802 2803 #undef __FUNCT__ 2804 #define __FUNCT__ "SNESGetSolution" 2805 /*@ 2806 SNESGetSolution - Returns the vector where the approximate solution is 2807 stored. 2808 2809 Not Collective, but Vec is parallel if SNES is parallel 2810 2811 Input Parameter: 2812 . snes - the SNES context 2813 2814 Output Parameter: 2815 . x - the solution 2816 2817 Level: intermediate 2818 2819 .keywords: SNES, nonlinear, get, solution 2820 2821 .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 2822 @*/ 2823 PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 2824 { 2825 PetscFunctionBegin; 2826 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2827 PetscValidPointer(x,2); 2828 *x = snes->vec_sol; 2829 PetscFunctionReturn(0); 2830 } 2831 2832 #undef __FUNCT__ 2833 #define __FUNCT__ "SNESGetSolutionUpdate" 2834 /*@ 2835 SNESGetSolutionUpdate - Returns the vector where the solution update is 2836 stored. 2837 2838 Not Collective, but Vec is parallel if SNES is parallel 2839 2840 Input Parameter: 2841 . snes - the SNES context 2842 2843 Output Parameter: 2844 . x - the solution update 2845 2846 Level: advanced 2847 2848 .keywords: SNES, nonlinear, get, solution, update 2849 2850 .seealso: SNESGetSolution(), SNESGetFunction() 2851 @*/ 2852 PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 2853 { 2854 PetscFunctionBegin; 2855 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2856 PetscValidPointer(x,2); 2857 *x = snes->vec_sol_update; 2858 PetscFunctionReturn(0); 2859 } 2860 2861 #undef __FUNCT__ 2862 #define __FUNCT__ "SNESGetFunction" 2863 /*@C 2864 SNESGetFunction - Returns the vector where the function is stored. 2865 2866 Not Collective, but Vec is parallel if SNES is parallel 2867 2868 Input Parameter: 2869 . snes - the SNES context 2870 2871 Output Parameter: 2872 + r - the function (or PETSC_NULL) 2873 . func - the function (or PETSC_NULL) 2874 - ctx - the function context (or PETSC_NULL) 2875 2876 Level: advanced 2877 2878 .keywords: SNES, nonlinear, get, function 2879 2880 .seealso: SNESSetFunction(), SNESGetSolution() 2881 @*/ 2882 PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 2883 { 2884 PetscFunctionBegin; 2885 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2886 if (r) *r = snes->vec_func; 2887 if (func) *func = snes->ops->computefunction; 2888 if (ctx) *ctx = snes->funP; 2889 PetscFunctionReturn(0); 2890 } 2891 2892 #undef __FUNCT__ 2893 #define __FUNCT__ "SNESSetOptionsPrefix" 2894 /*@C 2895 SNESSetOptionsPrefix - Sets the prefix used for searching for all 2896 SNES options in the database. 2897 2898 Logically Collective on SNES 2899 2900 Input Parameter: 2901 + snes - the SNES context 2902 - prefix - the prefix to prepend to all option names 2903 2904 Notes: 2905 A hyphen (-) must NOT be given at the beginning of the prefix name. 2906 The first character of all runtime options is AUTOMATICALLY the hyphen. 2907 2908 Level: advanced 2909 2910 .keywords: SNES, set, options, prefix, database 2911 2912 .seealso: SNESSetFromOptions() 2913 @*/ 2914 PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 2915 { 2916 PetscErrorCode ierr; 2917 2918 PetscFunctionBegin; 2919 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2920 ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2921 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 2922 ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2923 PetscFunctionReturn(0); 2924 } 2925 2926 #undef __FUNCT__ 2927 #define __FUNCT__ "SNESAppendOptionsPrefix" 2928 /*@C 2929 SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 2930 SNES options in the database. 2931 2932 Logically Collective on SNES 2933 2934 Input Parameters: 2935 + snes - the SNES context 2936 - prefix - the prefix to prepend to all option names 2937 2938 Notes: 2939 A hyphen (-) must NOT be given at the beginning of the prefix name. 2940 The first character of all runtime options is AUTOMATICALLY the hyphen. 2941 2942 Level: advanced 2943 2944 .keywords: SNES, append, options, prefix, database 2945 2946 .seealso: SNESGetOptionsPrefix() 2947 @*/ 2948 PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 2949 { 2950 PetscErrorCode ierr; 2951 2952 PetscFunctionBegin; 2953 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2954 ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2955 if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 2956 ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 2957 PetscFunctionReturn(0); 2958 } 2959 2960 #undef __FUNCT__ 2961 #define __FUNCT__ "SNESGetOptionsPrefix" 2962 /*@C 2963 SNESGetOptionsPrefix - Sets the prefix used for searching for all 2964 SNES options in the database. 2965 2966 Not Collective 2967 2968 Input Parameter: 2969 . snes - the SNES context 2970 2971 Output Parameter: 2972 . prefix - pointer to the prefix string used 2973 2974 Notes: On the fortran side, the user should pass in a string 'prefix' of 2975 sufficient length to hold the prefix. 2976 2977 Level: advanced 2978 2979 .keywords: SNES, get, options, prefix, database 2980 2981 .seealso: SNESAppendOptionsPrefix() 2982 @*/ 2983 PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 2984 { 2985 PetscErrorCode ierr; 2986 2987 PetscFunctionBegin; 2988 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2989 ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 2990 PetscFunctionReturn(0); 2991 } 2992 2993 2994 #undef __FUNCT__ 2995 #define __FUNCT__ "SNESRegister" 2996 /*@C 2997 SNESRegister - See SNESRegisterDynamic() 2998 2999 Level: advanced 3000 @*/ 3001 PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3002 { 3003 char fullname[PETSC_MAX_PATH_LEN]; 3004 PetscErrorCode ierr; 3005 3006 PetscFunctionBegin; 3007 ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3008 ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3009 PetscFunctionReturn(0); 3010 } 3011 3012 #undef __FUNCT__ 3013 #define __FUNCT__ "SNESTestLocalMin" 3014 PetscErrorCode SNESTestLocalMin(SNES snes) 3015 { 3016 PetscErrorCode ierr; 3017 PetscInt N,i,j; 3018 Vec u,uh,fh; 3019 PetscScalar value; 3020 PetscReal norm; 3021 3022 PetscFunctionBegin; 3023 ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3024 ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3025 ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3026 3027 /* currently only works for sequential */ 3028 ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3029 ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3030 for (i=0; i<N; i++) { 3031 ierr = VecCopy(u,uh);CHKERRQ(ierr); 3032 ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3033 for (j=-10; j<11; j++) { 3034 value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3035 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3036 ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3037 ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 3038 ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3039 value = -value; 3040 ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3041 } 3042 } 3043 ierr = VecDestroy(&uh);CHKERRQ(ierr); 3044 ierr = VecDestroy(&fh);CHKERRQ(ierr); 3045 PetscFunctionReturn(0); 3046 } 3047 3048 #undef __FUNCT__ 3049 #define __FUNCT__ "SNESKSPSetUseEW" 3050 /*@ 3051 SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 3052 computing relative tolerance for linear solvers within an inexact 3053 Newton method. 3054 3055 Logically Collective on SNES 3056 3057 Input Parameters: 3058 + snes - SNES context 3059 - flag - PETSC_TRUE or PETSC_FALSE 3060 3061 Options Database: 3062 + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 3063 . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 3064 . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 3065 . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 3066 . -snes_ksp_ew_gamma <gamma> - Sets gamma 3067 . -snes_ksp_ew_alpha <alpha> - Sets alpha 3068 . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 3069 - -snes_ksp_ew_threshold <threshold> - Sets threshold 3070 3071 Notes: 3072 Currently, the default is to use a constant relative tolerance for 3073 the inner linear solvers. Alternatively, one can use the 3074 Eisenstat-Walker method, where the relative convergence tolerance 3075 is reset at each Newton iteration according progress of the nonlinear 3076 solver. 3077 3078 Level: advanced 3079 3080 Reference: 3081 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 3082 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 3083 3084 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 3085 3086 .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 3087 @*/ 3088 PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 3089 { 3090 PetscFunctionBegin; 3091 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3092 PetscValidLogicalCollectiveBool(snes,flag,2); 3093 snes->ksp_ewconv = flag; 3094 PetscFunctionReturn(0); 3095 } 3096 3097 #undef __FUNCT__ 3098 #define __FUNCT__ "SNESKSPGetUseEW" 3099 /*@ 3100 SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 3101 for computing relative tolerance for linear solvers within an 3102 inexact Newton method. 3103 3104 Not Collective 3105 3106 Input Parameter: 3107 . snes - SNES context 3108 3109 Output Parameter: 3110 . flag - PETSC_TRUE or PETSC_FALSE 3111 3112 Notes: 3113 Currently, the default is to use a constant relative tolerance for 3114 the inner linear solvers. Alternatively, one can use the 3115 Eisenstat-Walker method, where the relative convergence tolerance 3116 is reset at each Newton iteration according progress of the nonlinear 3117 solver. 3118 3119 Level: advanced 3120 3121 Reference: 3122 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 3123 inexact Newton method", SISC 17 (1), pp.16-32, 1996. 3124 3125 .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 3126 3127 .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 3128 @*/ 3129 PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 3130 { 3131 PetscFunctionBegin; 3132 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3133 PetscValidPointer(flag,2); 3134 *flag = snes->ksp_ewconv; 3135 PetscFunctionReturn(0); 3136 } 3137 3138 #undef __FUNCT__ 3139 #define __FUNCT__ "SNESKSPSetParametersEW" 3140 /*@ 3141 SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 3142 convergence criteria for the linear solvers within an inexact 3143 Newton method. 3144 3145 Logically Collective on SNES 3146 3147 Input Parameters: 3148 + snes - SNES context 3149 . version - version 1, 2 (default is 2) or 3 3150 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 3151 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 3152 . gamma - multiplicative factor for version 2 rtol computation 3153 (0 <= gamma2 <= 1) 3154 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 3155 . alpha2 - power for safeguard 3156 - threshold - threshold for imposing safeguard (0 < threshold < 1) 3157 3158 Note: 3159 Version 3 was contributed by Luis Chacon, June 2006. 3160 3161 Use PETSC_DEFAULT to retain the default for any of the parameters. 3162 3163 Level: advanced 3164 3165 Reference: 3166 S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 3167 inexact Newton method", Utah State University Math. Stat. Dept. Res. 3168 Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 3169 3170 .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 3171 3172 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 3173 @*/ 3174 PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 3175 PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 3176 { 3177 SNESKSPEW *kctx; 3178 PetscFunctionBegin; 3179 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3180 kctx = (SNESKSPEW*)snes->kspconvctx; 3181 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3182 PetscValidLogicalCollectiveInt(snes,version,2); 3183 PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3184 PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3185 PetscValidLogicalCollectiveReal(snes,gamma,5); 3186 PetscValidLogicalCollectiveReal(snes,alpha,6); 3187 PetscValidLogicalCollectiveReal(snes,alpha2,7); 3188 PetscValidLogicalCollectiveReal(snes,threshold,8); 3189 3190 if (version != PETSC_DEFAULT) kctx->version = version; 3191 if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 3192 if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 3193 if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 3194 if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 3195 if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 3196 if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 3197 3198 if (kctx->version < 1 || kctx->version > 3) { 3199 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 3200 } 3201 if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3202 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 3203 } 3204 if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3205 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 3206 } 3207 if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3208 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 3209 } 3210 if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3211 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 3212 } 3213 if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3214 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 3215 } 3216 PetscFunctionReturn(0); 3217 } 3218 3219 #undef __FUNCT__ 3220 #define __FUNCT__ "SNESKSPGetParametersEW" 3221 /*@ 3222 SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 3223 convergence criteria for the linear solvers within an inexact 3224 Newton method. 3225 3226 Not Collective 3227 3228 Input Parameters: 3229 snes - SNES context 3230 3231 Output Parameters: 3232 + version - version 1, 2 (default is 2) or 3 3233 . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 3234 . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 3235 . gamma - multiplicative factor for version 2 rtol computation 3236 (0 <= gamma2 <= 1) 3237 . alpha - power for version 2 rtol computation (1 < alpha <= 2) 3238 . alpha2 - power for safeguard 3239 - threshold - threshold for imposing safeguard (0 < threshold < 1) 3240 3241 Level: advanced 3242 3243 .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 3244 3245 .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 3246 @*/ 3247 PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 3248 PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 3249 { 3250 SNESKSPEW *kctx; 3251 PetscFunctionBegin; 3252 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3253 kctx = (SNESKSPEW*)snes->kspconvctx; 3254 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3255 if(version) *version = kctx->version; 3256 if(rtol_0) *rtol_0 = kctx->rtol_0; 3257 if(rtol_max) *rtol_max = kctx->rtol_max; 3258 if(gamma) *gamma = kctx->gamma; 3259 if(alpha) *alpha = kctx->alpha; 3260 if(alpha2) *alpha2 = kctx->alpha2; 3261 if(threshold) *threshold = kctx->threshold; 3262 PetscFunctionReturn(0); 3263 } 3264 3265 #undef __FUNCT__ 3266 #define __FUNCT__ "SNESKSPEW_PreSolve" 3267 static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 3268 { 3269 PetscErrorCode ierr; 3270 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 3271 PetscReal rtol=PETSC_DEFAULT,stol; 3272 3273 PetscFunctionBegin; 3274 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3275 if (!snes->iter) { /* first time in, so use the original user rtol */ 3276 rtol = kctx->rtol_0; 3277 } else { 3278 if (kctx->version == 1) { 3279 rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 3280 if (rtol < 0.0) rtol = -rtol; 3281 stol = pow(kctx->rtol_last,kctx->alpha2); 3282 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3283 } else if (kctx->version == 2) { 3284 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3285 stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 3286 if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 3287 } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 3288 rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 3289 /* safeguard: avoid sharp decrease of rtol */ 3290 stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 3291 stol = PetscMax(rtol,stol); 3292 rtol = PetscMin(kctx->rtol_0,stol); 3293 /* safeguard: avoid oversolving */ 3294 stol = kctx->gamma*(snes->ttol)/snes->norm; 3295 stol = PetscMax(rtol,stol); 3296 rtol = PetscMin(kctx->rtol_0,stol); 3297 } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 3298 } 3299 /* safeguard: avoid rtol greater than one */ 3300 rtol = PetscMin(rtol,kctx->rtol_max); 3301 ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 3302 ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 3303 PetscFunctionReturn(0); 3304 } 3305 3306 #undef __FUNCT__ 3307 #define __FUNCT__ "SNESKSPEW_PostSolve" 3308 static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 3309 { 3310 PetscErrorCode ierr; 3311 SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 3312 PCSide pcside; 3313 Vec lres; 3314 3315 PetscFunctionBegin; 3316 if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 3317 ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 3318 ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 3319 if (kctx->version == 1) { 3320 ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 3321 if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 3322 /* KSP residual is true linear residual */ 3323 ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 3324 } else { 3325 /* KSP residual is preconditioned residual */ 3326 /* compute true linear residual norm */ 3327 ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 3328 ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 3329 ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 3330 ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 3331 ierr = VecDestroy(&lres);CHKERRQ(ierr); 3332 } 3333 } 3334 PetscFunctionReturn(0); 3335 } 3336 3337 #undef __FUNCT__ 3338 #define __FUNCT__ "SNES_KSPSolve" 3339 PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 3340 { 3341 PetscErrorCode ierr; 3342 3343 PetscFunctionBegin; 3344 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3345 ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3346 if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 3347 PetscFunctionReturn(0); 3348 } 3349 3350 #undef __FUNCT__ 3351 #define __FUNCT__ "SNESSetDM" 3352 /*@ 3353 SNESSetDM - Sets the DM that may be used by some preconditioners 3354 3355 Logically Collective on SNES 3356 3357 Input Parameters: 3358 + snes - the preconditioner context 3359 - dm - the dm 3360 3361 Level: intermediate 3362 3363 3364 .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 3365 @*/ 3366 PetscErrorCode SNESSetDM(SNES snes,DM dm) 3367 { 3368 PetscErrorCode ierr; 3369 KSP ksp; 3370 3371 PetscFunctionBegin; 3372 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3373 if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 3374 ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 3375 snes->dm = dm; 3376 ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3377 ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3378 ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 3379 PetscFunctionReturn(0); 3380 } 3381 3382 #undef __FUNCT__ 3383 #define __FUNCT__ "SNESGetDM" 3384 /*@ 3385 SNESGetDM - Gets the DM that may be used by some preconditioners 3386 3387 Not Collective but DM obtained is parallel on SNES 3388 3389 Input Parameter: 3390 . snes - the preconditioner context 3391 3392 Output Parameter: 3393 . dm - the dm 3394 3395 Level: intermediate 3396 3397 3398 .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 3399 @*/ 3400 PetscErrorCode SNESGetDM(SNES snes,DM *dm) 3401 { 3402 PetscFunctionBegin; 3403 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3404 *dm = snes->dm; 3405 PetscFunctionReturn(0); 3406 } 3407 3408 #undef __FUNCT__ 3409 #define __FUNCT__ "SNESSetPC" 3410 /*@ 3411 SNESSetPC - Sets the preconditioner to be used. 3412 3413 Collective on SNES 3414 3415 Input Parameters: 3416 + snes - iterative context obtained from SNESCreate() 3417 - pc - the preconditioner object 3418 3419 Notes: 3420 Use SNESGetPC() to retrieve the preconditioner context (for example, 3421 to configure it using the API). 3422 3423 Level: developer 3424 3425 .keywords: SNES, set, precondition 3426 .seealso: SNESGetPC() 3427 @*/ 3428 PetscErrorCode SNESSetPC(SNES snes, SNES pc) 3429 { 3430 PetscErrorCode ierr; 3431 3432 PetscFunctionBegin; 3433 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3434 PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 3435 PetscCheckSameComm(snes, 1, pc, 2); 3436 ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 3437 ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 3438 snes->pc = pc; 3439 ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 3440 PetscFunctionReturn(0); 3441 } 3442 3443 #undef __FUNCT__ 3444 #define __FUNCT__ "SNESGetPC" 3445 /*@ 3446 SNESGetPC - Returns a pointer to the preconditioner context set with SNESSetPC(). 3447 3448 Not Collective 3449 3450 Input Parameter: 3451 . snes - iterative context obtained from SNESCreate() 3452 3453 Output Parameter: 3454 . pc - preconditioner context 3455 3456 Level: developer 3457 3458 .keywords: SNES, get, preconditioner 3459 .seealso: SNESSetPC() 3460 @*/ 3461 PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 3462 { 3463 PetscErrorCode ierr; 3464 3465 PetscFunctionBegin; 3466 PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3467 PetscValidPointer(pc, 2); 3468 if (!snes->pc) { 3469 ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 3470 ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 3471 ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 3472 } 3473 *pc = snes->pc; 3474 PetscFunctionReturn(0); 3475 } 3476 3477 #if defined(PETSC_HAVE_MATLAB_ENGINE) 3478 #include <mex.h> 3479 3480 typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 3481 3482 #undef __FUNCT__ 3483 #define __FUNCT__ "SNESComputeFunction_Matlab" 3484 /* 3485 SNESComputeFunction_Matlab - Calls the function that has been set with 3486 SNESSetFunctionMatlab(). 3487 3488 Collective on SNES 3489 3490 Input Parameters: 3491 + snes - the SNES context 3492 - x - input vector 3493 3494 Output Parameter: 3495 . y - function vector, as set by SNESSetFunction() 3496 3497 Notes: 3498 SNESComputeFunction() is typically used within nonlinear solvers 3499 implementations, so most users would not generally call this routine 3500 themselves. 3501 3502 Level: developer 3503 3504 .keywords: SNES, nonlinear, compute, function 3505 3506 .seealso: SNESSetFunction(), SNESGetFunction() 3507 */ 3508 PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 3509 { 3510 PetscErrorCode ierr; 3511 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3512 int nlhs = 1,nrhs = 5; 3513 mxArray *plhs[1],*prhs[5]; 3514 long long int lx = 0,ly = 0,ls = 0; 3515 3516 PetscFunctionBegin; 3517 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3518 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3519 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3520 PetscCheckSameComm(snes,1,x,2); 3521 PetscCheckSameComm(snes,1,y,3); 3522 3523 /* call Matlab function in ctx with arguments x and y */ 3524 3525 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3526 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3527 ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 3528 prhs[0] = mxCreateDoubleScalar((double)ls); 3529 prhs[1] = mxCreateDoubleScalar((double)lx); 3530 prhs[2] = mxCreateDoubleScalar((double)ly); 3531 prhs[3] = mxCreateString(sctx->funcname); 3532 prhs[4] = sctx->ctx; 3533 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 3534 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3535 mxDestroyArray(prhs[0]); 3536 mxDestroyArray(prhs[1]); 3537 mxDestroyArray(prhs[2]); 3538 mxDestroyArray(prhs[3]); 3539 mxDestroyArray(plhs[0]); 3540 PetscFunctionReturn(0); 3541 } 3542 3543 3544 #undef __FUNCT__ 3545 #define __FUNCT__ "SNESSetFunctionMatlab" 3546 /* 3547 SNESSetFunctionMatlab - Sets the function evaluation routine and function 3548 vector for use by the SNES routines in solving systems of nonlinear 3549 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3550 3551 Logically Collective on SNES 3552 3553 Input Parameters: 3554 + snes - the SNES context 3555 . r - vector to store function value 3556 - func - function evaluation routine 3557 3558 Calling sequence of func: 3559 $ func (SNES snes,Vec x,Vec f,void *ctx); 3560 3561 3562 Notes: 3563 The Newton-like methods typically solve linear systems of the form 3564 $ f'(x) x = -f(x), 3565 where f'(x) denotes the Jacobian matrix and f(x) is the function. 3566 3567 Level: beginner 3568 3569 .keywords: SNES, nonlinear, set, function 3570 3571 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3572 */ 3573 PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 3574 { 3575 PetscErrorCode ierr; 3576 SNESMatlabContext *sctx; 3577 3578 PetscFunctionBegin; 3579 /* currently sctx is memory bleed */ 3580 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3581 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3582 /* 3583 This should work, but it doesn't 3584 sctx->ctx = ctx; 3585 mexMakeArrayPersistent(sctx->ctx); 3586 */ 3587 sctx->ctx = mxDuplicateArray(ctx); 3588 ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 3589 PetscFunctionReturn(0); 3590 } 3591 3592 #undef __FUNCT__ 3593 #define __FUNCT__ "SNESComputeJacobian_Matlab" 3594 /* 3595 SNESComputeJacobian_Matlab - Calls the function that has been set with 3596 SNESSetJacobianMatlab(). 3597 3598 Collective on SNES 3599 3600 Input Parameters: 3601 + snes - the SNES context 3602 . x - input vector 3603 . A, B - the matrices 3604 - ctx - user context 3605 3606 Output Parameter: 3607 . flag - structure of the matrix 3608 3609 Level: developer 3610 3611 .keywords: SNES, nonlinear, compute, function 3612 3613 .seealso: SNESSetFunction(), SNESGetFunction() 3614 @*/ 3615 PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 3616 { 3617 PetscErrorCode ierr; 3618 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3619 int nlhs = 2,nrhs = 6; 3620 mxArray *plhs[2],*prhs[6]; 3621 long long int lx = 0,lA = 0,ls = 0, lB = 0; 3622 3623 PetscFunctionBegin; 3624 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3625 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 3626 3627 /* call Matlab function in ctx with arguments x and y */ 3628 3629 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3630 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3631 ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 3632 ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 3633 prhs[0] = mxCreateDoubleScalar((double)ls); 3634 prhs[1] = mxCreateDoubleScalar((double)lx); 3635 prhs[2] = mxCreateDoubleScalar((double)lA); 3636 prhs[3] = mxCreateDoubleScalar((double)lB); 3637 prhs[4] = mxCreateString(sctx->funcname); 3638 prhs[5] = sctx->ctx; 3639 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 3640 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3641 *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 3642 mxDestroyArray(prhs[0]); 3643 mxDestroyArray(prhs[1]); 3644 mxDestroyArray(prhs[2]); 3645 mxDestroyArray(prhs[3]); 3646 mxDestroyArray(prhs[4]); 3647 mxDestroyArray(plhs[0]); 3648 mxDestroyArray(plhs[1]); 3649 PetscFunctionReturn(0); 3650 } 3651 3652 3653 #undef __FUNCT__ 3654 #define __FUNCT__ "SNESSetJacobianMatlab" 3655 /* 3656 SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 3657 vector for use by the SNES routines in solving systems of nonlinear 3658 equations from MATLAB. Here the function is a string containing the name of a MATLAB function 3659 3660 Logically Collective on SNES 3661 3662 Input Parameters: 3663 + snes - the SNES context 3664 . A,B - Jacobian matrices 3665 . func - function evaluation routine 3666 - ctx - user context 3667 3668 Calling sequence of func: 3669 $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 3670 3671 3672 Level: developer 3673 3674 .keywords: SNES, nonlinear, set, function 3675 3676 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3677 */ 3678 PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 3679 { 3680 PetscErrorCode ierr; 3681 SNESMatlabContext *sctx; 3682 3683 PetscFunctionBegin; 3684 /* currently sctx is memory bleed */ 3685 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3686 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3687 /* 3688 This should work, but it doesn't 3689 sctx->ctx = ctx; 3690 mexMakeArrayPersistent(sctx->ctx); 3691 */ 3692 sctx->ctx = mxDuplicateArray(ctx); 3693 ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 3694 PetscFunctionReturn(0); 3695 } 3696 3697 #undef __FUNCT__ 3698 #define __FUNCT__ "SNESMonitor_Matlab" 3699 /* 3700 SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 3701 3702 Collective on SNES 3703 3704 .seealso: SNESSetFunction(), SNESGetFunction() 3705 @*/ 3706 PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 3707 { 3708 PetscErrorCode ierr; 3709 SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 3710 int nlhs = 1,nrhs = 6; 3711 mxArray *plhs[1],*prhs[6]; 3712 long long int lx = 0,ls = 0; 3713 Vec x=snes->vec_sol; 3714 3715 PetscFunctionBegin; 3716 PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3717 3718 ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 3719 ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 3720 prhs[0] = mxCreateDoubleScalar((double)ls); 3721 prhs[1] = mxCreateDoubleScalar((double)it); 3722 prhs[2] = mxCreateDoubleScalar((double)fnorm); 3723 prhs[3] = mxCreateDoubleScalar((double)lx); 3724 prhs[4] = mxCreateString(sctx->funcname); 3725 prhs[5] = sctx->ctx; 3726 ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 3727 ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 3728 mxDestroyArray(prhs[0]); 3729 mxDestroyArray(prhs[1]); 3730 mxDestroyArray(prhs[2]); 3731 mxDestroyArray(prhs[3]); 3732 mxDestroyArray(prhs[4]); 3733 mxDestroyArray(plhs[0]); 3734 PetscFunctionReturn(0); 3735 } 3736 3737 3738 #undef __FUNCT__ 3739 #define __FUNCT__ "SNESMonitorSetMatlab" 3740 /* 3741 SNESMonitorSetMatlab - Sets the monitor function from MATLAB 3742 3743 Level: developer 3744 3745 .keywords: SNES, nonlinear, set, function 3746 3747 .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 3748 */ 3749 PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 3750 { 3751 PetscErrorCode ierr; 3752 SNESMatlabContext *sctx; 3753 3754 PetscFunctionBegin; 3755 /* currently sctx is memory bleed */ 3756 ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 3757 ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 3758 /* 3759 This should work, but it doesn't 3760 sctx->ctx = ctx; 3761 mexMakeArrayPersistent(sctx->ctx); 3762 */ 3763 sctx->ctx = mxDuplicateArray(ctx); 3764 ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 3765 PetscFunctionReturn(0); 3766 } 3767 3768 #endif 3769