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