19b94acceSBarry Smith 2c6db04a5SJed Brown #include <private/snesimpl.h> /*I "petscsnes.h" I*/ 39b94acceSBarry Smith 4ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 58ba1e511SMatthew Knepley PetscFList SNESList = PETSC_NULL; 68ba1e511SMatthew Knepley 78ba1e511SMatthew Knepley /* Logging support */ 87087cfbeSBarry Smith PetscClassId SNES_CLASSID; 9701cf23dSPeter Brune PetscLogEvent SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval; 10a09944afSBarry Smith 11a09944afSBarry Smith #undef __FUNCT__ 12cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian" 13cab2e9ccSBarry Smith /* 14cab2e9ccSBarry Smith Translates from a SNES call to a DM call in computing a Jacobian 15cab2e9ccSBarry Smith */ 16cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr) 17cab2e9ccSBarry Smith { 18cab2e9ccSBarry Smith PetscErrorCode ierr; 19cab2e9ccSBarry Smith DM dm; 20cab2e9ccSBarry Smith 21cab2e9ccSBarry Smith PetscFunctionBegin; 22cab2e9ccSBarry Smith ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23cab2e9ccSBarry Smith ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr); 24cab2e9ccSBarry Smith PetscFunctionReturn(0); 25cab2e9ccSBarry Smith } 26cab2e9ccSBarry Smith 27cab2e9ccSBarry Smith #undef __FUNCT__ 28e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged" 29e113a28aSBarry Smith /*@ 30e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 31e113a28aSBarry Smith 323f9fe445SBarry Smith Logically Collective on SNES 33e113a28aSBarry Smith 34e113a28aSBarry Smith Input Parameters: 35e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 36e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 37e113a28aSBarry Smith 38e113a28aSBarry Smith Options database keys: 39e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 40e113a28aSBarry Smith 41e113a28aSBarry Smith Level: intermediate 42e113a28aSBarry Smith 43e113a28aSBarry Smith Notes: 44e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 45e113a28aSBarry Smith to determine if it has converged. 46e113a28aSBarry Smith 47e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 48e113a28aSBarry Smith 49e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 50e113a28aSBarry Smith @*/ 517087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 52e113a28aSBarry Smith { 53e113a28aSBarry Smith PetscFunctionBegin; 54e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 55acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 56e113a28aSBarry Smith snes->errorifnotconverged = flg; 57dd568438SSatish Balay 58e113a28aSBarry Smith PetscFunctionReturn(0); 59e113a28aSBarry Smith } 60e113a28aSBarry Smith 61e113a28aSBarry Smith #undef __FUNCT__ 62e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged" 63e113a28aSBarry Smith /*@ 64e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 65e113a28aSBarry Smith 66e113a28aSBarry Smith Not Collective 67e113a28aSBarry Smith 68e113a28aSBarry Smith Input Parameter: 69e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 70e113a28aSBarry Smith 71e113a28aSBarry Smith Output Parameter: 72e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 73e113a28aSBarry Smith 74e113a28aSBarry Smith Level: intermediate 75e113a28aSBarry Smith 76e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 77e113a28aSBarry Smith 78e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 79e113a28aSBarry Smith @*/ 807087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 81e113a28aSBarry Smith { 82e113a28aSBarry Smith PetscFunctionBegin; 83e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 84e113a28aSBarry Smith PetscValidPointer(flag,2); 85e113a28aSBarry Smith *flag = snes->errorifnotconverged; 86e113a28aSBarry Smith PetscFunctionReturn(0); 87e113a28aSBarry Smith } 88e113a28aSBarry Smith 89e113a28aSBarry Smith #undef __FUNCT__ 904936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError" 91e725d27bSBarry Smith /*@ 924936397dSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 934936397dSBarry Smith in the functions domain. For example, negative pressure. 944936397dSBarry Smith 953f9fe445SBarry Smith Logically Collective on SNES 964936397dSBarry Smith 974936397dSBarry Smith Input Parameters: 984936397dSBarry Smith . SNES - the SNES context 994936397dSBarry Smith 10028529972SSatish Balay Level: advanced 1014936397dSBarry Smith 1024936397dSBarry Smith .keywords: SNES, view 1034936397dSBarry Smith 1044936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction() 1054936397dSBarry Smith @*/ 1067087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 1074936397dSBarry Smith { 1084936397dSBarry Smith PetscFunctionBegin; 1090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1104936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1114936397dSBarry Smith PetscFunctionReturn(0); 1124936397dSBarry Smith } 1134936397dSBarry Smith 1144936397dSBarry Smith #undef __FUNCT__ 1154a2ae208SSatish Balay #define __FUNCT__ "SNESView" 1167e2c5f70SBarry Smith /*@C 1179b94acceSBarry Smith SNESView - Prints the SNES data structure. 1189b94acceSBarry Smith 1194c49b128SBarry Smith Collective on SNES 120fee21e36SBarry Smith 121c7afd0dbSLois Curfman McInnes Input Parameters: 122c7afd0dbSLois Curfman McInnes + SNES - the SNES context 123c7afd0dbSLois Curfman McInnes - viewer - visualization context 124c7afd0dbSLois Curfman McInnes 1259b94acceSBarry Smith Options Database Key: 126c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 1279b94acceSBarry Smith 1289b94acceSBarry Smith Notes: 1299b94acceSBarry Smith The available visualization contexts include 130b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 131b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 132c8a8ba5cSLois Curfman McInnes output where only the first processor opens 133c8a8ba5cSLois Curfman McInnes the file. All other processors send their 134c8a8ba5cSLois Curfman McInnes data to the first processor to print. 1359b94acceSBarry Smith 1363e081fefSLois Curfman McInnes The user can open an alternative visualization context with 137b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 1389b94acceSBarry Smith 13936851e7fSLois Curfman McInnes Level: beginner 14036851e7fSLois Curfman McInnes 1419b94acceSBarry Smith .keywords: SNES, view 1429b94acceSBarry Smith 143b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 1449b94acceSBarry Smith @*/ 1457087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 1469b94acceSBarry Smith { 147fa9f3622SBarry Smith SNESKSPEW *kctx; 148dfbe8321SBarry Smith PetscErrorCode ierr; 14994b7f48cSBarry Smith KSP ksp; 150ace3abfcSBarry Smith PetscBool iascii,isstring; 1519b94acceSBarry Smith 1523a40ed3dSBarry Smith PetscFunctionBegin; 1530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1543050cee2SBarry Smith if (!viewer) { 1557adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 1563050cee2SBarry Smith } 1570700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 158c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 15974679c65SBarry Smith 1602692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1612692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 16232077d6dSBarry Smith if (iascii) { 163317d6ea6SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 164e7788613SBarry Smith if (snes->ops->view) { 165b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 166e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 167b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1680ef38995SBarry Smith } 16977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 170a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 17170441072SBarry Smith snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr); 17277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 17377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 1749b94acceSBarry Smith if (snes->ksp_ewconv) { 175fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 1769b94acceSBarry Smith if (kctx) { 17777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 178a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 179a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 1809b94acceSBarry Smith } 1819b94acceSBarry Smith } 182eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 183eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 184eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 185eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 186eb1f6c34SBarry Smith } 187eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 188eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 189eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 19042f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 191eb1f6c34SBarry Smith } 1920f5bd95cSBarry Smith } else if (isstring) { 193317d6ea6SBarry Smith const char *type; 194454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 195b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 19619bcc07fSBarry Smith } 19742f4f86dSBarry Smith if (snes->pc && snes->usespc) { 1984a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1994a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 2004a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2014a0c5b0cSMatthew G Knepley } 2022c155ee1SBarry Smith if (snes->usesksp) { 2032c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 204b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 20594b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 206b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2072c155ee1SBarry Smith } 2083a40ed3dSBarry Smith PetscFunctionReturn(0); 2099b94acceSBarry Smith } 2109b94acceSBarry Smith 21176b2cf59SMatthew Knepley /* 21276b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 21376b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 21476b2cf59SMatthew Knepley */ 21576b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 216a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2176849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 21876b2cf59SMatthew Knepley 219e74ef692SMatthew Knepley #undef __FUNCT__ 220e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 221ac226902SBarry Smith /*@C 22276b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 22376b2cf59SMatthew Knepley 22476b2cf59SMatthew Knepley Not Collective 22576b2cf59SMatthew Knepley 22676b2cf59SMatthew Knepley Input Parameter: 22776b2cf59SMatthew Knepley . snescheck - function that checks for options 22876b2cf59SMatthew Knepley 22976b2cf59SMatthew Knepley Level: developer 23076b2cf59SMatthew Knepley 23176b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 23276b2cf59SMatthew Knepley @*/ 2337087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 23476b2cf59SMatthew Knepley { 23576b2cf59SMatthew Knepley PetscFunctionBegin; 23676b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 237e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 23876b2cf59SMatthew Knepley } 23976b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 24076b2cf59SMatthew Knepley PetscFunctionReturn(0); 24176b2cf59SMatthew Knepley } 24276b2cf59SMatthew Knepley 2437087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 244aa3661deSLisandro Dalcin 245aa3661deSLisandro Dalcin #undef __FUNCT__ 246aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 247ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 248aa3661deSLisandro Dalcin { 249aa3661deSLisandro Dalcin Mat J; 250aa3661deSLisandro Dalcin KSP ksp; 251aa3661deSLisandro Dalcin PC pc; 252ace3abfcSBarry Smith PetscBool match; 253aa3661deSLisandro Dalcin PetscErrorCode ierr; 254aa3661deSLisandro Dalcin 255aa3661deSLisandro Dalcin PetscFunctionBegin; 2560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 257aa3661deSLisandro Dalcin 25898613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 25998613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 26098613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 26198613b67SLisandro Dalcin } 26298613b67SLisandro Dalcin 263aa3661deSLisandro Dalcin if (version == 1) { 264aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 26598613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2669c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 267aa3661deSLisandro Dalcin } else if (version == 2) { 268e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 26982a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 270aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 271aa3661deSLisandro Dalcin #else 272e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 273aa3661deSLisandro Dalcin #endif 274a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 275aa3661deSLisandro Dalcin 276aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 277d3462f78SMatthew Knepley if (hasOperator) { 278aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 279aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 280aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 281aa3661deSLisandro Dalcin } else { 282aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 283aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 284aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 285aa3661deSLisandro Dalcin /* Force no preconditioner */ 286aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 287aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 288aa3661deSLisandro Dalcin ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 289aa3661deSLisandro Dalcin if (!match) { 290aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 291aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 292aa3661deSLisandro Dalcin } 293aa3661deSLisandro Dalcin } 2946bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 295aa3661deSLisandro Dalcin PetscFunctionReturn(0); 296aa3661deSLisandro Dalcin } 297aa3661deSLisandro Dalcin 2984a2ae208SSatish Balay #undef __FUNCT__ 2994a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 3009b94acceSBarry Smith /*@ 30194b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 3029b94acceSBarry Smith 303c7afd0dbSLois Curfman McInnes Collective on SNES 304c7afd0dbSLois Curfman McInnes 3059b94acceSBarry Smith Input Parameter: 3069b94acceSBarry Smith . snes - the SNES context 3079b94acceSBarry Smith 30836851e7fSLois Curfman McInnes Options Database Keys: 309ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 31082738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 31182738288SBarry Smith of the change in the solution between steps 31270441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 313b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 314b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 315b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 316*4839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 317ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 318a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 319e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 320b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 3212492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 32282738288SBarry Smith solver; hence iterations will continue until max_it 3231fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 32482738288SBarry Smith of convergence test 325e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 326e8105e01SRichard Katz filename given prints to stdout 327a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 328a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 329a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 330a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 331e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 3325968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 333fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 33482738288SBarry Smith 33582738288SBarry Smith Options Database for Eisenstat-Walker method: 336fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 3374b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 33836851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 33936851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 34036851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 34136851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 34236851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 34336851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 34482738288SBarry Smith 34511ca99fdSLois Curfman McInnes Notes: 34611ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 3470598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 34883e2fdc7SBarry Smith 34936851e7fSLois Curfman McInnes Level: beginner 35036851e7fSLois Curfman McInnes 3519b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 3529b94acceSBarry Smith 35369ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 3549b94acceSBarry Smith @*/ 3557087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 3569b94acceSBarry Smith { 357ea630c6eSPeter Brune PetscBool flg,set,mf,mf_operator,pcset; 358efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 359aa3661deSLisandro Dalcin MatStructure matflag; 36085385478SLisandro Dalcin const char *deft = SNESLS; 36185385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 36285385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 363e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 36451e86f29SPeter Brune const char *optionsprefix; 365649052a6SBarry Smith PetscViewer monviewer; 36685385478SLisandro Dalcin PetscErrorCode ierr; 3679b94acceSBarry Smith 3683a40ed3dSBarry Smith PetscFunctionBegin; 3690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 370ca161407SBarry Smith 371186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 3723194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 3737adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 374b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 375d64ed03dSBarry Smith if (flg) { 376186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 3777adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 378186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 379d64ed03dSBarry Smith } 38090d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 381909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 38293c39befSBarry Smith 38357034d6fSHong Zhang ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr); 38457034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 385186905e3SBarry Smith 38657034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 387b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 388b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 38950ffb88aSMatthew Knepley ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 390ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 391acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 39285385478SLisandro Dalcin 393a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 394a8054027SBarry Smith if (flg) { 395a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 396a8054027SBarry Smith } 397e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 398e35cf81dSBarry Smith if (flg) { 399e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 400e35cf81dSBarry Smith } 401efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 402efd51863SBarry Smith if (flg) { 403efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 404efd51863SBarry Smith } 405a8054027SBarry Smith 40685385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 40785385478SLisandro Dalcin if (flg) { 40885385478SLisandro Dalcin switch (indx) { 4097f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 4107f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 41185385478SLisandro Dalcin } 41285385478SLisandro Dalcin } 41385385478SLisandro Dalcin 414acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 415186905e3SBarry Smith 41685385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 41785385478SLisandro Dalcin 418acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 419186905e3SBarry Smith 420fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 421fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 422fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 423fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 424fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 425fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 426fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 427186905e3SBarry Smith 42890d69ab7SBarry Smith flg = PETSC_FALSE; 429acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 430a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 431eabae89aSBarry Smith 432a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 433e8105e01SRichard Katz if (flg) { 434649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 435649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 436e8105e01SRichard Katz } 437eabae89aSBarry Smith 438b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 439b271bb04SBarry Smith if (flg) { 440b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 441b271bb04SBarry Smith } 442b271bb04SBarry Smith 443a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 444eabae89aSBarry Smith if (flg) { 445649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 446f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 447e8105e01SRichard Katz } 448eabae89aSBarry Smith 449a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 450eabae89aSBarry Smith if (flg) { 451649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 452649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 453eabae89aSBarry Smith } 454eabae89aSBarry Smith 4555180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 4565180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 4575180491cSLisandro Dalcin 45890d69ab7SBarry Smith flg = PETSC_FALSE; 459acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 460a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 46190d69ab7SBarry Smith flg = PETSC_FALSE; 462acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 463a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 46490d69ab7SBarry Smith flg = PETSC_FALSE; 465acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 466a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 46790d69ab7SBarry Smith flg = PETSC_FALSE; 468acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 469a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 47090d69ab7SBarry Smith flg = PETSC_FALSE; 471acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 472b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 473e24b481bSBarry Smith 47490d69ab7SBarry Smith flg = PETSC_FALSE; 475acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 4764b27c08aSLois Curfman McInnes if (flg) { 477186905e3SBarry Smith ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);CHKERRQ(ierr); 478ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 4799b94acceSBarry Smith } 480639f9d9dSBarry Smith 481aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 482aa3661deSLisandro Dalcin flg = PETSC_FALSE; 483acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 484a8248277SBarry Smith if (flg && mf_operator) { 485a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 486a8248277SBarry Smith mf = PETSC_TRUE; 487a8248277SBarry Smith } 488aa3661deSLisandro Dalcin flg = PETSC_FALSE; 489acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 490aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 491aa3661deSLisandro Dalcin mf_version = 1; 492aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 493aa3661deSLisandro Dalcin 494d28543b3SPeter Brune 49589b92e6fSPeter Brune /* GS Options */ 49689b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 49789b92e6fSPeter Brune 498ea630c6eSPeter Brune /* line search options */ 499ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_alpha","Constant function norm must decrease by","None",snes->ls_alpha,&snes->ls_alpha,0);CHKERRQ(ierr); 500ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_maxstep","Step must be less than","None",snes->maxstep,&snes->maxstep,0);CHKERRQ(ierr); 501ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_steptol","Minimum lambda allowed","None",snes->steptol,&snes->steptol,0);CHKERRQ(ierr); 502ea630c6eSPeter Brune ierr = PetscOptionsReal("-snes_ls_damping","Damping parameter","SNES",snes->damping,&snes->damping,&flg);CHKERRQ(ierr); 503af60355fSPeter Brune ierr = PetscOptionsInt("-snes_ls_it" ,"Line search iterations","SNES",snes->ls_its,&snes->ls_its,&flg);CHKERRQ(ierr); 504ea630c6eSPeter Brune ierr = PetscOptionsBool("-snes_ls_monitor","Print progress of line searches","SNESLineSearchSetMonitor",snes->ls_monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr); 505ea630c6eSPeter Brune if (set) {ierr = SNESLineSearchSetMonitor(snes,flg);CHKERRQ(ierr);} 50615f5eeeaSPeter Brune ierr = PetscOptionsEnum("-snes_ls","Line search used","SNESLineSearchSet",SNESLineSearchTypes,(PetscEnum)snes->ls_type,(PetscEnum*)&indx,&flg);CHKERRQ(ierr); 50715f5eeeaSPeter Brune if (flg) { 508ea630c6eSPeter Brune ierr = SNESLineSearchSetType(snes,(SNESLineSearchType)indx);CHKERRQ(ierr); 50915f5eeeaSPeter Brune } 5108e3fc8c0SJed Brown flg = snes->ops->precheckstep == SNESLineSearchPreCheckPicard ? PETSC_TRUE : PETSC_FALSE; 5118e3fc8c0SJed Brown ierr = PetscOptionsBool("-snes_ls_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr); 5128e3fc8c0SJed Brown if (set) { 5138e3fc8c0SJed Brown if (flg) { 5148e3fc8c0SJed Brown snes->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */ 5158e3fc8c0SJed Brown ierr = PetscOptionsReal("-snes_ls_precheck_picard_angle","Maximum angle at which to activate the correction","none",snes->precheck_picard_angle,&snes->precheck_picard_angle,PETSC_NULL);CHKERRQ(ierr); 5168e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,SNESLineSearchPreCheckPicard,&snes->precheck_picard_angle);CHKERRQ(ierr); 5178e3fc8c0SJed Brown } else { 5188e3fc8c0SJed Brown ierr = SNESLineSearchSetPreCheck(snes,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 5198e3fc8c0SJed Brown } 5208e3fc8c0SJed Brown } 5218e3fc8c0SJed Brown 52276b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 52376b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 52476b2cf59SMatthew Knepley } 52576b2cf59SMatthew Knepley 526e7788613SBarry Smith if (snes->ops->setfromoptions) { 527e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 528639f9d9dSBarry Smith } 5295d973c19SBarry Smith 5305d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 5315d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 532b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 5334bbc92c1SBarry Smith 534aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 5351cee3971SBarry Smith 5361cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 537aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 538aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 53985385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 54093993e2dSLois Curfman McInnes 54151e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 54251e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 54351e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 54451e86f29SPeter Brune if (pcset && (!snes->pc)) { 54551e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 54651e86f29SPeter Brune } 5474a0c5b0cSMatthew G Knepley if (snes->pc) { 548fde0ff24SPeter Brune ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr); 549fde0ff24SPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr); 5504a0c5b0cSMatthew G Knepley ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 551646217ecSPeter Brune ierr = SNESSetGS(snes->pc, snes->ops->computegs, snes->gsP);CHKERRQ(ierr); 5524a0c5b0cSMatthew G Knepley /* Should we make a duplicate vector and matrix? Leave the DM to make it? */ 5534a0c5b0cSMatthew G Knepley ierr = SNESSetFunction(snes->pc, snes->vec_func, snes->ops->computefunction, snes->funP);CHKERRQ(ierr); 5544a0c5b0cSMatthew G Knepley ierr = SNESSetJacobian(snes->pc, snes->jacobian, snes->jacobian_pre, snes->ops->computejacobian, snes->jacP);CHKERRQ(ierr); 5554a0c5b0cSMatthew G Knepley ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 5564a0c5b0cSMatthew G Knepley } 5573a40ed3dSBarry Smith PetscFunctionReturn(0); 5589b94acceSBarry Smith } 5599b94acceSBarry Smith 560d25893d9SBarry Smith #undef __FUNCT__ 561d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 562d25893d9SBarry Smith /*@ 563d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 564d25893d9SBarry Smith the nonlinear solvers. 565d25893d9SBarry Smith 566d25893d9SBarry Smith Logically Collective on SNES 567d25893d9SBarry Smith 568d25893d9SBarry Smith Input Parameters: 569d25893d9SBarry Smith + snes - the SNES context 570d25893d9SBarry Smith . compute - function to compute the context 571d25893d9SBarry Smith - destroy - function to destroy the context 572d25893d9SBarry Smith 573d25893d9SBarry Smith Level: intermediate 574d25893d9SBarry Smith 575d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 576d25893d9SBarry Smith 577d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 578d25893d9SBarry Smith @*/ 579d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 580d25893d9SBarry Smith { 581d25893d9SBarry Smith PetscFunctionBegin; 582d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 583d25893d9SBarry Smith snes->ops->usercompute = compute; 584d25893d9SBarry Smith snes->ops->userdestroy = destroy; 585d25893d9SBarry Smith PetscFunctionReturn(0); 586d25893d9SBarry Smith } 587a847f771SSatish Balay 5884a2ae208SSatish Balay #undef __FUNCT__ 5894a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 590b07ff414SBarry Smith /*@ 5919b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 5929b94acceSBarry Smith the nonlinear solvers. 5939b94acceSBarry Smith 5943f9fe445SBarry Smith Logically Collective on SNES 595fee21e36SBarry Smith 596c7afd0dbSLois Curfman McInnes Input Parameters: 597c7afd0dbSLois Curfman McInnes + snes - the SNES context 598c7afd0dbSLois Curfman McInnes - usrP - optional user context 599c7afd0dbSLois Curfman McInnes 60036851e7fSLois Curfman McInnes Level: intermediate 60136851e7fSLois Curfman McInnes 6029b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 6039b94acceSBarry Smith 604d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext() 6059b94acceSBarry Smith @*/ 6067087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 6079b94acceSBarry Smith { 6081b2093e4SBarry Smith PetscErrorCode ierr; 609b07ff414SBarry Smith KSP ksp; 6101b2093e4SBarry Smith 6113a40ed3dSBarry Smith PetscFunctionBegin; 6120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 613b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 614b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 6159b94acceSBarry Smith snes->user = usrP; 6163a40ed3dSBarry Smith PetscFunctionReturn(0); 6179b94acceSBarry Smith } 61874679c65SBarry Smith 6194a2ae208SSatish Balay #undef __FUNCT__ 6204a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 621b07ff414SBarry Smith /*@ 6229b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 6239b94acceSBarry Smith nonlinear solvers. 6249b94acceSBarry Smith 625c7afd0dbSLois Curfman McInnes Not Collective 626c7afd0dbSLois Curfman McInnes 6279b94acceSBarry Smith Input Parameter: 6289b94acceSBarry Smith . snes - SNES context 6299b94acceSBarry Smith 6309b94acceSBarry Smith Output Parameter: 6319b94acceSBarry Smith . usrP - user context 6329b94acceSBarry Smith 63336851e7fSLois Curfman McInnes Level: intermediate 63436851e7fSLois Curfman McInnes 6359b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 6369b94acceSBarry Smith 6379b94acceSBarry Smith .seealso: SNESSetApplicationContext() 6389b94acceSBarry Smith @*/ 639e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 6409b94acceSBarry Smith { 6413a40ed3dSBarry Smith PetscFunctionBegin; 6420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 643e71120c6SJed Brown *(void**)usrP = snes->user; 6443a40ed3dSBarry Smith PetscFunctionReturn(0); 6459b94acceSBarry Smith } 64674679c65SBarry Smith 6474a2ae208SSatish Balay #undef __FUNCT__ 6484a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 6499b94acceSBarry Smith /*@ 650c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 651c8228a4eSBarry Smith at this time. 6529b94acceSBarry Smith 653c7afd0dbSLois Curfman McInnes Not Collective 654c7afd0dbSLois Curfman McInnes 6559b94acceSBarry Smith Input Parameter: 6569b94acceSBarry Smith . snes - SNES context 6579b94acceSBarry Smith 6589b94acceSBarry Smith Output Parameter: 6599b94acceSBarry Smith . iter - iteration number 6609b94acceSBarry Smith 661c8228a4eSBarry Smith Notes: 662c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 663c8228a4eSBarry Smith 664c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 66508405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 66608405cd6SLois Curfman McInnes .vb 66708405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 66808405cd6SLois Curfman McInnes if (!(it % 2)) { 66908405cd6SLois Curfman McInnes [compute Jacobian here] 67008405cd6SLois Curfman McInnes } 67108405cd6SLois Curfman McInnes .ve 672c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 67308405cd6SLois Curfman McInnes recomputed every second SNES iteration. 674c8228a4eSBarry Smith 67536851e7fSLois Curfman McInnes Level: intermediate 67636851e7fSLois Curfman McInnes 6772b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 6782b668275SBarry Smith 679b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 6809b94acceSBarry Smith @*/ 6817087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 6829b94acceSBarry Smith { 6833a40ed3dSBarry Smith PetscFunctionBegin; 6840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 6854482741eSBarry Smith PetscValidIntPointer(iter,2); 6869b94acceSBarry Smith *iter = snes->iter; 6873a40ed3dSBarry Smith PetscFunctionReturn(0); 6889b94acceSBarry Smith } 68974679c65SBarry Smith 6904a2ae208SSatish Balay #undef __FUNCT__ 6914a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 6929b94acceSBarry Smith /*@ 6939b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 6949b94acceSBarry Smith with SNESSSetFunction(). 6959b94acceSBarry Smith 696c7afd0dbSLois Curfman McInnes Collective on SNES 697c7afd0dbSLois Curfman McInnes 6989b94acceSBarry Smith Input Parameter: 6999b94acceSBarry Smith . snes - SNES context 7009b94acceSBarry Smith 7019b94acceSBarry Smith Output Parameter: 7029b94acceSBarry Smith . fnorm - 2-norm of function 7039b94acceSBarry Smith 70436851e7fSLois Curfman McInnes Level: intermediate 70536851e7fSLois Curfman McInnes 7069b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 707a86d99e1SLois Curfman McInnes 708b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 7099b94acceSBarry Smith @*/ 7107087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 7119b94acceSBarry Smith { 7123a40ed3dSBarry Smith PetscFunctionBegin; 7130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7144482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 7159b94acceSBarry Smith *fnorm = snes->norm; 7163a40ed3dSBarry Smith PetscFunctionReturn(0); 7179b94acceSBarry Smith } 71874679c65SBarry Smith 7194a2ae208SSatish Balay #undef __FUNCT__ 720b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 7219b94acceSBarry Smith /*@ 722b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 7239b94acceSBarry Smith attempted by the nonlinear solver. 7249b94acceSBarry Smith 725c7afd0dbSLois Curfman McInnes Not Collective 726c7afd0dbSLois Curfman McInnes 7279b94acceSBarry Smith Input Parameter: 7289b94acceSBarry Smith . snes - SNES context 7299b94acceSBarry Smith 7309b94acceSBarry Smith Output Parameter: 7319b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 7329b94acceSBarry Smith 733c96a6f78SLois Curfman McInnes Notes: 734c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 735c96a6f78SLois Curfman McInnes 73636851e7fSLois Curfman McInnes Level: intermediate 73736851e7fSLois Curfman McInnes 7389b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 73958ebbce7SBarry Smith 740e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 74158ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 7429b94acceSBarry Smith @*/ 7437087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 7449b94acceSBarry Smith { 7453a40ed3dSBarry Smith PetscFunctionBegin; 7460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 7474482741eSBarry Smith PetscValidIntPointer(nfails,2); 74850ffb88aSMatthew Knepley *nfails = snes->numFailures; 74950ffb88aSMatthew Knepley PetscFunctionReturn(0); 75050ffb88aSMatthew Knepley } 75150ffb88aSMatthew Knepley 75250ffb88aSMatthew Knepley #undef __FUNCT__ 753b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 75450ffb88aSMatthew Knepley /*@ 755b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 75650ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 75750ffb88aSMatthew Knepley 75850ffb88aSMatthew Knepley Not Collective 75950ffb88aSMatthew Knepley 76050ffb88aSMatthew Knepley Input Parameters: 76150ffb88aSMatthew Knepley + snes - SNES context 76250ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 76350ffb88aSMatthew Knepley 76450ffb88aSMatthew Knepley Level: intermediate 76550ffb88aSMatthew Knepley 76650ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 76758ebbce7SBarry Smith 768e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 76958ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 77050ffb88aSMatthew Knepley @*/ 7717087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 77250ffb88aSMatthew Knepley { 77350ffb88aSMatthew Knepley PetscFunctionBegin; 7740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 77550ffb88aSMatthew Knepley snes->maxFailures = maxFails; 77650ffb88aSMatthew Knepley PetscFunctionReturn(0); 77750ffb88aSMatthew Knepley } 77850ffb88aSMatthew Knepley 77950ffb88aSMatthew Knepley #undef __FUNCT__ 780b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 78150ffb88aSMatthew Knepley /*@ 782b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 78350ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 78450ffb88aSMatthew Knepley 78550ffb88aSMatthew Knepley Not Collective 78650ffb88aSMatthew Knepley 78750ffb88aSMatthew Knepley Input Parameter: 78850ffb88aSMatthew Knepley . snes - SNES context 78950ffb88aSMatthew Knepley 79050ffb88aSMatthew Knepley Output Parameter: 79150ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 79250ffb88aSMatthew Knepley 79350ffb88aSMatthew Knepley Level: intermediate 79450ffb88aSMatthew Knepley 79550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 79658ebbce7SBarry Smith 797e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 79858ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 79958ebbce7SBarry Smith 80050ffb88aSMatthew Knepley @*/ 8017087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 80250ffb88aSMatthew Knepley { 80350ffb88aSMatthew Knepley PetscFunctionBegin; 8040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8054482741eSBarry Smith PetscValidIntPointer(maxFails,2); 80650ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 8073a40ed3dSBarry Smith PetscFunctionReturn(0); 8089b94acceSBarry Smith } 809a847f771SSatish Balay 8104a2ae208SSatish Balay #undef __FUNCT__ 8112541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 8122541af92SBarry Smith /*@ 8132541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 8142541af92SBarry Smith done by SNES. 8152541af92SBarry Smith 8162541af92SBarry Smith Not Collective 8172541af92SBarry Smith 8182541af92SBarry Smith Input Parameter: 8192541af92SBarry Smith . snes - SNES context 8202541af92SBarry Smith 8212541af92SBarry Smith Output Parameter: 8222541af92SBarry Smith . nfuncs - number of evaluations 8232541af92SBarry Smith 8242541af92SBarry Smith Level: intermediate 8252541af92SBarry Smith 8262541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 82758ebbce7SBarry Smith 828e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 8292541af92SBarry Smith @*/ 8307087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 8312541af92SBarry Smith { 8322541af92SBarry Smith PetscFunctionBegin; 8330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8342541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 8352541af92SBarry Smith *nfuncs = snes->nfuncs; 8362541af92SBarry Smith PetscFunctionReturn(0); 8372541af92SBarry Smith } 8382541af92SBarry Smith 8392541af92SBarry Smith #undef __FUNCT__ 8403d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 8413d4c4710SBarry Smith /*@ 8423d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 8433d4c4710SBarry Smith linear solvers. 8443d4c4710SBarry Smith 8453d4c4710SBarry Smith Not Collective 8463d4c4710SBarry Smith 8473d4c4710SBarry Smith Input Parameter: 8483d4c4710SBarry Smith . snes - SNES context 8493d4c4710SBarry Smith 8503d4c4710SBarry Smith Output Parameter: 8513d4c4710SBarry Smith . nfails - number of failed solves 8523d4c4710SBarry Smith 8533d4c4710SBarry Smith Notes: 8543d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 8553d4c4710SBarry Smith 8563d4c4710SBarry Smith Level: intermediate 8573d4c4710SBarry Smith 8583d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 85958ebbce7SBarry Smith 860e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 8613d4c4710SBarry Smith @*/ 8627087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 8633d4c4710SBarry Smith { 8643d4c4710SBarry Smith PetscFunctionBegin; 8650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8663d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 8673d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 8683d4c4710SBarry Smith PetscFunctionReturn(0); 8693d4c4710SBarry Smith } 8703d4c4710SBarry Smith 8713d4c4710SBarry Smith #undef __FUNCT__ 8723d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 8733d4c4710SBarry Smith /*@ 8743d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 8753d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 8763d4c4710SBarry Smith 8773f9fe445SBarry Smith Logically Collective on SNES 8783d4c4710SBarry Smith 8793d4c4710SBarry Smith Input Parameters: 8803d4c4710SBarry Smith + snes - SNES context 8813d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 8823d4c4710SBarry Smith 8833d4c4710SBarry Smith Level: intermediate 8843d4c4710SBarry Smith 885a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 8863d4c4710SBarry Smith 8873d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 8883d4c4710SBarry Smith 88958ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 8903d4c4710SBarry Smith @*/ 8917087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 8923d4c4710SBarry Smith { 8933d4c4710SBarry Smith PetscFunctionBegin; 8940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 895c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 8963d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 8973d4c4710SBarry Smith PetscFunctionReturn(0); 8983d4c4710SBarry Smith } 8993d4c4710SBarry Smith 9003d4c4710SBarry Smith #undef __FUNCT__ 9013d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 9023d4c4710SBarry Smith /*@ 9033d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 9043d4c4710SBarry Smith are allowed before SNES terminates 9053d4c4710SBarry Smith 9063d4c4710SBarry Smith Not Collective 9073d4c4710SBarry Smith 9083d4c4710SBarry Smith Input Parameter: 9093d4c4710SBarry Smith . snes - SNES context 9103d4c4710SBarry Smith 9113d4c4710SBarry Smith Output Parameter: 9123d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 9133d4c4710SBarry Smith 9143d4c4710SBarry Smith Level: intermediate 9153d4c4710SBarry Smith 9163d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 9173d4c4710SBarry Smith 9183d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 9193d4c4710SBarry Smith 920e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 9213d4c4710SBarry Smith @*/ 9227087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 9233d4c4710SBarry Smith { 9243d4c4710SBarry Smith PetscFunctionBegin; 9250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9263d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 9273d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 9283d4c4710SBarry Smith PetscFunctionReturn(0); 9293d4c4710SBarry Smith } 9303d4c4710SBarry Smith 9313d4c4710SBarry Smith #undef __FUNCT__ 932b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 933c96a6f78SLois Curfman McInnes /*@ 934b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 935c96a6f78SLois Curfman McInnes used by the nonlinear solver. 936c96a6f78SLois Curfman McInnes 937c7afd0dbSLois Curfman McInnes Not Collective 938c7afd0dbSLois Curfman McInnes 939c96a6f78SLois Curfman McInnes Input Parameter: 940c96a6f78SLois Curfman McInnes . snes - SNES context 941c96a6f78SLois Curfman McInnes 942c96a6f78SLois Curfman McInnes Output Parameter: 943c96a6f78SLois Curfman McInnes . lits - number of linear iterations 944c96a6f78SLois Curfman McInnes 945c96a6f78SLois Curfman McInnes Notes: 946c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 947c96a6f78SLois Curfman McInnes 94836851e7fSLois Curfman McInnes Level: intermediate 94936851e7fSLois Curfman McInnes 950c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 9512b668275SBarry Smith 9528c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 953c96a6f78SLois Curfman McInnes @*/ 9547087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 955c96a6f78SLois Curfman McInnes { 9563a40ed3dSBarry Smith PetscFunctionBegin; 9570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9584482741eSBarry Smith PetscValidIntPointer(lits,2); 959c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 9603a40ed3dSBarry Smith PetscFunctionReturn(0); 961c96a6f78SLois Curfman McInnes } 962c96a6f78SLois Curfman McInnes 9634a2ae208SSatish Balay #undef __FUNCT__ 96494b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 96552baeb72SSatish Balay /*@ 96694b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 9679b94acceSBarry Smith 96894b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 969c7afd0dbSLois Curfman McInnes 9709b94acceSBarry Smith Input Parameter: 9719b94acceSBarry Smith . snes - the SNES context 9729b94acceSBarry Smith 9739b94acceSBarry Smith Output Parameter: 97494b7f48cSBarry Smith . ksp - the KSP context 9759b94acceSBarry Smith 9769b94acceSBarry Smith Notes: 97794b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 9789b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 9792999313aSBarry Smith PC contexts as well. 9809b94acceSBarry Smith 98136851e7fSLois Curfman McInnes Level: beginner 98236851e7fSLois Curfman McInnes 98394b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 9849b94acceSBarry Smith 9852999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 9869b94acceSBarry Smith @*/ 9877087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 9889b94acceSBarry Smith { 9891cee3971SBarry Smith PetscErrorCode ierr; 9901cee3971SBarry Smith 9913a40ed3dSBarry Smith PetscFunctionBegin; 9920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9934482741eSBarry Smith PetscValidPointer(ksp,2); 9941cee3971SBarry Smith 9951cee3971SBarry Smith if (!snes->ksp) { 9961cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 9971cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 9981cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 9991cee3971SBarry Smith } 100094b7f48cSBarry Smith *ksp = snes->ksp; 10013a40ed3dSBarry Smith PetscFunctionReturn(0); 10029b94acceSBarry Smith } 100382bf6240SBarry Smith 10044a2ae208SSatish Balay #undef __FUNCT__ 10052999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 10062999313aSBarry Smith /*@ 10072999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 10082999313aSBarry Smith 10092999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 10102999313aSBarry Smith 10112999313aSBarry Smith Input Parameters: 10122999313aSBarry Smith + snes - the SNES context 10132999313aSBarry Smith - ksp - the KSP context 10142999313aSBarry Smith 10152999313aSBarry Smith Notes: 10162999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 10172999313aSBarry Smith so this routine is rarely needed. 10182999313aSBarry Smith 10192999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 10202999313aSBarry Smith decreased by one. 10212999313aSBarry Smith 10222999313aSBarry Smith Level: developer 10232999313aSBarry Smith 10242999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 10252999313aSBarry Smith 10262999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 10272999313aSBarry Smith @*/ 10287087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 10292999313aSBarry Smith { 10302999313aSBarry Smith PetscErrorCode ierr; 10312999313aSBarry Smith 10322999313aSBarry Smith PetscFunctionBegin; 10330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10340700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 10352999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 10367dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1037906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 10382999313aSBarry Smith snes->ksp = ksp; 10392999313aSBarry Smith PetscFunctionReturn(0); 10402999313aSBarry Smith } 10412999313aSBarry Smith 10427adad957SLisandro Dalcin #if 0 10432999313aSBarry Smith #undef __FUNCT__ 10444a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 10456849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1046e24b481bSBarry Smith { 1047e24b481bSBarry Smith PetscFunctionBegin; 1048e24b481bSBarry Smith PetscFunctionReturn(0); 1049e24b481bSBarry Smith } 10507adad957SLisandro Dalcin #endif 1051e24b481bSBarry Smith 10529b94acceSBarry Smith /* -----------------------------------------------------------*/ 10534a2ae208SSatish Balay #undef __FUNCT__ 10544a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 105552baeb72SSatish Balay /*@ 10569b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 10579b94acceSBarry Smith 1058c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1059c7afd0dbSLois Curfman McInnes 1060c7afd0dbSLois Curfman McInnes Input Parameters: 1061906ed7ccSBarry Smith . comm - MPI communicator 10629b94acceSBarry Smith 10639b94acceSBarry Smith Output Parameter: 10649b94acceSBarry Smith . outsnes - the new SNES context 10659b94acceSBarry Smith 1066c7afd0dbSLois Curfman McInnes Options Database Keys: 1067c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1068c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1069c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1070c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1071c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1072c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1073c1f60f51SBarry Smith 107436851e7fSLois Curfman McInnes Level: beginner 107536851e7fSLois Curfman McInnes 10769b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 10779b94acceSBarry Smith 1078a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1079a8054027SBarry Smith 10809b94acceSBarry Smith @*/ 10817087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 10829b94acceSBarry Smith { 1083dfbe8321SBarry Smith PetscErrorCode ierr; 10849b94acceSBarry Smith SNES snes; 1085fa9f3622SBarry Smith SNESKSPEW *kctx; 108637fcc0dbSBarry Smith 10873a40ed3dSBarry Smith PetscFunctionBegin; 1088ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 10898ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 10908ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 10918ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 10928ba1e511SMatthew Knepley #endif 10938ba1e511SMatthew Knepley 10943194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 10957adad957SLisandro Dalcin 109685385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 10972c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 1098d28543b3SPeter Brune snes->usegs = PETSC_FALSE; 10999b94acceSBarry Smith snes->max_its = 50; 11009750a799SBarry Smith snes->max_funcs = 10000; 11019b94acceSBarry Smith snes->norm = 0.0; 1102b4874afaSBarry Smith snes->rtol = 1.e-8; 1103b4874afaSBarry Smith snes->ttol = 0.0; 110470441072SBarry Smith snes->abstol = 1.e-50; 11059b94acceSBarry Smith snes->xtol = 1.e-8; 11064b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 11079b94acceSBarry Smith snes->nfuncs = 0; 110850ffb88aSMatthew Knepley snes->numFailures = 0; 110950ffb88aSMatthew Knepley snes->maxFailures = 1; 11107a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1111e35cf81dSBarry Smith snes->lagjacobian = 1; 1112a8054027SBarry Smith snes->lagpreconditioner = 1; 1113639f9d9dSBarry Smith snes->numbermonitors = 0; 11149b94acceSBarry Smith snes->data = 0; 11154dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1116186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 11176f24a144SLois Curfman McInnes snes->nwork = 0; 111858c9b817SLisandro Dalcin snes->work = 0; 111958c9b817SLisandro Dalcin snes->nvwork = 0; 112058c9b817SLisandro Dalcin snes->vwork = 0; 1121758f92a0SBarry Smith snes->conv_hist_len = 0; 1122758f92a0SBarry Smith snes->conv_hist_max = 0; 1123758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1124758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1125758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1126184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 112789b92e6fSPeter Brune snes->gssweeps = 1; 11289b94acceSBarry Smith 1129ea630c6eSPeter Brune /* initialize the line search options */ 1130ea630c6eSPeter Brune snes->ls_type = SNES_LS_BASIC; 1131af60355fSPeter Brune snes->ls_its = 1; 1132ea630c6eSPeter Brune snes->damping = 1.0; 1133ea630c6eSPeter Brune snes->maxstep = 1e8; 1134ea630c6eSPeter Brune snes->steptol = 1e-12; 1135ea630c6eSPeter Brune snes->ls_alpha = 1e-4; 1136ea630c6eSPeter Brune snes->ls_monitor = PETSC_NULL; 1137ea630c6eSPeter Brune 1138ea630c6eSPeter Brune snes->ops->linesearch = PETSC_NULL; 1139ea630c6eSPeter Brune snes->precheck = PETSC_NULL; 1140ea630c6eSPeter Brune snes->ops->precheckstep = PETSC_NULL; 1141ea630c6eSPeter Brune snes->postcheck = PETSC_NULL; 1142ea630c6eSPeter Brune snes->ops->postcheckstep= PETSC_NULL; 1143ea630c6eSPeter Brune 11443d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 11453d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 11463d4c4710SBarry Smith 11479b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 114838f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 11499b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 11509b94acceSBarry Smith kctx->version = 2; 11519b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 11529b94acceSBarry Smith this was too large for some test cases */ 115375567043SBarry Smith kctx->rtol_last = 0.0; 11549b94acceSBarry Smith kctx->rtol_max = .9; 11559b94acceSBarry Smith kctx->gamma = 1.0; 115662d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 115771f87433Sdalcinl kctx->alpha2 = kctx->alpha; 11589b94acceSBarry Smith kctx->threshold = .1; 115975567043SBarry Smith kctx->lresid_last = 0.0; 116075567043SBarry Smith kctx->norm_last = 0.0; 11619b94acceSBarry Smith 11629b94acceSBarry Smith *outsnes = snes; 11633a40ed3dSBarry Smith PetscFunctionReturn(0); 11649b94acceSBarry Smith } 11659b94acceSBarry Smith 11664a2ae208SSatish Balay #undef __FUNCT__ 11674a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 11689b94acceSBarry Smith /*@C 11699b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 11709b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 11719b94acceSBarry Smith equations. 11729b94acceSBarry Smith 11733f9fe445SBarry Smith Logically Collective on SNES 1174fee21e36SBarry Smith 1175c7afd0dbSLois Curfman McInnes Input Parameters: 1176c7afd0dbSLois Curfman McInnes + snes - the SNES context 1177c7afd0dbSLois Curfman McInnes . r - vector to store function value 1178de044059SHong Zhang . func - function evaluation routine 1179c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1180c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 11819b94acceSBarry Smith 1182c7afd0dbSLois Curfman McInnes Calling sequence of func: 11838d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1184c7afd0dbSLois Curfman McInnes 1185313e4042SLois Curfman McInnes . f - function vector 1186c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 11879b94acceSBarry Smith 11889b94acceSBarry Smith Notes: 11899b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 11909b94acceSBarry Smith $ f'(x) x = -f(x), 1191c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 11929b94acceSBarry Smith 119336851e7fSLois Curfman McInnes Level: beginner 119436851e7fSLois Curfman McInnes 11959b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 11969b94acceSBarry Smith 11978b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 11989b94acceSBarry Smith @*/ 11997087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 12009b94acceSBarry Smith { 120185385478SLisandro Dalcin PetscErrorCode ierr; 12023a40ed3dSBarry Smith PetscFunctionBegin; 12030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1204d2a683ecSLisandro Dalcin if (r) { 1205d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1206d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 120785385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 12086bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 120985385478SLisandro Dalcin snes->vec_func = r; 1210d2a683ecSLisandro Dalcin } else if (!snes->vec_func && snes->dm) { 1211d2a683ecSLisandro Dalcin ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 1212d2a683ecSLisandro Dalcin } 1213d2a683ecSLisandro Dalcin if (func) snes->ops->computefunction = func; 1214d2a683ecSLisandro Dalcin if (ctx) snes->funP = ctx; 12153a40ed3dSBarry Smith PetscFunctionReturn(0); 12169b94acceSBarry Smith } 12179b94acceSBarry Smith 1218646217ecSPeter Brune 1219646217ecSPeter Brune #undef __FUNCT__ 1220646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1221c79ef259SPeter Brune /*@C 1222c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1223c79ef259SPeter Brune use with composed nonlinear solvers. 1224c79ef259SPeter Brune 1225c79ef259SPeter Brune Input Parameters: 1226c79ef259SPeter Brune + snes - the SNES context 1227c79ef259SPeter Brune . gsfunc - function evaluation routine 1228c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1229c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1230c79ef259SPeter Brune 1231c79ef259SPeter Brune Calling sequence of func: 1232c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1233c79ef259SPeter Brune 1234c79ef259SPeter Brune + X - solution vector 1235c79ef259SPeter Brune . B - RHS vector 1236d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1237c79ef259SPeter Brune 1238c79ef259SPeter Brune Notes: 1239c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1240c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1241c79ef259SPeter Brune 1242d28543b3SPeter Brune Level: intermediate 1243c79ef259SPeter Brune 1244d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1245c79ef259SPeter Brune 1246c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1247c79ef259SPeter Brune @*/ 1248646217ecSPeter Brune PetscErrorCode SNESSetGS(SNES snes, PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void *), void * ctx) { 1249646217ecSPeter Brune PetscFunctionBegin; 1250646217ecSPeter Brune if (gsfunc) snes->ops->computegs = gsfunc; 1251646217ecSPeter Brune if (ctx) snes->gsP = ctx; 1252646217ecSPeter Brune PetscFunctionReturn(0); 1253646217ecSPeter Brune } 1254646217ecSPeter Brune 1255d25893d9SBarry Smith #undef __FUNCT__ 1256d28543b3SPeter Brune #define __FUNCT__ "SNESSetUseGS" 1257d28543b3SPeter Brune /*@ 1258d28543b3SPeter Brune SNESSetUseGS - Toggles use of the user-set nonlinear GS solver in 1259d28543b3SPeter Brune SNES solvers that may use a preconditioning routine. 1260d28543b3SPeter Brune 1261d28543b3SPeter Brune Input Parameters: 1262d28543b3SPeter Brune + snes - the SNES context 1263d28543b3SPeter Brune - usegs - whether to use the nonlinear GS routine or not. 1264d28543b3SPeter Brune 1265d28543b3SPeter Brune Notes: 1266d28543b3SPeter Brune The behavior of the nonlinear GS solvers is that if useGS is set, then 1267d28543b3SPeter Brune the update is constructed with the user-defined nonlinear GS method. 1268d28543b3SPeter Brune Otherwise, the update is either formed by the user-customized 1269d28543b3SPeter Brune preconditioner SNES, or by nonlinear richardson if both of these 1270d28543b3SPeter Brune are not provided. 1271d28543b3SPeter Brune 1272d28543b3SPeter Brune Level: intermediate 1273d28543b3SPeter Brune 1274d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 1275d28543b3SPeter Brune 1276d28543b3SPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetUseGS() 1277d28543b3SPeter Brune @*/ 1278d28543b3SPeter Brune PetscErrorCode SNESSetUseGS(SNES snes, PetscBool usegs) { 1279d28543b3SPeter Brune PetscFunctionBegin; 1280d28543b3SPeter Brune snes->usegs = usegs; 1281d28543b3SPeter Brune PetscFunctionReturn(0); 1282d28543b3SPeter Brune } 1283d28543b3SPeter Brune 1284d28543b3SPeter Brune 1285d28543b3SPeter Brune #undef __FUNCT__ 1286d28543b3SPeter Brune #define __FUNCT__ "SNESGetUseGS" 1287d28543b3SPeter Brune /*@ 1288d28543b3SPeter Brune SNESGetUseGS - Returns whether or not the SNES is using a 1289d28543b3SPeter Brune provided nonlinear GS routine. 1290d28543b3SPeter Brune 1291d28543b3SPeter Brune Input Parameters: 1292d28543b3SPeter Brune + snes - the SNES context 1293d28543b3SPeter Brune - usegs - flag indicating whether or not GS is being used 1294d28543b3SPeter Brune 1295d28543b3SPeter Brune Level: intermediate 1296d28543b3SPeter Brune 1297d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1298d28543b3SPeter Brune 1299d28543b3SPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetUseGS() 1300d28543b3SPeter Brune @*/ 1301d28543b3SPeter Brune 1302d28543b3SPeter Brune PetscErrorCode SNESGetUseGS(SNES snes, PetscBool * usegs) { 1303d28543b3SPeter Brune PetscFunctionBegin; 1304d28543b3SPeter Brune 1305d28543b3SPeter Brune *usegs = snes->usegs; 1306d28543b3SPeter Brune PetscFunctionReturn(0); 1307d28543b3SPeter Brune } 1308d28543b3SPeter Brune 1309d28543b3SPeter Brune #undef __FUNCT__ 131089b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 131189b92e6fSPeter Brune /*@ 131289b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 131389b92e6fSPeter Brune 131489b92e6fSPeter Brune Input Parameters: 131589b92e6fSPeter Brune + snes - the SNES context 131689b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 131789b92e6fSPeter Brune 131889b92e6fSPeter Brune Level: intermediate 131989b92e6fSPeter Brune 132089b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 132189b92e6fSPeter Brune 132289b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 132389b92e6fSPeter Brune @*/ 132489b92e6fSPeter Brune 132589b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 132689b92e6fSPeter Brune PetscFunctionBegin; 132789b92e6fSPeter Brune snes->gssweeps = sweeps; 132889b92e6fSPeter Brune PetscFunctionReturn(0); 132989b92e6fSPeter Brune } 133089b92e6fSPeter Brune 133189b92e6fSPeter Brune 133289b92e6fSPeter Brune #undef __FUNCT__ 133389b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 133489b92e6fSPeter Brune /*@ 133589b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 133689b92e6fSPeter Brune 133789b92e6fSPeter Brune Input Parameters: 133889b92e6fSPeter Brune . snes - the SNES context 133989b92e6fSPeter Brune 134089b92e6fSPeter Brune Output Parameters: 134189b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 134289b92e6fSPeter Brune 134389b92e6fSPeter Brune Level: intermediate 134489b92e6fSPeter Brune 134589b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 134689b92e6fSPeter Brune 134789b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 134889b92e6fSPeter Brune @*/ 134989b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 135089b92e6fSPeter Brune PetscFunctionBegin; 135189b92e6fSPeter Brune *sweeps = snes->gssweeps; 135289b92e6fSPeter Brune PetscFunctionReturn(0); 135389b92e6fSPeter Brune } 135489b92e6fSPeter Brune 135589b92e6fSPeter Brune #undef __FUNCT__ 13568b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 13578b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 13588b0a5094SBarry Smith { 13598b0a5094SBarry Smith PetscErrorCode ierr; 13608b0a5094SBarry Smith PetscFunctionBegin; 13618b0a5094SBarry Smith /* A(x)*x - b(x) */ 13628b0a5094SBarry Smith ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,snes->jacP);CHKERRQ(ierr); 13638b0a5094SBarry Smith ierr = (*snes->ops->computepfunction)(snes,x,f,snes->funP);CHKERRQ(ierr); 13648b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 13658b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 13668b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 13678b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 13688b0a5094SBarry Smith PetscFunctionReturn(0); 13698b0a5094SBarry Smith } 13708b0a5094SBarry Smith 13718b0a5094SBarry Smith #undef __FUNCT__ 13728b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 13738b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 13748b0a5094SBarry Smith { 13758b0a5094SBarry Smith PetscFunctionBegin; 13768b0a5094SBarry Smith *flag = snes->matstruct; 13778b0a5094SBarry Smith PetscFunctionReturn(0); 13788b0a5094SBarry Smith } 13798b0a5094SBarry Smith 13808b0a5094SBarry Smith #undef __FUNCT__ 13818b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 13828b0a5094SBarry Smith /*@C 13830d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 13848b0a5094SBarry Smith 13858b0a5094SBarry Smith Logically Collective on SNES 13868b0a5094SBarry Smith 13878b0a5094SBarry Smith Input Parameters: 13888b0a5094SBarry Smith + snes - the SNES context 13898b0a5094SBarry Smith . r - vector to store function value 13908b0a5094SBarry Smith . func - function evaluation routine 13918b0a5094SBarry Smith . jmat - normally the same as mat but you can pass another matrix for which you compute the Jacobian of A(x) x - b(x) (see jmat below) 13928b0a5094SBarry Smith . mat - matrix to store A 13938b0a5094SBarry Smith . mfunc - function to compute matrix value 13948b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 13958b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 13968b0a5094SBarry Smith 13978b0a5094SBarry Smith Calling sequence of func: 13988b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 13998b0a5094SBarry Smith 14008b0a5094SBarry Smith + f - function vector 14018b0a5094SBarry Smith - ctx - optional user-defined function context 14028b0a5094SBarry Smith 14038b0a5094SBarry Smith Calling sequence of mfunc: 14048b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 14058b0a5094SBarry Smith 14068b0a5094SBarry Smith + x - input vector 14078b0a5094SBarry Smith . jmat - Form Jacobian matrix of A(x) x - b(x) if available, not there is really no reason to use it in this way since then you can just use SNESSetJacobian(), 14088b0a5094SBarry Smith normally just pass mat in this location 14098b0a5094SBarry Smith . mat - form A(x) matrix 14108b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 14118b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 14128b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 14138b0a5094SBarry Smith 14148b0a5094SBarry Smith Notes: 14158b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 14168b0a5094SBarry Smith 14178b0a5094SBarry Smith $ Solves the equation A(x) x = b(x) via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = b(x^{n}) - A(x^{n})x^{n} 14188b0a5094SBarry Smith $ Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration. 14198b0a5094SBarry Smith 14208b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 14218b0a5094SBarry Smith 14220d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 14230d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 14248b0a5094SBarry Smith 14258b0a5094SBarry Smith There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some 14268b0a5094SBarry Smith believe it is the iteration A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative reference that defines the Picard iteration 14278b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 14288b0a5094SBarry Smith 14298b0a5094SBarry Smith Level: beginner 14308b0a5094SBarry Smith 14318b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 14328b0a5094SBarry Smith 14330d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 14348b0a5094SBarry Smith @*/ 14358b0a5094SBarry Smith PetscErrorCode SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),Mat jmat, Mat mat, PetscErrorCode (*mfunc)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 14368b0a5094SBarry Smith { 14378b0a5094SBarry Smith PetscErrorCode ierr; 14388b0a5094SBarry Smith PetscFunctionBegin; 14398b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14408b0a5094SBarry Smith snes->ops->computepfunction = func; 14418b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 14428b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 14438b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 14448b0a5094SBarry Smith PetscFunctionReturn(0); 14458b0a5094SBarry Smith } 14468b0a5094SBarry Smith 14478b0a5094SBarry Smith #undef __FUNCT__ 1448d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1449d25893d9SBarry Smith /*@C 1450d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1451d25893d9SBarry Smith 1452d25893d9SBarry Smith Logically Collective on SNES 1453d25893d9SBarry Smith 1454d25893d9SBarry Smith Input Parameters: 1455d25893d9SBarry Smith + snes - the SNES context 1456d25893d9SBarry Smith . func - function evaluation routine 1457d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1458d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1459d25893d9SBarry Smith 1460d25893d9SBarry Smith Calling sequence of func: 1461d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1462d25893d9SBarry Smith 1463d25893d9SBarry Smith . f - function vector 1464d25893d9SBarry Smith - ctx - optional user-defined function context 1465d25893d9SBarry Smith 1466d25893d9SBarry Smith Level: intermediate 1467d25893d9SBarry Smith 1468d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1469d25893d9SBarry Smith 1470d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1471d25893d9SBarry Smith @*/ 1472d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1473d25893d9SBarry Smith { 1474d25893d9SBarry Smith PetscFunctionBegin; 1475d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1476d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1477d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1478d25893d9SBarry Smith PetscFunctionReturn(0); 1479d25893d9SBarry Smith } 1480d25893d9SBarry Smith 14813ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 14823ab0aad5SBarry Smith #undef __FUNCT__ 14831096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 14841096aae1SMatthew Knepley /*@C 14851096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 14861096aae1SMatthew Knepley it assumes a zero right hand side. 14871096aae1SMatthew Knepley 14883f9fe445SBarry Smith Logically Collective on SNES 14891096aae1SMatthew Knepley 14901096aae1SMatthew Knepley Input Parameter: 14911096aae1SMatthew Knepley . snes - the SNES context 14921096aae1SMatthew Knepley 14931096aae1SMatthew Knepley Output Parameter: 1494bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 14951096aae1SMatthew Knepley 14961096aae1SMatthew Knepley Level: intermediate 14971096aae1SMatthew Knepley 14981096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 14991096aae1SMatthew Knepley 150085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 15011096aae1SMatthew Knepley @*/ 15027087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 15031096aae1SMatthew Knepley { 15041096aae1SMatthew Knepley PetscFunctionBegin; 15050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15061096aae1SMatthew Knepley PetscValidPointer(rhs,2); 150785385478SLisandro Dalcin *rhs = snes->vec_rhs; 15081096aae1SMatthew Knepley PetscFunctionReturn(0); 15091096aae1SMatthew Knepley } 15101096aae1SMatthew Knepley 15111096aae1SMatthew Knepley #undef __FUNCT__ 15124a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 15139b94acceSBarry Smith /*@ 151436851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 15159b94acceSBarry Smith SNESSetFunction(). 15169b94acceSBarry Smith 1517c7afd0dbSLois Curfman McInnes Collective on SNES 1518c7afd0dbSLois Curfman McInnes 15199b94acceSBarry Smith Input Parameters: 1520c7afd0dbSLois Curfman McInnes + snes - the SNES context 1521c7afd0dbSLois Curfman McInnes - x - input vector 15229b94acceSBarry Smith 15239b94acceSBarry Smith Output Parameter: 15243638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 15259b94acceSBarry Smith 15261bffabb2SLois Curfman McInnes Notes: 152736851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 152836851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 152936851e7fSLois Curfman McInnes themselves. 153036851e7fSLois Curfman McInnes 153136851e7fSLois Curfman McInnes Level: developer 153236851e7fSLois Curfman McInnes 15339b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 15349b94acceSBarry Smith 1535a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 15369b94acceSBarry Smith @*/ 15377087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 15389b94acceSBarry Smith { 1539dfbe8321SBarry Smith PetscErrorCode ierr; 15409b94acceSBarry Smith 15413a40ed3dSBarry Smith PetscFunctionBegin; 15420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15430700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 15440700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1545c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1546c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 15474ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1548184914b5SBarry Smith 1549d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 1550e7788613SBarry Smith if (snes->ops->computefunction) { 1551d64ed03dSBarry Smith PetscStackPush("SNES user function"); 155239d508bbSBarry Smith ierr = (*snes->ops->computefunction)(snes,x,y,snes->funP);CHKERRQ(ierr); 1553d64ed03dSBarry Smith PetscStackPop; 155473250ac0SBarry Smith } else if (snes->dm) { 1555644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1556c90fad12SPeter Brune } else if (snes->vec_rhs) { 1557c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1558644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 155985385478SLisandro Dalcin if (snes->vec_rhs) { 156085385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 15613ab0aad5SBarry Smith } 1562ae3c334cSLois Curfman McInnes snes->nfuncs++; 1563d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 15644ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 15653a40ed3dSBarry Smith PetscFunctionReturn(0); 15669b94acceSBarry Smith } 15679b94acceSBarry Smith 15684a2ae208SSatish Balay #undef __FUNCT__ 1569646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1570c79ef259SPeter Brune /*@ 1571c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1572c79ef259SPeter Brune SNESSetGS(). 1573c79ef259SPeter Brune 1574c79ef259SPeter Brune Collective on SNES 1575c79ef259SPeter Brune 1576c79ef259SPeter Brune Input Parameters: 1577c79ef259SPeter Brune + snes - the SNES context 1578c79ef259SPeter Brune . x - input vector 1579c79ef259SPeter Brune - b - rhs vector 1580c79ef259SPeter Brune 1581c79ef259SPeter Brune Output Parameter: 1582c79ef259SPeter Brune . x - new solution vector 1583c79ef259SPeter Brune 1584c79ef259SPeter Brune Notes: 1585c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1586c79ef259SPeter Brune implementations, so most users would not generally call this routine 1587c79ef259SPeter Brune themselves. 1588c79ef259SPeter Brune 1589c79ef259SPeter Brune Level: developer 1590c79ef259SPeter Brune 1591c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1592c79ef259SPeter Brune 1593c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1594c79ef259SPeter Brune @*/ 1595646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1596646217ecSPeter Brune { 1597646217ecSPeter Brune PetscErrorCode ierr; 159889b92e6fSPeter Brune PetscInt i; 1599646217ecSPeter Brune 1600646217ecSPeter Brune PetscFunctionBegin; 1601646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1602646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1603646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1604646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1605646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 16064ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1607701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 1608646217ecSPeter Brune if (snes->ops->computegs) { 160989b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1610646217ecSPeter Brune PetscStackPush("SNES user GS"); 1611646217ecSPeter Brune ierr = (*snes->ops->computegs)(snes,x,b,snes->gsP);CHKERRQ(ierr); 1612646217ecSPeter Brune PetscStackPop; 161389b92e6fSPeter Brune } 1614646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1615701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 16164ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1617646217ecSPeter Brune PetscFunctionReturn(0); 1618646217ecSPeter Brune } 1619646217ecSPeter Brune 1620646217ecSPeter Brune 1621646217ecSPeter Brune #undef __FUNCT__ 16224a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 162362fef451SLois Curfman McInnes /*@ 162462fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 162562fef451SLois Curfman McInnes set with SNESSetJacobian(). 162662fef451SLois Curfman McInnes 1627c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1628c7afd0dbSLois Curfman McInnes 162962fef451SLois Curfman McInnes Input Parameters: 1630c7afd0dbSLois Curfman McInnes + snes - the SNES context 1631c7afd0dbSLois Curfman McInnes - x - input vector 163262fef451SLois Curfman McInnes 163362fef451SLois Curfman McInnes Output Parameters: 1634c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 163562fef451SLois Curfman McInnes . B - optional preconditioning matrix 16362b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1637fee21e36SBarry Smith 1638e35cf81dSBarry Smith Options Database Keys: 1639e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1640693365a8SJed Brown . -snes_lag_jacobian <lag> 1641693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1642693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1643693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 16444c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1645c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1646c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1647c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1648c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1649c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 16504c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1651c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1652c01495d3SJed Brown 1653e35cf81dSBarry Smith 165462fef451SLois Curfman McInnes Notes: 165562fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 165662fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 165762fef451SLois Curfman McInnes 165894b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1659dc5a77f8SLois Curfman McInnes flag parameter. 166062fef451SLois Curfman McInnes 166136851e7fSLois Curfman McInnes Level: developer 166236851e7fSLois Curfman McInnes 166362fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 166462fef451SLois Curfman McInnes 1665e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 166662fef451SLois Curfman McInnes @*/ 16677087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 16689b94acceSBarry Smith { 1669dfbe8321SBarry Smith PetscErrorCode ierr; 1670ace3abfcSBarry Smith PetscBool flag; 16713a40ed3dSBarry Smith 16723a40ed3dSBarry Smith PetscFunctionBegin; 16730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16740700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 16754482741eSBarry Smith PetscValidPointer(flg,5); 1676c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 16774ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 1678e7788613SBarry Smith if (!snes->ops->computejacobian) PetscFunctionReturn(0); 1679ebd3b9afSBarry Smith 1680ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1681ebd3b9afSBarry Smith 1682fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1683fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1684fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1685fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1686e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1687e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1688ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1689ebd3b9afSBarry Smith if (flag) { 1690ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1691ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1692ebd3b9afSBarry Smith } 1693e35cf81dSBarry Smith PetscFunctionReturn(0); 1694e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1695e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1696e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1697ebd3b9afSBarry Smith ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1698ebd3b9afSBarry Smith if (flag) { 1699ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1700ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1701ebd3b9afSBarry Smith } 1702e35cf81dSBarry Smith PetscFunctionReturn(0); 1703e35cf81dSBarry Smith } 1704e35cf81dSBarry Smith 1705c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1706e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1707d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 1708e7788613SBarry Smith ierr = (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);CHKERRQ(ierr); 1709d64ed03dSBarry Smith PetscStackPop; 1710d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1711a8054027SBarry Smith 17123b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 17133b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 17143b4f5425SBarry Smith snes->lagpreconditioner = -1; 17153b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1716a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1717a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1718a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1719a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1720a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1721a8054027SBarry Smith } 1722a8054027SBarry Smith 17236d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 17240700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 17250700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1726693365a8SJed Brown { 1727693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 1728693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 1729693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 1730693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 1731693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 1732693365a8SJed Brown if (flag || flag_draw || flag_contour) { 1733693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 1734693365a8SJed Brown MatStructure mstruct; 1735693365a8SJed Brown PetscViewer vdraw,vstdout; 17366b3a5b13SJed Brown PetscBool flg; 1737693365a8SJed Brown if (flag_operator) { 1738693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 1739693365a8SJed Brown Bexp = Bexp_mine; 1740693365a8SJed Brown } else { 1741693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 1742693365a8SJed Brown ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 1743693365a8SJed Brown if (flg) Bexp = *B; 1744693365a8SJed Brown else { 1745693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 1746693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 1747693365a8SJed Brown Bexp = Bexp_mine; 1748693365a8SJed Brown } 1749693365a8SJed Brown } 1750693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 1751693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 1752693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 1753693365a8SJed Brown if (flag_draw || flag_contour) { 1754693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 1755693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 1756693365a8SJed Brown } else vdraw = PETSC_NULL; 1757693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 1758693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 1759693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 1760693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 1761693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1762693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 1763693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 1764693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 1765693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 1766693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 1767693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 1768693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 1769693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 1770693365a8SJed Brown } 1771693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 1772693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 1773693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 1774693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 1775693365a8SJed Brown } 1776693365a8SJed Brown } 17774c30e9fbSJed Brown { 17786719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 17796719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 17804c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 17816719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 17824c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 17834c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 17846719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 17856719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 17866719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 17876719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 17884c30e9fbSJed Brown Mat Bfd; 17894c30e9fbSJed Brown MatStructure mstruct; 17904c30e9fbSJed Brown PetscViewer vdraw,vstdout; 17914c30e9fbSJed Brown ISColoring iscoloring; 17924c30e9fbSJed Brown MatFDColoring matfdcoloring; 17934c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 17944c30e9fbSJed Brown void *funcctx; 17956719d8e4SJed Brown PetscReal norm1,norm2,normmax; 17964c30e9fbSJed Brown 17974c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 17984c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 17994c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 18004c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 18014c30e9fbSJed Brown 18024c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 18034c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 18044c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 18054c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 18064c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 18074c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 18084c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 18094c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 18104c30e9fbSJed Brown 18114c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 18124c30e9fbSJed Brown if (flag_draw || flag_contour) { 18134c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 18144c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 18154c30e9fbSJed Brown } else vdraw = PETSC_NULL; 18164c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 18176719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 18184c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 18194c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 18206719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 18214c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 18224c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 18234c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 18246719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 18254c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 18266719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 18276719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 18284c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 18294c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 18304c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 18314c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 18324c30e9fbSJed Brown } 18334c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 18346719d8e4SJed Brown 18356719d8e4SJed Brown if (flag_threshold) { 18366719d8e4SJed Brown PetscInt bs,rstart,rend,i; 18376719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 18386719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 18396719d8e4SJed Brown for (i=rstart; i<rend; i++) { 18406719d8e4SJed Brown const PetscScalar *ba,*ca; 18416719d8e4SJed Brown const PetscInt *bj,*cj; 18426719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 18436719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 18446719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 18456719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 18466719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 18476719d8e4SJed Brown for (j=0; j<bn; j++) { 18486719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 18496719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 18506719d8e4SJed Brown maxentrycol = bj[j]; 18516719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 18526719d8e4SJed Brown } 18536719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 18546719d8e4SJed Brown maxdiffcol = bj[j]; 18556719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 18566719d8e4SJed Brown } 18576719d8e4SJed Brown if (rdiff > maxrdiff) { 18586719d8e4SJed Brown maxrdiffcol = bj[j]; 18596719d8e4SJed Brown maxrdiff = rdiff; 18606719d8e4SJed Brown } 18616719d8e4SJed Brown } 18626719d8e4SJed Brown if (maxrdiff > 1) { 18636719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%G at %D, maxdiff=%G at %D, maxrdiff=%G at %D):",i,maxentry,maxentrycol,maxdiff,maxdiffcol,maxrdiff,maxrdiffcol);CHKERRQ(ierr); 18646719d8e4SJed Brown for (j=0; j<bn; j++) { 18656719d8e4SJed Brown PetscReal rdiff; 18666719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 18676719d8e4SJed Brown if (rdiff > 1) { 18686719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 18696719d8e4SJed Brown } 18706719d8e4SJed Brown } 18716719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 18726719d8e4SJed Brown } 18736719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 18746719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 18756719d8e4SJed Brown } 18766719d8e4SJed Brown } 18774c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 18784c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 18794c30e9fbSJed Brown } 18804c30e9fbSJed Brown } 18813a40ed3dSBarry Smith PetscFunctionReturn(0); 18829b94acceSBarry Smith } 18839b94acceSBarry Smith 18844a2ae208SSatish Balay #undef __FUNCT__ 18854a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 18869b94acceSBarry Smith /*@C 18879b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 1888044dda88SLois Curfman McInnes location to store the matrix. 18899b94acceSBarry Smith 18903f9fe445SBarry Smith Logically Collective on SNES and Mat 1891c7afd0dbSLois Curfman McInnes 18929b94acceSBarry Smith Input Parameters: 1893c7afd0dbSLois Curfman McInnes + snes - the SNES context 18949b94acceSBarry Smith . A - Jacobian matrix 18959b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 1896efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 1897c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1898efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 18999b94acceSBarry Smith 19009b94acceSBarry Smith Calling sequence of func: 19018d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 19029b94acceSBarry Smith 1903c7afd0dbSLois Curfman McInnes + x - input vector 19049b94acceSBarry Smith . A - Jacobian matrix 19059b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 1906ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 19072b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 1908c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 19099b94acceSBarry Smith 19109b94acceSBarry Smith Notes: 191194b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 19122cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 1913ac21db08SLois Curfman McInnes 1914ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 19159b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 19169b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 19179b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 19189b94acceSBarry Smith throughout the global iterations. 19199b94acceSBarry Smith 192016913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 192116913363SBarry Smith each matrix. 192216913363SBarry Smith 1923a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 1924a8a26c1eSJed Brown must be a MatFDColoring. 1925a8a26c1eSJed Brown 1926c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 1927c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 1928c3cc8fd1SJed Brown 192936851e7fSLois Curfman McInnes Level: beginner 193036851e7fSLois Curfman McInnes 19319b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 19329b94acceSBarry Smith 19333ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 19349b94acceSBarry Smith @*/ 19357087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 19369b94acceSBarry Smith { 1937dfbe8321SBarry Smith PetscErrorCode ierr; 19383a7fca6bSBarry Smith 19393a40ed3dSBarry Smith PetscFunctionBegin; 19400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19410700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 19420700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 1943c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 194406975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 1945e7788613SBarry Smith if (func) snes->ops->computejacobian = func; 19463a7fca6bSBarry Smith if (ctx) snes->jacP = ctx; 19473a7fca6bSBarry Smith if (A) { 19487dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 19496bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 19509b94acceSBarry Smith snes->jacobian = A; 19513a7fca6bSBarry Smith } 19523a7fca6bSBarry Smith if (B) { 19537dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 19546bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 19559b94acceSBarry Smith snes->jacobian_pre = B; 19563a7fca6bSBarry Smith } 19573a40ed3dSBarry Smith PetscFunctionReturn(0); 19589b94acceSBarry Smith } 195962fef451SLois Curfman McInnes 19604a2ae208SSatish Balay #undef __FUNCT__ 19614a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 1962c2aafc4cSSatish Balay /*@C 1963b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 1964b4fd4287SBarry Smith provided context for evaluating the Jacobian. 1965b4fd4287SBarry Smith 1966c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 1967c7afd0dbSLois Curfman McInnes 1968b4fd4287SBarry Smith Input Parameter: 1969b4fd4287SBarry Smith . snes - the nonlinear solver context 1970b4fd4287SBarry Smith 1971b4fd4287SBarry Smith Output Parameters: 1972c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 1973b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 197470e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 197570e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 1976fee21e36SBarry Smith 197736851e7fSLois Curfman McInnes Level: advanced 197836851e7fSLois Curfman McInnes 1979b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 1980b4fd4287SBarry Smith @*/ 19817087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 1982b4fd4287SBarry Smith { 19833a40ed3dSBarry Smith PetscFunctionBegin; 19840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1985b4fd4287SBarry Smith if (A) *A = snes->jacobian; 1986b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 1987e7788613SBarry Smith if (func) *func = snes->ops->computejacobian; 198870e92668SMatthew Knepley if (ctx) *ctx = snes->jacP; 19893a40ed3dSBarry Smith PetscFunctionReturn(0); 1990b4fd4287SBarry Smith } 1991b4fd4287SBarry Smith 19929b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 19939b94acceSBarry Smith 19944a2ae208SSatish Balay #undef __FUNCT__ 19954a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 19969b94acceSBarry Smith /*@ 19979b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 1998272ac6f2SLois Curfman McInnes of a nonlinear solver. 19999b94acceSBarry Smith 2000fee21e36SBarry Smith Collective on SNES 2001fee21e36SBarry Smith 2002c7afd0dbSLois Curfman McInnes Input Parameters: 200370e92668SMatthew Knepley . snes - the SNES context 2004c7afd0dbSLois Curfman McInnes 2005272ac6f2SLois Curfman McInnes Notes: 2006272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2007272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2008272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2009272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2010272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2011272ac6f2SLois Curfman McInnes 201236851e7fSLois Curfman McInnes Level: advanced 201336851e7fSLois Curfman McInnes 20149b94acceSBarry Smith .keywords: SNES, nonlinear, setup 20159b94acceSBarry Smith 20169b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 20179b94acceSBarry Smith @*/ 20187087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 20199b94acceSBarry Smith { 2020dfbe8321SBarry Smith PetscErrorCode ierr; 20213a40ed3dSBarry Smith 20223a40ed3dSBarry Smith PetscFunctionBegin; 20230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20244dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 20259b94acceSBarry Smith 20267adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 202785385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 202885385478SLisandro Dalcin } 202985385478SLisandro Dalcin 2030a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 203117186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 203258c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 203358c9b817SLisandro Dalcin 203458c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 203558c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 203658c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 203758c9b817SLisandro Dalcin } 203858c9b817SLisandro Dalcin 2039ef8dffc7SBarry Smith if (!snes->ops->computejacobian && snes->dm) { 2040214df951SJed Brown Mat J,B; 2041214df951SJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 2042214df951SJed Brown if (snes->mf_operator) { 2043214df951SJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 2044214df951SJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2045214df951SJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 2046214df951SJed Brown } else { 2047214df951SJed Brown J = B; 2048214df951SJed Brown ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr); 2049214df951SJed Brown } 2050214df951SJed Brown ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr); 2051cab2e9ccSBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 2052214df951SJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 20532ef29e96SBarry Smith } else if (!snes->jacobian && snes->ops->computejacobian == MatMFFDComputeJacobian) { 2054a8248277SBarry Smith Mat J; 2055a8248277SBarry Smith ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 2056a8248277SBarry Smith ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2057a8248277SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 2058a8248277SBarry Smith ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);CHKERRQ(ierr); 2059a8248277SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 2060a8248277SBarry Smith } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 2061a8248277SBarry Smith Mat J,B; 2062a8248277SBarry Smith ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 2063a8248277SBarry Smith ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2064a8248277SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 2065950540a4SJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 2066a8248277SBarry Smith ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,snes->funP);CHKERRQ(ierr); 2067a8248277SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 2068a8248277SBarry Smith ierr = MatDestroy(&B);CHKERRQ(ierr); 2069efd51863SBarry Smith } else if (snes->dm && !snes->jacobian_pre){ 2070efd51863SBarry Smith Mat J; 2071950540a4SJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&J);CHKERRQ(ierr); 20723cbb28f5SBarry Smith ierr = SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 2073efd51863SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 2074ef8dffc7SBarry Smith } 2075cfaf3a74SBarry Smith if (!snes->ops->computefunction && !snes->dm) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction() or call SNESSetDM()"); 2076c9b9fda1SJed Brown if (!snes->vec_func) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a vector when calling SNESSetFunction() or call SNESSetDM()"); 2077efd51863SBarry Smith 2078b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2079b710008aSBarry Smith 2080d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2081d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2082d25893d9SBarry Smith } 2083d25893d9SBarry Smith 2084410397dcSLisandro Dalcin if (snes->ops->setup) { 2085410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2086410397dcSLisandro Dalcin } 208758c9b817SLisandro Dalcin 20887aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 20893a40ed3dSBarry Smith PetscFunctionReturn(0); 20909b94acceSBarry Smith } 20919b94acceSBarry Smith 20924a2ae208SSatish Balay #undef __FUNCT__ 209337596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 209437596af1SLisandro Dalcin /*@ 209537596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 209637596af1SLisandro Dalcin 209737596af1SLisandro Dalcin Collective on SNES 209837596af1SLisandro Dalcin 209937596af1SLisandro Dalcin Input Parameter: 210037596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 210137596af1SLisandro Dalcin 2102d25893d9SBarry Smith Level: intermediate 2103d25893d9SBarry Smith 2104d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 210537596af1SLisandro Dalcin 210637596af1SLisandro Dalcin .keywords: SNES, destroy 210737596af1SLisandro Dalcin 210837596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 210937596af1SLisandro Dalcin @*/ 211037596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 211137596af1SLisandro Dalcin { 211237596af1SLisandro Dalcin PetscErrorCode ierr; 211337596af1SLisandro Dalcin 211437596af1SLisandro Dalcin PetscFunctionBegin; 211537596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2116d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2117d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2118d25893d9SBarry Smith snes->user = PETSC_NULL; 2119d25893d9SBarry Smith } 21208a23116dSBarry Smith if (snes->pc) { 21218a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 21228a23116dSBarry Smith } 21238a23116dSBarry Smith 212437596af1SLisandro Dalcin if (snes->ops->reset) { 212537596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 212637596af1SLisandro Dalcin } 212737596af1SLisandro Dalcin if (snes->ksp) {ierr = KSPReset(snes->ksp);CHKERRQ(ierr);} 21286bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 21296bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 21306bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 21316bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 21326bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 21336bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 213437596af1SLisandro Dalcin if (snes->work) {ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);} 213537596af1SLisandro Dalcin if (snes->vwork) {ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);} 213637596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 213737596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 213837596af1SLisandro Dalcin PetscFunctionReturn(0); 213937596af1SLisandro Dalcin } 214037596af1SLisandro Dalcin 214137596af1SLisandro Dalcin #undef __FUNCT__ 21424a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 214352baeb72SSatish Balay /*@ 21449b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 21459b94acceSBarry Smith with SNESCreate(). 21469b94acceSBarry Smith 2147c7afd0dbSLois Curfman McInnes Collective on SNES 2148c7afd0dbSLois Curfman McInnes 21499b94acceSBarry Smith Input Parameter: 21509b94acceSBarry Smith . snes - the SNES context 21519b94acceSBarry Smith 215236851e7fSLois Curfman McInnes Level: beginner 215336851e7fSLois Curfman McInnes 21549b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 21559b94acceSBarry Smith 215663a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 21579b94acceSBarry Smith @*/ 21586bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 21599b94acceSBarry Smith { 21606849ba73SBarry Smith PetscErrorCode ierr; 21613a40ed3dSBarry Smith 21623a40ed3dSBarry Smith PetscFunctionBegin; 21636bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 21646bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 21656bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2166d4bb536fSBarry Smith 21676bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 21688a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 21696b8b9a38SLisandro Dalcin 2170be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 21716bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 21726bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 21736d4c513bSLisandro Dalcin 21746bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 21756bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 21766b8b9a38SLisandro Dalcin 21776bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 21786bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 21796bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 21806b8b9a38SLisandro Dalcin } 21816bf464f9SBarry Smith if ((*snes)->conv_malloc) { 21826bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 21836bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 218458c9b817SLisandro Dalcin } 2185ea630c6eSPeter Brune ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr); 21866bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2187a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 21883a40ed3dSBarry Smith PetscFunctionReturn(0); 21899b94acceSBarry Smith } 21909b94acceSBarry Smith 21919b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 21929b94acceSBarry Smith 21934a2ae208SSatish Balay #undef __FUNCT__ 2194a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2195a8054027SBarry Smith /*@ 2196a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2197a8054027SBarry Smith 21983f9fe445SBarry Smith Logically Collective on SNES 2199a8054027SBarry Smith 2200a8054027SBarry Smith Input Parameters: 2201a8054027SBarry Smith + snes - the SNES context 2202a8054027SBarry Smith - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 22033b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2204a8054027SBarry Smith 2205a8054027SBarry Smith Options Database Keys: 2206a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2207a8054027SBarry Smith 2208a8054027SBarry Smith Notes: 2209a8054027SBarry Smith The default is 1 2210a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2211a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2212a8054027SBarry Smith 2213a8054027SBarry Smith Level: intermediate 2214a8054027SBarry Smith 2215a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2216a8054027SBarry Smith 2217e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2218a8054027SBarry Smith 2219a8054027SBarry Smith @*/ 22207087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2221a8054027SBarry Smith { 2222a8054027SBarry Smith PetscFunctionBegin; 22230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2224e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2225e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2226c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2227a8054027SBarry Smith snes->lagpreconditioner = lag; 2228a8054027SBarry Smith PetscFunctionReturn(0); 2229a8054027SBarry Smith } 2230a8054027SBarry Smith 2231a8054027SBarry Smith #undef __FUNCT__ 2232efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2233efd51863SBarry Smith /*@ 2234efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2235efd51863SBarry Smith 2236efd51863SBarry Smith Logically Collective on SNES 2237efd51863SBarry Smith 2238efd51863SBarry Smith Input Parameters: 2239efd51863SBarry Smith + snes - the SNES context 2240efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2241efd51863SBarry Smith 2242efd51863SBarry Smith Options Database Keys: 2243efd51863SBarry Smith . -snes_grid_sequence <steps> 2244efd51863SBarry Smith 2245efd51863SBarry Smith Level: intermediate 2246efd51863SBarry Smith 2247c0df2a02SJed Brown Notes: 2248c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2249c0df2a02SJed Brown 2250efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2251efd51863SBarry Smith 2252efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2253efd51863SBarry Smith 2254efd51863SBarry Smith @*/ 2255efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2256efd51863SBarry Smith { 2257efd51863SBarry Smith PetscFunctionBegin; 2258efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2259efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2260efd51863SBarry Smith snes->gridsequence = steps; 2261efd51863SBarry Smith PetscFunctionReturn(0); 2262efd51863SBarry Smith } 2263efd51863SBarry Smith 2264efd51863SBarry Smith #undef __FUNCT__ 2265a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2266a8054027SBarry Smith /*@ 2267a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2268a8054027SBarry Smith 22693f9fe445SBarry Smith Not Collective 2270a8054027SBarry Smith 2271a8054027SBarry Smith Input Parameter: 2272a8054027SBarry Smith . snes - the SNES context 2273a8054027SBarry Smith 2274a8054027SBarry Smith Output Parameter: 2275a8054027SBarry Smith . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 22763b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2277a8054027SBarry Smith 2278a8054027SBarry Smith Options Database Keys: 2279a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2280a8054027SBarry Smith 2281a8054027SBarry Smith Notes: 2282a8054027SBarry Smith The default is 1 2283a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2284a8054027SBarry Smith 2285a8054027SBarry Smith Level: intermediate 2286a8054027SBarry Smith 2287a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2288a8054027SBarry Smith 2289a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2290a8054027SBarry Smith 2291a8054027SBarry Smith @*/ 22927087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2293a8054027SBarry Smith { 2294a8054027SBarry Smith PetscFunctionBegin; 22950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2296a8054027SBarry Smith *lag = snes->lagpreconditioner; 2297a8054027SBarry Smith PetscFunctionReturn(0); 2298a8054027SBarry Smith } 2299a8054027SBarry Smith 2300a8054027SBarry Smith #undef __FUNCT__ 2301e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2302e35cf81dSBarry Smith /*@ 2303e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2304e35cf81dSBarry Smith often the preconditioner is rebuilt. 2305e35cf81dSBarry Smith 23063f9fe445SBarry Smith Logically Collective on SNES 2307e35cf81dSBarry Smith 2308e35cf81dSBarry Smith Input Parameters: 2309e35cf81dSBarry Smith + snes - the SNES context 2310e35cf81dSBarry Smith - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 2311fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2312e35cf81dSBarry Smith 2313e35cf81dSBarry Smith Options Database Keys: 2314e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2315e35cf81dSBarry Smith 2316e35cf81dSBarry Smith Notes: 2317e35cf81dSBarry Smith The default is 1 2318e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2319fe3ffe1eSBarry Smith 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 2320fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2321e35cf81dSBarry Smith 2322e35cf81dSBarry Smith Level: intermediate 2323e35cf81dSBarry Smith 2324e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2325e35cf81dSBarry Smith 2326e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2327e35cf81dSBarry Smith 2328e35cf81dSBarry Smith @*/ 23297087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2330e35cf81dSBarry Smith { 2331e35cf81dSBarry Smith PetscFunctionBegin; 23320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2333e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2334e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2335c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2336e35cf81dSBarry Smith snes->lagjacobian = lag; 2337e35cf81dSBarry Smith PetscFunctionReturn(0); 2338e35cf81dSBarry Smith } 2339e35cf81dSBarry Smith 2340e35cf81dSBarry Smith #undef __FUNCT__ 2341e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2342e35cf81dSBarry Smith /*@ 2343e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2344e35cf81dSBarry Smith 23453f9fe445SBarry Smith Not Collective 2346e35cf81dSBarry Smith 2347e35cf81dSBarry Smith Input Parameter: 2348e35cf81dSBarry Smith . snes - the SNES context 2349e35cf81dSBarry Smith 2350e35cf81dSBarry Smith Output Parameter: 2351e35cf81dSBarry Smith . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 2352e35cf81dSBarry Smith the Jacobian is built etc. 2353e35cf81dSBarry Smith 2354e35cf81dSBarry Smith Options Database Keys: 2355e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2356e35cf81dSBarry Smith 2357e35cf81dSBarry Smith Notes: 2358e35cf81dSBarry Smith The default is 1 2359e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2360e35cf81dSBarry Smith 2361e35cf81dSBarry Smith Level: intermediate 2362e35cf81dSBarry Smith 2363e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2364e35cf81dSBarry Smith 2365e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2366e35cf81dSBarry Smith 2367e35cf81dSBarry Smith @*/ 23687087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2369e35cf81dSBarry Smith { 2370e35cf81dSBarry Smith PetscFunctionBegin; 23710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2372e35cf81dSBarry Smith *lag = snes->lagjacobian; 2373e35cf81dSBarry Smith PetscFunctionReturn(0); 2374e35cf81dSBarry Smith } 2375e35cf81dSBarry Smith 2376e35cf81dSBarry Smith #undef __FUNCT__ 23774a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 23789b94acceSBarry Smith /*@ 2379d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 23809b94acceSBarry Smith 23813f9fe445SBarry Smith Logically Collective on SNES 2382c7afd0dbSLois Curfman McInnes 23839b94acceSBarry Smith Input Parameters: 2384c7afd0dbSLois Curfman McInnes + snes - the SNES context 238570441072SBarry Smith . abstol - absolute convergence tolerance 238633174efeSLois Curfman McInnes . rtol - relative convergence tolerance 238733174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 238833174efeSLois Curfman McInnes of the change in the solution between steps 238933174efeSLois Curfman McInnes . maxit - maximum number of iterations 2390c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2391fee21e36SBarry Smith 239233174efeSLois Curfman McInnes Options Database Keys: 239370441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2394c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2395c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2396c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2397c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 23989b94acceSBarry Smith 2399d7a720efSLois Curfman McInnes Notes: 24009b94acceSBarry Smith The default maximum number of iterations is 50. 24019b94acceSBarry Smith The default maximum number of function evaluations is 1000. 24029b94acceSBarry Smith 240336851e7fSLois Curfman McInnes Level: intermediate 240436851e7fSLois Curfman McInnes 240533174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 24069b94acceSBarry Smith 24072492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 24089b94acceSBarry Smith @*/ 24097087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 24109b94acceSBarry Smith { 24113a40ed3dSBarry Smith PetscFunctionBegin; 24120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2413c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2414c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2415c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2416c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2417c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2418c5eb9154SBarry Smith 2419ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2420ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2421ab54825eSJed Brown snes->abstol = abstol; 2422ab54825eSJed Brown } 2423ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2424ab54825eSJed Brown if (rtol < 0.0 || 1.0 <= rtol) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %G must be non-negative and less than 1.0",rtol); 2425ab54825eSJed Brown snes->rtol = rtol; 2426ab54825eSJed Brown } 2427ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2428ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2429ab54825eSJed Brown snes->xtol = stol; 2430ab54825eSJed Brown } 2431ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2432ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2433ab54825eSJed Brown snes->max_its = maxit; 2434ab54825eSJed Brown } 2435ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2436ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2437ab54825eSJed Brown snes->max_funcs = maxf; 2438ab54825eSJed Brown } 24393a40ed3dSBarry Smith PetscFunctionReturn(0); 24409b94acceSBarry Smith } 24419b94acceSBarry Smith 24424a2ae208SSatish Balay #undef __FUNCT__ 24434a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 24449b94acceSBarry Smith /*@ 244533174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 244633174efeSLois Curfman McInnes 2447c7afd0dbSLois Curfman McInnes Not Collective 2448c7afd0dbSLois Curfman McInnes 244933174efeSLois Curfman McInnes Input Parameters: 2450c7afd0dbSLois Curfman McInnes + snes - the SNES context 245185385478SLisandro Dalcin . atol - absolute convergence tolerance 245233174efeSLois Curfman McInnes . rtol - relative convergence tolerance 245333174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 245433174efeSLois Curfman McInnes of the change in the solution between steps 245533174efeSLois Curfman McInnes . maxit - maximum number of iterations 2456c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2457fee21e36SBarry Smith 245833174efeSLois Curfman McInnes Notes: 245933174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 246033174efeSLois Curfman McInnes 246136851e7fSLois Curfman McInnes Level: intermediate 246236851e7fSLois Curfman McInnes 246333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 246433174efeSLois Curfman McInnes 246533174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 246633174efeSLois Curfman McInnes @*/ 24677087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 246833174efeSLois Curfman McInnes { 24693a40ed3dSBarry Smith PetscFunctionBegin; 24700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 247185385478SLisandro Dalcin if (atol) *atol = snes->abstol; 247233174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 247333174efeSLois Curfman McInnes if (stol) *stol = snes->xtol; 247433174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 247533174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 24763a40ed3dSBarry Smith PetscFunctionReturn(0); 247733174efeSLois Curfman McInnes } 247833174efeSLois Curfman McInnes 24794a2ae208SSatish Balay #undef __FUNCT__ 24804a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 248133174efeSLois Curfman McInnes /*@ 24829b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 24839b94acceSBarry Smith 24843f9fe445SBarry Smith Logically Collective on SNES 2485fee21e36SBarry Smith 2486c7afd0dbSLois Curfman McInnes Input Parameters: 2487c7afd0dbSLois Curfman McInnes + snes - the SNES context 2488c7afd0dbSLois Curfman McInnes - tol - tolerance 2489c7afd0dbSLois Curfman McInnes 24909b94acceSBarry Smith Options Database Key: 2491c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 24929b94acceSBarry Smith 249336851e7fSLois Curfman McInnes Level: intermediate 249436851e7fSLois Curfman McInnes 24959b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 24969b94acceSBarry Smith 24972492ecdbSBarry Smith .seealso: SNESSetTolerances() 24989b94acceSBarry Smith @*/ 24997087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 25009b94acceSBarry Smith { 25013a40ed3dSBarry Smith PetscFunctionBegin; 25020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2503c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 25049b94acceSBarry Smith snes->deltatol = tol; 25053a40ed3dSBarry Smith PetscFunctionReturn(0); 25069b94acceSBarry Smith } 25079b94acceSBarry Smith 2508df9fa365SBarry Smith /* 2509df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2510df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2511df9fa365SBarry Smith macros instead of functions 2512df9fa365SBarry Smith */ 25134a2ae208SSatish Balay #undef __FUNCT__ 2514a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 25157087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2516ce1608b8SBarry Smith { 2517dfbe8321SBarry Smith PetscErrorCode ierr; 2518ce1608b8SBarry Smith 2519ce1608b8SBarry Smith PetscFunctionBegin; 25200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2521a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2522ce1608b8SBarry Smith PetscFunctionReturn(0); 2523ce1608b8SBarry Smith } 2524ce1608b8SBarry Smith 25254a2ae208SSatish Balay #undef __FUNCT__ 2526a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 25277087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2528df9fa365SBarry Smith { 2529dfbe8321SBarry Smith PetscErrorCode ierr; 2530df9fa365SBarry Smith 2531df9fa365SBarry Smith PetscFunctionBegin; 2532a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2533df9fa365SBarry Smith PetscFunctionReturn(0); 2534df9fa365SBarry Smith } 2535df9fa365SBarry Smith 25364a2ae208SSatish Balay #undef __FUNCT__ 2537a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 25386bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2539df9fa365SBarry Smith { 2540dfbe8321SBarry Smith PetscErrorCode ierr; 2541df9fa365SBarry Smith 2542df9fa365SBarry Smith PetscFunctionBegin; 2543a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2544df9fa365SBarry Smith PetscFunctionReturn(0); 2545df9fa365SBarry Smith } 2546df9fa365SBarry Smith 25477087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2548b271bb04SBarry Smith #undef __FUNCT__ 2549b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 25507087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2551b271bb04SBarry Smith { 2552b271bb04SBarry Smith PetscDrawLG lg; 2553b271bb04SBarry Smith PetscErrorCode ierr; 2554b271bb04SBarry Smith PetscReal x,y,per; 2555b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2556b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2557b271bb04SBarry Smith PetscDraw draw; 2558b271bb04SBarry Smith PetscFunctionBegin; 2559b271bb04SBarry Smith if (!monctx) { 2560b271bb04SBarry Smith MPI_Comm comm; 2561b271bb04SBarry Smith 2562b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2563b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2564b271bb04SBarry Smith } 2565b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2566b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2567b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2568b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2569b271bb04SBarry Smith x = (PetscReal) n; 2570b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2571b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2572b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2573b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2574b271bb04SBarry Smith } 2575b271bb04SBarry Smith 2576b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2577b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2578b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2579b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2580b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2581b271bb04SBarry Smith x = (PetscReal) n; 2582b271bb04SBarry Smith y = 100.0*per; 2583b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2584b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2585b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2586b271bb04SBarry Smith } 2587b271bb04SBarry Smith 2588b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2589b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2590b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2591b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2592b271bb04SBarry Smith x = (PetscReal) n; 2593b271bb04SBarry Smith y = (prev - rnorm)/prev; 2594b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2595b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2596b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2597b271bb04SBarry Smith } 2598b271bb04SBarry Smith 2599b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2600b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2601b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2602b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2603b271bb04SBarry Smith x = (PetscReal) n; 2604b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2605b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2606b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2607b271bb04SBarry Smith } 2608b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2609b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2610b271bb04SBarry Smith } 2611b271bb04SBarry Smith prev = rnorm; 2612b271bb04SBarry Smith PetscFunctionReturn(0); 2613b271bb04SBarry Smith } 2614b271bb04SBarry Smith 2615b271bb04SBarry Smith #undef __FUNCT__ 2616b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 26177087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2618b271bb04SBarry Smith { 2619b271bb04SBarry Smith PetscErrorCode ierr; 2620b271bb04SBarry Smith 2621b271bb04SBarry Smith PetscFunctionBegin; 2622b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2623b271bb04SBarry Smith PetscFunctionReturn(0); 2624b271bb04SBarry Smith } 2625b271bb04SBarry Smith 2626b271bb04SBarry Smith #undef __FUNCT__ 2627b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 26286bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2629b271bb04SBarry Smith { 2630b271bb04SBarry Smith PetscErrorCode ierr; 2631b271bb04SBarry Smith 2632b271bb04SBarry Smith PetscFunctionBegin; 2633b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2634b271bb04SBarry Smith PetscFunctionReturn(0); 2635b271bb04SBarry Smith } 2636b271bb04SBarry Smith 26377a03ce2fSLisandro Dalcin #undef __FUNCT__ 26387a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2639228d79bcSJed Brown /*@ 2640228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2641228d79bcSJed Brown 2642228d79bcSJed Brown Collective on SNES 2643228d79bcSJed Brown 2644228d79bcSJed Brown Input Parameters: 2645228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2646228d79bcSJed Brown . iter - iteration number 2647228d79bcSJed Brown - rnorm - relative norm of the residual 2648228d79bcSJed Brown 2649228d79bcSJed Brown Notes: 2650228d79bcSJed Brown This routine is called by the SNES implementations. 2651228d79bcSJed Brown It does not typically need to be called by the user. 2652228d79bcSJed Brown 2653228d79bcSJed Brown Level: developer 2654228d79bcSJed Brown 2655228d79bcSJed Brown .seealso: SNESMonitorSet() 2656228d79bcSJed Brown @*/ 26577a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 26587a03ce2fSLisandro Dalcin { 26597a03ce2fSLisandro Dalcin PetscErrorCode ierr; 26607a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 26617a03ce2fSLisandro Dalcin 26627a03ce2fSLisandro Dalcin PetscFunctionBegin; 26637a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 26647a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 26657a03ce2fSLisandro Dalcin } 26667a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 26677a03ce2fSLisandro Dalcin } 26687a03ce2fSLisandro Dalcin 26699b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 26709b94acceSBarry Smith 26714a2ae208SSatish Balay #undef __FUNCT__ 2672a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 26739b94acceSBarry Smith /*@C 2674a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 26759b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 26769b94acceSBarry Smith progress. 26779b94acceSBarry Smith 26783f9fe445SBarry Smith Logically Collective on SNES 2679fee21e36SBarry Smith 2680c7afd0dbSLois Curfman McInnes Input Parameters: 2681c7afd0dbSLois Curfman McInnes + snes - the SNES context 2682c7afd0dbSLois Curfman McInnes . func - monitoring routine 2683b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2684e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2685b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2686b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 26879b94acceSBarry Smith 2688c7afd0dbSLois Curfman McInnes Calling sequence of func: 2689a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2690c7afd0dbSLois Curfman McInnes 2691c7afd0dbSLois Curfman McInnes + snes - the SNES context 2692c7afd0dbSLois Curfman McInnes . its - iteration number 2693c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 269440a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 26959b94acceSBarry Smith 26969665c990SLois Curfman McInnes Options Database Keys: 2697a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 2698a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 2699a6570f20SBarry Smith uses SNESMonitorLGCreate() 2700cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 2701c7afd0dbSLois Curfman McInnes been hardwired into a code by 2702a6570f20SBarry Smith calls to SNESMonitorSet(), but 2703c7afd0dbSLois Curfman McInnes does not cancel those set via 2704c7afd0dbSLois Curfman McInnes the options database. 27059665c990SLois Curfman McInnes 2706639f9d9dSBarry Smith Notes: 27076bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 2708a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 27096bc08f3fSLois Curfman McInnes order in which they were set. 2710639f9d9dSBarry Smith 2711025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 2712025f1a04SBarry Smith 271336851e7fSLois Curfman McInnes Level: intermediate 271436851e7fSLois Curfman McInnes 27159b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 27169b94acceSBarry Smith 2717a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 27189b94acceSBarry Smith @*/ 2719c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 27209b94acceSBarry Smith { 2721b90d0a6eSBarry Smith PetscInt i; 2722649052a6SBarry Smith PetscErrorCode ierr; 2723b90d0a6eSBarry Smith 27243a40ed3dSBarry Smith PetscFunctionBegin; 27250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 272617186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 2727b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 2728649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 2729649052a6SBarry Smith if (monitordestroy) { 2730c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 2731649052a6SBarry Smith } 2732b90d0a6eSBarry Smith PetscFunctionReturn(0); 2733b90d0a6eSBarry Smith } 2734b90d0a6eSBarry Smith } 2735b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 2736b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 2737639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 27383a40ed3dSBarry Smith PetscFunctionReturn(0); 27399b94acceSBarry Smith } 27409b94acceSBarry Smith 27414a2ae208SSatish Balay #undef __FUNCT__ 2742a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 27435cd90555SBarry Smith /*@C 2744a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 27455cd90555SBarry Smith 27463f9fe445SBarry Smith Logically Collective on SNES 2747c7afd0dbSLois Curfman McInnes 27485cd90555SBarry Smith Input Parameters: 27495cd90555SBarry Smith . snes - the SNES context 27505cd90555SBarry Smith 27511a480d89SAdministrator Options Database Key: 2752a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 2753a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 2754c7afd0dbSLois Curfman McInnes set via the options database 27555cd90555SBarry Smith 27565cd90555SBarry Smith Notes: 27575cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 27585cd90555SBarry Smith 275936851e7fSLois Curfman McInnes Level: intermediate 276036851e7fSLois Curfman McInnes 27615cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 27625cd90555SBarry Smith 2763a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 27645cd90555SBarry Smith @*/ 27657087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 27665cd90555SBarry Smith { 2767d952e501SBarry Smith PetscErrorCode ierr; 2768d952e501SBarry Smith PetscInt i; 2769d952e501SBarry Smith 27705cd90555SBarry Smith PetscFunctionBegin; 27710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2772d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 2773d952e501SBarry Smith if (snes->monitordestroy[i]) { 27743c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 2775d952e501SBarry Smith } 2776d952e501SBarry Smith } 27775cd90555SBarry Smith snes->numbermonitors = 0; 27785cd90555SBarry Smith PetscFunctionReturn(0); 27795cd90555SBarry Smith } 27805cd90555SBarry Smith 27814a2ae208SSatish Balay #undef __FUNCT__ 27824a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 27839b94acceSBarry Smith /*@C 27849b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 27859b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 27869b94acceSBarry Smith 27873f9fe445SBarry Smith Logically Collective on SNES 2788fee21e36SBarry Smith 2789c7afd0dbSLois Curfman McInnes Input Parameters: 2790c7afd0dbSLois Curfman McInnes + snes - the SNES context 2791c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 27927f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 27937f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 27949b94acceSBarry Smith 2795c7afd0dbSLois Curfman McInnes Calling sequence of func: 279606ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 2797c7afd0dbSLois Curfman McInnes 2798c7afd0dbSLois Curfman McInnes + snes - the SNES context 279906ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 2800c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 2801184914b5SBarry Smith . reason - reason for convergence/divergence 2802c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 28034b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 28044b27c08aSLois Curfman McInnes - f - 2-norm of function 28059b94acceSBarry Smith 280636851e7fSLois Curfman McInnes Level: advanced 280736851e7fSLois Curfman McInnes 28089b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 28099b94acceSBarry Smith 281085385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 28119b94acceSBarry Smith @*/ 28127087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 28139b94acceSBarry Smith { 28147f7931b9SBarry Smith PetscErrorCode ierr; 28157f7931b9SBarry Smith 28163a40ed3dSBarry Smith PetscFunctionBegin; 28170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 281885385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 28197f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 28207f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 28217f7931b9SBarry Smith } 282285385478SLisandro Dalcin snes->ops->converged = func; 28237f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 282485385478SLisandro Dalcin snes->cnvP = cctx; 28253a40ed3dSBarry Smith PetscFunctionReturn(0); 28269b94acceSBarry Smith } 28279b94acceSBarry Smith 28284a2ae208SSatish Balay #undef __FUNCT__ 28294a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 283052baeb72SSatish Balay /*@ 2831184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 2832184914b5SBarry Smith 2833184914b5SBarry Smith Not Collective 2834184914b5SBarry Smith 2835184914b5SBarry Smith Input Parameter: 2836184914b5SBarry Smith . snes - the SNES context 2837184914b5SBarry Smith 2838184914b5SBarry Smith Output Parameter: 28394d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 2840184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 2841184914b5SBarry Smith 2842184914b5SBarry Smith Level: intermediate 2843184914b5SBarry Smith 2844184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 2845184914b5SBarry Smith 2846184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 2847184914b5SBarry Smith 284885385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 2849184914b5SBarry Smith @*/ 28507087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 2851184914b5SBarry Smith { 2852184914b5SBarry Smith PetscFunctionBegin; 28530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28544482741eSBarry Smith PetscValidPointer(reason,2); 2855184914b5SBarry Smith *reason = snes->reason; 2856184914b5SBarry Smith PetscFunctionReturn(0); 2857184914b5SBarry Smith } 2858184914b5SBarry Smith 28594a2ae208SSatish Balay #undef __FUNCT__ 28604a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 2861c9005455SLois Curfman McInnes /*@ 2862c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 2863c9005455SLois Curfman McInnes 28643f9fe445SBarry Smith Logically Collective on SNES 2865fee21e36SBarry Smith 2866c7afd0dbSLois Curfman McInnes Input Parameters: 2867c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 28688c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 2869cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 2870758f92a0SBarry Smith . na - size of a and its 287164731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 2872758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 2873c7afd0dbSLois Curfman McInnes 2874308dcc3eSBarry Smith Notes: 2875308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 2876308dcc3eSBarry Smith default array of length 10000 is allocated. 2877308dcc3eSBarry Smith 2878c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 2879c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 2880c9005455SLois Curfman McInnes during the section of code that is being timed. 2881c9005455SLois Curfman McInnes 288236851e7fSLois Curfman McInnes Level: intermediate 288336851e7fSLois Curfman McInnes 2884c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 2885758f92a0SBarry Smith 288608405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 2887758f92a0SBarry Smith 2888c9005455SLois Curfman McInnes @*/ 28897087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 2890c9005455SLois Curfman McInnes { 2891308dcc3eSBarry Smith PetscErrorCode ierr; 2892308dcc3eSBarry Smith 28933a40ed3dSBarry Smith PetscFunctionBegin; 28940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28954482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 2896a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 2897308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 2898308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 2899308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 2900308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 2901308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 2902308dcc3eSBarry Smith } 2903c9005455SLois Curfman McInnes snes->conv_hist = a; 2904758f92a0SBarry Smith snes->conv_hist_its = its; 2905758f92a0SBarry Smith snes->conv_hist_max = na; 2906a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 2907758f92a0SBarry Smith snes->conv_hist_reset = reset; 2908758f92a0SBarry Smith PetscFunctionReturn(0); 2909758f92a0SBarry Smith } 2910758f92a0SBarry Smith 2911308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 2912c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 2913c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 2914308dcc3eSBarry Smith EXTERN_C_BEGIN 2915308dcc3eSBarry Smith #undef __FUNCT__ 2916308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 2917308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 2918308dcc3eSBarry Smith { 2919308dcc3eSBarry Smith mxArray *mat; 2920308dcc3eSBarry Smith PetscInt i; 2921308dcc3eSBarry Smith PetscReal *ar; 2922308dcc3eSBarry Smith 2923308dcc3eSBarry Smith PetscFunctionBegin; 2924308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 2925308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 2926308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 2927308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 2928308dcc3eSBarry Smith } 2929308dcc3eSBarry Smith PetscFunctionReturn(mat); 2930308dcc3eSBarry Smith } 2931308dcc3eSBarry Smith EXTERN_C_END 2932308dcc3eSBarry Smith #endif 2933308dcc3eSBarry Smith 2934308dcc3eSBarry Smith 29354a2ae208SSatish Balay #undef __FUNCT__ 29364a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 29370c4c9dddSBarry Smith /*@C 2938758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 2939758f92a0SBarry Smith 29403f9fe445SBarry Smith Not Collective 2941758f92a0SBarry Smith 2942758f92a0SBarry Smith Input Parameter: 2943758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 2944758f92a0SBarry Smith 2945758f92a0SBarry Smith Output Parameters: 2946758f92a0SBarry Smith . a - array to hold history 2947758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 2948758f92a0SBarry Smith negative if not converged) for each solve. 2949758f92a0SBarry Smith - na - size of a and its 2950758f92a0SBarry Smith 2951758f92a0SBarry Smith Notes: 2952758f92a0SBarry Smith The calling sequence for this routine in Fortran is 2953758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 2954758f92a0SBarry Smith 2955758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 2956758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 2957758f92a0SBarry Smith during the section of code that is being timed. 2958758f92a0SBarry Smith 2959758f92a0SBarry Smith Level: intermediate 2960758f92a0SBarry Smith 2961758f92a0SBarry Smith .keywords: SNES, get, convergence, history 2962758f92a0SBarry Smith 2963758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 2964758f92a0SBarry Smith 2965758f92a0SBarry Smith @*/ 29667087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 2967758f92a0SBarry Smith { 2968758f92a0SBarry Smith PetscFunctionBegin; 29690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2970758f92a0SBarry Smith if (a) *a = snes->conv_hist; 2971758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 2972758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 29733a40ed3dSBarry Smith PetscFunctionReturn(0); 2974c9005455SLois Curfman McInnes } 2975c9005455SLois Curfman McInnes 2976e74ef692SMatthew Knepley #undef __FUNCT__ 2977e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 2978ac226902SBarry Smith /*@C 297976b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 2980eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 29817e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 298276b2cf59SMatthew Knepley 29833f9fe445SBarry Smith Logically Collective on SNES 298476b2cf59SMatthew Knepley 298576b2cf59SMatthew Knepley Input Parameters: 298676b2cf59SMatthew Knepley . snes - The nonlinear solver context 298776b2cf59SMatthew Knepley . func - The function 298876b2cf59SMatthew Knepley 298976b2cf59SMatthew Knepley Calling sequence of func: 2990b5d30489SBarry Smith . func (SNES snes, PetscInt step); 299176b2cf59SMatthew Knepley 299276b2cf59SMatthew Knepley . step - The current step of the iteration 299376b2cf59SMatthew Knepley 2994fe97e370SBarry Smith Level: advanced 2995fe97e370SBarry Smith 2996fe97e370SBarry Smith 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() 2997fe97e370SBarry Smith This is not used by most users. 299876b2cf59SMatthew Knepley 299976b2cf59SMatthew Knepley .keywords: SNES, update 3000b5d30489SBarry Smith 300185385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 300276b2cf59SMatthew Knepley @*/ 30037087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 300476b2cf59SMatthew Knepley { 300576b2cf59SMatthew Knepley PetscFunctionBegin; 30060700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3007e7788613SBarry Smith snes->ops->update = func; 300876b2cf59SMatthew Knepley PetscFunctionReturn(0); 300976b2cf59SMatthew Knepley } 301076b2cf59SMatthew Knepley 3011e74ef692SMatthew Knepley #undef __FUNCT__ 3012e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 301376b2cf59SMatthew Knepley /*@ 301476b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 301576b2cf59SMatthew Knepley 301676b2cf59SMatthew Knepley Not collective 301776b2cf59SMatthew Knepley 301876b2cf59SMatthew Knepley Input Parameters: 301976b2cf59SMatthew Knepley . snes - The nonlinear solver context 302076b2cf59SMatthew Knepley . step - The current step of the iteration 302176b2cf59SMatthew Knepley 3022205452f4SMatthew Knepley Level: intermediate 3023205452f4SMatthew Knepley 302476b2cf59SMatthew Knepley .keywords: SNES, update 3025a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 302676b2cf59SMatthew Knepley @*/ 30277087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 302876b2cf59SMatthew Knepley { 302976b2cf59SMatthew Knepley PetscFunctionBegin; 303076b2cf59SMatthew Knepley PetscFunctionReturn(0); 303176b2cf59SMatthew Knepley } 303276b2cf59SMatthew Knepley 30334a2ae208SSatish Balay #undef __FUNCT__ 30344a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 30359b94acceSBarry Smith /* 30369b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 30379b94acceSBarry Smith positive parameter delta. 30389b94acceSBarry Smith 30399b94acceSBarry Smith Input Parameters: 3040c7afd0dbSLois Curfman McInnes + snes - the SNES context 30419b94acceSBarry Smith . y - approximate solution of linear system 30429b94acceSBarry Smith . fnorm - 2-norm of current function 3043c7afd0dbSLois Curfman McInnes - delta - trust region size 30449b94acceSBarry Smith 30459b94acceSBarry Smith Output Parameters: 3046c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 30479b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 30489b94acceSBarry Smith region, and exceeds zero otherwise. 3049c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 30509b94acceSBarry Smith 30519b94acceSBarry Smith Note: 30524b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 30539b94acceSBarry Smith is set to be the maximum allowable step size. 30549b94acceSBarry Smith 30559b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 30569b94acceSBarry Smith */ 3057dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 30589b94acceSBarry Smith { 3059064f8208SBarry Smith PetscReal nrm; 3060ea709b57SSatish Balay PetscScalar cnorm; 3061dfbe8321SBarry Smith PetscErrorCode ierr; 30623a40ed3dSBarry Smith 30633a40ed3dSBarry Smith PetscFunctionBegin; 30640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 30650700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3066c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3067184914b5SBarry Smith 3068064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3069064f8208SBarry Smith if (nrm > *delta) { 3070064f8208SBarry Smith nrm = *delta/nrm; 3071064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3072064f8208SBarry Smith cnorm = nrm; 30732dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 30749b94acceSBarry Smith *ynorm = *delta; 30759b94acceSBarry Smith } else { 30769b94acceSBarry Smith *gpnorm = 0.0; 3077064f8208SBarry Smith *ynorm = nrm; 30789b94acceSBarry Smith } 30793a40ed3dSBarry Smith PetscFunctionReturn(0); 30809b94acceSBarry Smith } 30819b94acceSBarry Smith 30824a2ae208SSatish Balay #undef __FUNCT__ 30834a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 30846ce558aeSBarry Smith /*@C 3085f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3086f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 30879b94acceSBarry Smith 3088c7afd0dbSLois Curfman McInnes Collective on SNES 3089c7afd0dbSLois Curfman McInnes 3090b2002411SLois Curfman McInnes Input Parameters: 3091c7afd0dbSLois Curfman McInnes + snes - the SNES context 30923cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 309385385478SLisandro Dalcin - x - the solution vector. 30949b94acceSBarry Smith 3095b2002411SLois Curfman McInnes Notes: 30968ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 30978ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 30988ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 30998ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 31008ddd3da0SLois Curfman McInnes 310136851e7fSLois Curfman McInnes Level: beginner 310236851e7fSLois Curfman McInnes 31039b94acceSBarry Smith .keywords: SNES, nonlinear, solve 31049b94acceSBarry Smith 3105c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 31069b94acceSBarry Smith @*/ 31077087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 31089b94acceSBarry Smith { 3109dfbe8321SBarry Smith PetscErrorCode ierr; 3110ace3abfcSBarry Smith PetscBool flg; 3111eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3112eabae89aSBarry Smith PetscViewer viewer; 3113efd51863SBarry Smith PetscInt grid; 3114a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3115052efed2SBarry Smith 31163a40ed3dSBarry Smith PetscFunctionBegin; 31170700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3118a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3119a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 31200700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 312185385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 312285385478SLisandro Dalcin 3123a69afd8bSBarry Smith if (!x && snes->dm) { 3124a69afd8bSBarry Smith ierr = DMCreateGlobalVector(snes->dm,&xcreated);CHKERRQ(ierr); 3125a69afd8bSBarry Smith x = xcreated; 3126a69afd8bSBarry Smith } 3127a69afd8bSBarry Smith 3128a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3129efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3130efd51863SBarry Smith 313185385478SLisandro Dalcin /* set solution vector */ 3132efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 31336bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 313485385478SLisandro Dalcin snes->vec_sol = x; 313585385478SLisandro Dalcin /* set afine vector if provided */ 313685385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 31376bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 313885385478SLisandro Dalcin snes->vec_rhs = b; 313985385478SLisandro Dalcin 314070e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 31413f149594SLisandro Dalcin 31427eee914bSBarry Smith if (!grid) { 31437eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3144d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3145dd568438SSatish Balay } else if (snes->dm) { 3146dd568438SSatish Balay PetscBool ig; 3147dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3148dd568438SSatish Balay if (ig) { 31497eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 31507eee914bSBarry Smith } 3151d25893d9SBarry Smith } 3152dd568438SSatish Balay } 3153d25893d9SBarry Smith 3154abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 315550ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3156d5e45103SBarry Smith 31573f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 31584936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 315985385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 31604936397dSBarry Smith if (snes->domainerror){ 31614936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 31624936397dSBarry Smith snes->domainerror = PETSC_FALSE; 31634936397dSBarry Smith } 316417186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 31653f149594SLisandro Dalcin 31667adad957SLisandro Dalcin ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 3167eabae89aSBarry Smith if (flg && !PetscPreLoadingOn) { 31687adad957SLisandro Dalcin ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 3169eabae89aSBarry Smith ierr = SNESView(snes,viewer);CHKERRQ(ierr); 31706bf464f9SBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 3171eabae89aSBarry Smith } 3172eabae89aSBarry Smith 317390d69ab7SBarry Smith flg = PETSC_FALSE; 3174acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3175da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 31765968eb51SBarry Smith if (snes->printreason) { 3177a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 31785968eb51SBarry Smith if (snes->reason > 0) { 3179a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 31805968eb51SBarry Smith } else { 3181a8248277SBarry Smith ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);CHKERRQ(ierr); 31825968eb51SBarry Smith } 3183a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 31845968eb51SBarry Smith } 31855968eb51SBarry Smith 31868501fc72SJed Brown flg = PETSC_FALSE; 31878501fc72SJed Brown ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 31888501fc72SJed Brown if (flg) { 31898501fc72SJed Brown PetscViewer viewer; 31908501fc72SJed Brown ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 31918501fc72SJed Brown ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 31928501fc72SJed Brown ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 31938501fc72SJed Brown ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 31948501fc72SJed Brown ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 31958501fc72SJed Brown } 31968501fc72SJed Brown 3197e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3198efd51863SBarry Smith if (grid < snes->gridsequence) { 3199efd51863SBarry Smith DM fine; 3200efd51863SBarry Smith Vec xnew; 3201efd51863SBarry Smith Mat interp; 3202efd51863SBarry Smith 3203efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3204e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3205efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3206efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3207efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3208efd51863SBarry Smith x = xnew; 3209efd51863SBarry Smith 3210efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3211efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3212efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3213a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3214efd51863SBarry Smith } 3215efd51863SBarry Smith } 3216a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 32173a40ed3dSBarry Smith PetscFunctionReturn(0); 32189b94acceSBarry Smith } 32199b94acceSBarry Smith 32209b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 32219b94acceSBarry Smith 32224a2ae208SSatish Balay #undef __FUNCT__ 32234a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 322482bf6240SBarry Smith /*@C 32254b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 32269b94acceSBarry Smith 3227fee21e36SBarry Smith Collective on SNES 3228fee21e36SBarry Smith 3229c7afd0dbSLois Curfman McInnes Input Parameters: 3230c7afd0dbSLois Curfman McInnes + snes - the SNES context 3231454a90a3SBarry Smith - type - a known method 3232c7afd0dbSLois Curfman McInnes 3233c7afd0dbSLois Curfman McInnes Options Database Key: 3234454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3235c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3236ae12b187SLois Curfman McInnes 32379b94acceSBarry Smith Notes: 3238e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 32394b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3240c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 32414b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3242c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 32439b94acceSBarry Smith 3244ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3245ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3246ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3247ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3248ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3249ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3250ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3251ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3252ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3253b0a32e0cSBarry Smith appropriate method. 325436851e7fSLois Curfman McInnes 325536851e7fSLois Curfman McInnes Level: intermediate 3256a703fe33SLois Curfman McInnes 3257454a90a3SBarry Smith .keywords: SNES, set, type 3258435da068SBarry Smith 3259435da068SBarry Smith .seealso: SNESType, SNESCreate() 3260435da068SBarry Smith 32619b94acceSBarry Smith @*/ 32627087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 32639b94acceSBarry Smith { 3264dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3265ace3abfcSBarry Smith PetscBool match; 32663a40ed3dSBarry Smith 32673a40ed3dSBarry Smith PetscFunctionBegin; 32680700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32694482741eSBarry Smith PetscValidCharPointer(type,2); 327082bf6240SBarry Smith 32716831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 32720f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 327392ff6ae8SBarry Smith 32744b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3275e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 327675396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 327775396ef9SLisandro Dalcin if (snes->ops->destroy) { ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); } 327875396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 327975396ef9SLisandro Dalcin snes->ops->setup = 0; 328075396ef9SLisandro Dalcin snes->ops->solve = 0; 328175396ef9SLisandro Dalcin snes->ops->view = 0; 328275396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 328375396ef9SLisandro Dalcin snes->ops->destroy = 0; 328475396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 328575396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3286454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 328703bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 32889fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 32899fb22e1aSBarry Smith if (PetscAMSPublishAll) { 32909fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 32919fb22e1aSBarry Smith } 32929fb22e1aSBarry Smith #endif 32933a40ed3dSBarry Smith PetscFunctionReturn(0); 32949b94acceSBarry Smith } 32959b94acceSBarry Smith 3296a847f771SSatish Balay 32979b94acceSBarry Smith /* --------------------------------------------------------------------- */ 32984a2ae208SSatish Balay #undef __FUNCT__ 32994a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 330052baeb72SSatish Balay /*@ 33019b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3302f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 33039b94acceSBarry Smith 3304fee21e36SBarry Smith Not Collective 3305fee21e36SBarry Smith 330636851e7fSLois Curfman McInnes Level: advanced 330736851e7fSLois Curfman McInnes 33089b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 33099b94acceSBarry Smith 33109b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 33119b94acceSBarry Smith @*/ 33127087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 33139b94acceSBarry Smith { 3314dfbe8321SBarry Smith PetscErrorCode ierr; 331582bf6240SBarry Smith 33163a40ed3dSBarry Smith PetscFunctionBegin; 33171441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 33184c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 33193a40ed3dSBarry Smith PetscFunctionReturn(0); 33209b94acceSBarry Smith } 33219b94acceSBarry Smith 33224a2ae208SSatish Balay #undef __FUNCT__ 33234a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 33249b94acceSBarry Smith /*@C 33259a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 33269b94acceSBarry Smith 3327c7afd0dbSLois Curfman McInnes Not Collective 3328c7afd0dbSLois Curfman McInnes 33299b94acceSBarry Smith Input Parameter: 33304b0e389bSBarry Smith . snes - nonlinear solver context 33319b94acceSBarry Smith 33329b94acceSBarry Smith Output Parameter: 33333a7fca6bSBarry Smith . type - SNES method (a character string) 33349b94acceSBarry Smith 333536851e7fSLois Curfman McInnes Level: intermediate 333636851e7fSLois Curfman McInnes 3337454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 33389b94acceSBarry Smith @*/ 33397087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 33409b94acceSBarry Smith { 33413a40ed3dSBarry Smith PetscFunctionBegin; 33420700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33434482741eSBarry Smith PetscValidPointer(type,2); 33447adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 33453a40ed3dSBarry Smith PetscFunctionReturn(0); 33469b94acceSBarry Smith } 33479b94acceSBarry Smith 33484a2ae208SSatish Balay #undef __FUNCT__ 33494a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 335052baeb72SSatish Balay /*@ 33519b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3352c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 33539b94acceSBarry Smith 3354c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3355c7afd0dbSLois Curfman McInnes 33569b94acceSBarry Smith Input Parameter: 33579b94acceSBarry Smith . snes - the SNES context 33589b94acceSBarry Smith 33599b94acceSBarry Smith Output Parameter: 33609b94acceSBarry Smith . x - the solution 33619b94acceSBarry Smith 336270e92668SMatthew Knepley Level: intermediate 336336851e7fSLois Curfman McInnes 33649b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 33659b94acceSBarry Smith 336685385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 33679b94acceSBarry Smith @*/ 33687087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 33699b94acceSBarry Smith { 33703a40ed3dSBarry Smith PetscFunctionBegin; 33710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33724482741eSBarry Smith PetscValidPointer(x,2); 337385385478SLisandro Dalcin *x = snes->vec_sol; 337470e92668SMatthew Knepley PetscFunctionReturn(0); 337570e92668SMatthew Knepley } 337670e92668SMatthew Knepley 337770e92668SMatthew Knepley #undef __FUNCT__ 33784a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 337952baeb72SSatish Balay /*@ 33809b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 33819b94acceSBarry Smith stored. 33829b94acceSBarry Smith 3383c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3384c7afd0dbSLois Curfman McInnes 33859b94acceSBarry Smith Input Parameter: 33869b94acceSBarry Smith . snes - the SNES context 33879b94acceSBarry Smith 33889b94acceSBarry Smith Output Parameter: 33899b94acceSBarry Smith . x - the solution update 33909b94acceSBarry Smith 339136851e7fSLois Curfman McInnes Level: advanced 339236851e7fSLois Curfman McInnes 33939b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 33949b94acceSBarry Smith 339585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 33969b94acceSBarry Smith @*/ 33977087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 33989b94acceSBarry Smith { 33993a40ed3dSBarry Smith PetscFunctionBegin; 34000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34014482741eSBarry Smith PetscValidPointer(x,2); 340285385478SLisandro Dalcin *x = snes->vec_sol_update; 34033a40ed3dSBarry Smith PetscFunctionReturn(0); 34049b94acceSBarry Smith } 34059b94acceSBarry Smith 34064a2ae208SSatish Balay #undef __FUNCT__ 34074a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 34089b94acceSBarry Smith /*@C 34093638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 34109b94acceSBarry Smith 3411a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3412c7afd0dbSLois Curfman McInnes 34139b94acceSBarry Smith Input Parameter: 34149b94acceSBarry Smith . snes - the SNES context 34159b94acceSBarry Smith 34169b94acceSBarry Smith Output Parameter: 34177bf4e008SBarry Smith + r - the function (or PETSC_NULL) 341870e92668SMatthew Knepley . func - the function (or PETSC_NULL) 341970e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 34209b94acceSBarry Smith 342136851e7fSLois Curfman McInnes Level: advanced 342236851e7fSLois Curfman McInnes 3423a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 34249b94acceSBarry Smith 34254b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 34269b94acceSBarry Smith @*/ 34277087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 34289b94acceSBarry Smith { 3429a63bb30eSJed Brown PetscErrorCode ierr; 3430a63bb30eSJed Brown 34313a40ed3dSBarry Smith PetscFunctionBegin; 34320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3433a63bb30eSJed Brown if (r) { 3434a63bb30eSJed Brown if (!snes->vec_func) { 3435a63bb30eSJed Brown if (snes->vec_rhs) { 3436a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3437a63bb30eSJed Brown } else if (snes->vec_sol) { 3438a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3439a63bb30eSJed Brown } else if (snes->dm) { 3440a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3441a63bb30eSJed Brown } 3442a63bb30eSJed Brown } 3443a63bb30eSJed Brown *r = snes->vec_func; 3444a63bb30eSJed Brown } 3445e7788613SBarry Smith if (func) *func = snes->ops->computefunction; 344670e92668SMatthew Knepley if (ctx) *ctx = snes->funP; 34473a40ed3dSBarry Smith PetscFunctionReturn(0); 34489b94acceSBarry Smith } 34499b94acceSBarry Smith 3450c79ef259SPeter Brune /*@C 3451c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3452c79ef259SPeter Brune 3453c79ef259SPeter Brune Input Parameter: 3454c79ef259SPeter Brune . snes - the SNES context 3455c79ef259SPeter Brune 3456c79ef259SPeter Brune Output Parameter: 3457c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3458c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3459c79ef259SPeter Brune 3460c79ef259SPeter Brune Level: advanced 3461c79ef259SPeter Brune 3462c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3463c79ef259SPeter Brune 3464c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3465c79ef259SPeter Brune @*/ 3466c79ef259SPeter Brune 34674a2ae208SSatish Balay #undef __FUNCT__ 3468646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3469646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3470646217ecSPeter Brune { 3471646217ecSPeter Brune PetscFunctionBegin; 3472646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3473646217ecSPeter Brune if (func) *func = snes->ops->computegs; 3474646217ecSPeter Brune if (ctx) *ctx = snes->funP; 3475646217ecSPeter Brune PetscFunctionReturn(0); 3476646217ecSPeter Brune } 3477646217ecSPeter Brune 34784a2ae208SSatish Balay #undef __FUNCT__ 34794a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 34803c7409f5SSatish Balay /*@C 34813c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3482d850072dSLois Curfman McInnes SNES options in the database. 34833c7409f5SSatish Balay 34843f9fe445SBarry Smith Logically Collective on SNES 3485fee21e36SBarry Smith 3486c7afd0dbSLois Curfman McInnes Input Parameter: 3487c7afd0dbSLois Curfman McInnes + snes - the SNES context 3488c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3489c7afd0dbSLois Curfman McInnes 3490d850072dSLois Curfman McInnes Notes: 3491a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3492c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3493d850072dSLois Curfman McInnes 349436851e7fSLois Curfman McInnes Level: advanced 349536851e7fSLois Curfman McInnes 34963c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3497a86d99e1SLois Curfman McInnes 3498a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 34993c7409f5SSatish Balay @*/ 35007087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 35013c7409f5SSatish Balay { 3502dfbe8321SBarry Smith PetscErrorCode ierr; 35033c7409f5SSatish Balay 35043a40ed3dSBarry Smith PetscFunctionBegin; 35050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3506639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 35071cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 350894b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 35093a40ed3dSBarry Smith PetscFunctionReturn(0); 35103c7409f5SSatish Balay } 35113c7409f5SSatish Balay 35124a2ae208SSatish Balay #undef __FUNCT__ 35134a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 35143c7409f5SSatish Balay /*@C 3515f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3516d850072dSLois Curfman McInnes SNES options in the database. 35173c7409f5SSatish Balay 35183f9fe445SBarry Smith Logically Collective on SNES 3519fee21e36SBarry Smith 3520c7afd0dbSLois Curfman McInnes Input Parameters: 3521c7afd0dbSLois Curfman McInnes + snes - the SNES context 3522c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3523c7afd0dbSLois Curfman McInnes 3524d850072dSLois Curfman McInnes Notes: 3525a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3526c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3527d850072dSLois Curfman McInnes 352836851e7fSLois Curfman McInnes Level: advanced 352936851e7fSLois Curfman McInnes 35303c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3531a86d99e1SLois Curfman McInnes 3532a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 35333c7409f5SSatish Balay @*/ 35347087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 35353c7409f5SSatish Balay { 3536dfbe8321SBarry Smith PetscErrorCode ierr; 35373c7409f5SSatish Balay 35383a40ed3dSBarry Smith PetscFunctionBegin; 35390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3540639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 35411cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 354294b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 35433a40ed3dSBarry Smith PetscFunctionReturn(0); 35443c7409f5SSatish Balay } 35453c7409f5SSatish Balay 35464a2ae208SSatish Balay #undef __FUNCT__ 35474a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 35489ab63eb5SSatish Balay /*@C 35493c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 35503c7409f5SSatish Balay SNES options in the database. 35513c7409f5SSatish Balay 3552c7afd0dbSLois Curfman McInnes Not Collective 3553c7afd0dbSLois Curfman McInnes 35543c7409f5SSatish Balay Input Parameter: 35553c7409f5SSatish Balay . snes - the SNES context 35563c7409f5SSatish Balay 35573c7409f5SSatish Balay Output Parameter: 35583c7409f5SSatish Balay . prefix - pointer to the prefix string used 35593c7409f5SSatish Balay 35604ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 35619ab63eb5SSatish Balay sufficient length to hold the prefix. 35629ab63eb5SSatish Balay 356336851e7fSLois Curfman McInnes Level: advanced 356436851e7fSLois Curfman McInnes 35653c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3566a86d99e1SLois Curfman McInnes 3567a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 35683c7409f5SSatish Balay @*/ 35697087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 35703c7409f5SSatish Balay { 3571dfbe8321SBarry Smith PetscErrorCode ierr; 35723c7409f5SSatish Balay 35733a40ed3dSBarry Smith PetscFunctionBegin; 35740700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3575639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 35763a40ed3dSBarry Smith PetscFunctionReturn(0); 35773c7409f5SSatish Balay } 35783c7409f5SSatish Balay 3579b2002411SLois Curfman McInnes 35804a2ae208SSatish Balay #undef __FUNCT__ 35814a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 35823cea93caSBarry Smith /*@C 35833cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 35843cea93caSBarry Smith 35857f6c08e0SMatthew Knepley Level: advanced 35863cea93caSBarry Smith @*/ 35877087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3588b2002411SLois Curfman McInnes { 3589e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3590dfbe8321SBarry Smith PetscErrorCode ierr; 3591b2002411SLois Curfman McInnes 3592b2002411SLois Curfman McInnes PetscFunctionBegin; 3593b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3594c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3595b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3596b2002411SLois Curfman McInnes } 3597da9b6338SBarry Smith 3598da9b6338SBarry Smith #undef __FUNCT__ 3599da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 36007087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3601da9b6338SBarry Smith { 3602dfbe8321SBarry Smith PetscErrorCode ierr; 360377431f27SBarry Smith PetscInt N,i,j; 3604da9b6338SBarry Smith Vec u,uh,fh; 3605da9b6338SBarry Smith PetscScalar value; 3606da9b6338SBarry Smith PetscReal norm; 3607da9b6338SBarry Smith 3608da9b6338SBarry Smith PetscFunctionBegin; 3609da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3610da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3611da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3612da9b6338SBarry Smith 3613da9b6338SBarry Smith /* currently only works for sequential */ 3614da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3615da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3616da9b6338SBarry Smith for (i=0; i<N; i++) { 3617da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 361877431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3619da9b6338SBarry Smith for (j=-10; j<11; j++) { 3620ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3621da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 36223ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3623da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 362477431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3625da9b6338SBarry Smith value = -value; 3626da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3627da9b6338SBarry Smith } 3628da9b6338SBarry Smith } 36296bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 36306bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3631da9b6338SBarry Smith PetscFunctionReturn(0); 3632da9b6338SBarry Smith } 363371f87433Sdalcinl 363471f87433Sdalcinl #undef __FUNCT__ 3635fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 363671f87433Sdalcinl /*@ 3637fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 363871f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 363971f87433Sdalcinl Newton method. 364071f87433Sdalcinl 36413f9fe445SBarry Smith Logically Collective on SNES 364271f87433Sdalcinl 364371f87433Sdalcinl Input Parameters: 364471f87433Sdalcinl + snes - SNES context 364571f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 364671f87433Sdalcinl 364764ba62caSBarry Smith Options Database: 364864ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 364964ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 365064ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 365164ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 365264ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 365364ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 365464ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 365564ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 365664ba62caSBarry Smith 365771f87433Sdalcinl Notes: 365871f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 365971f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 366071f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 366171f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 366271f87433Sdalcinl solver. 366371f87433Sdalcinl 366471f87433Sdalcinl Level: advanced 366571f87433Sdalcinl 366671f87433Sdalcinl Reference: 366771f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 366871f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 366971f87433Sdalcinl 367071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 367171f87433Sdalcinl 3672fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 367371f87433Sdalcinl @*/ 36747087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 367571f87433Sdalcinl { 367671f87433Sdalcinl PetscFunctionBegin; 36770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3678acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 367971f87433Sdalcinl snes->ksp_ewconv = flag; 368071f87433Sdalcinl PetscFunctionReturn(0); 368171f87433Sdalcinl } 368271f87433Sdalcinl 368371f87433Sdalcinl #undef __FUNCT__ 3684fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 368571f87433Sdalcinl /*@ 3686fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 368771f87433Sdalcinl for computing relative tolerance for linear solvers within an 368871f87433Sdalcinl inexact Newton method. 368971f87433Sdalcinl 369071f87433Sdalcinl Not Collective 369171f87433Sdalcinl 369271f87433Sdalcinl Input Parameter: 369371f87433Sdalcinl . snes - SNES context 369471f87433Sdalcinl 369571f87433Sdalcinl Output Parameter: 369671f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 369771f87433Sdalcinl 369871f87433Sdalcinl Notes: 369971f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 370071f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 370171f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 370271f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 370371f87433Sdalcinl solver. 370471f87433Sdalcinl 370571f87433Sdalcinl Level: advanced 370671f87433Sdalcinl 370771f87433Sdalcinl Reference: 370871f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 370971f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 371071f87433Sdalcinl 371171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 371271f87433Sdalcinl 3713fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 371471f87433Sdalcinl @*/ 37157087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 371671f87433Sdalcinl { 371771f87433Sdalcinl PetscFunctionBegin; 37180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 371971f87433Sdalcinl PetscValidPointer(flag,2); 372071f87433Sdalcinl *flag = snes->ksp_ewconv; 372171f87433Sdalcinl PetscFunctionReturn(0); 372271f87433Sdalcinl } 372371f87433Sdalcinl 372471f87433Sdalcinl #undef __FUNCT__ 3725fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 372671f87433Sdalcinl /*@ 3727fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 372871f87433Sdalcinl convergence criteria for the linear solvers within an inexact 372971f87433Sdalcinl Newton method. 373071f87433Sdalcinl 37313f9fe445SBarry Smith Logically Collective on SNES 373271f87433Sdalcinl 373371f87433Sdalcinl Input Parameters: 373471f87433Sdalcinl + snes - SNES context 373571f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 373671f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 373771f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 373871f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 373971f87433Sdalcinl (0 <= gamma2 <= 1) 374071f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 374171f87433Sdalcinl . alpha2 - power for safeguard 374271f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 374371f87433Sdalcinl 374471f87433Sdalcinl Note: 374571f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 374671f87433Sdalcinl 374771f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 374871f87433Sdalcinl 374971f87433Sdalcinl Level: advanced 375071f87433Sdalcinl 375171f87433Sdalcinl Reference: 375271f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 375371f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 375471f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 375571f87433Sdalcinl 375671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 375771f87433Sdalcinl 3758fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 375971f87433Sdalcinl @*/ 37607087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 376171f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 376271f87433Sdalcinl { 3763fa9f3622SBarry Smith SNESKSPEW *kctx; 376471f87433Sdalcinl PetscFunctionBegin; 37650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3766fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3767e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 3768c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 3769c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 3770c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 3771c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 3772c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 3773c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 3774c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 377571f87433Sdalcinl 377671f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 377771f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 377871f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 377971f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 378071f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 378171f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 378271f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 378371f87433Sdalcinl 378471f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 3785e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 378671f87433Sdalcinl } 378771f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 3788e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 378971f87433Sdalcinl } 379071f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 3791e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 379271f87433Sdalcinl } 379371f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 3794e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 379571f87433Sdalcinl } 379671f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 3797e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 379871f87433Sdalcinl } 379971f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 3800e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 380171f87433Sdalcinl } 380271f87433Sdalcinl PetscFunctionReturn(0); 380371f87433Sdalcinl } 380471f87433Sdalcinl 380571f87433Sdalcinl #undef __FUNCT__ 3806fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 380771f87433Sdalcinl /*@ 3808fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 380971f87433Sdalcinl convergence criteria for the linear solvers within an inexact 381071f87433Sdalcinl Newton method. 381171f87433Sdalcinl 381271f87433Sdalcinl Not Collective 381371f87433Sdalcinl 381471f87433Sdalcinl Input Parameters: 381571f87433Sdalcinl snes - SNES context 381671f87433Sdalcinl 381771f87433Sdalcinl Output Parameters: 381871f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 381971f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 382071f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 382171f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 382271f87433Sdalcinl (0 <= gamma2 <= 1) 382371f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 382471f87433Sdalcinl . alpha2 - power for safeguard 382571f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 382671f87433Sdalcinl 382771f87433Sdalcinl Level: advanced 382871f87433Sdalcinl 382971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 383071f87433Sdalcinl 3831fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 383271f87433Sdalcinl @*/ 38337087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 383471f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 383571f87433Sdalcinl { 3836fa9f3622SBarry Smith SNESKSPEW *kctx; 383771f87433Sdalcinl PetscFunctionBegin; 38380700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3839fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 3840e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 384171f87433Sdalcinl if(version) *version = kctx->version; 384271f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 384371f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 384471f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 384571f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 384671f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 384771f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 384871f87433Sdalcinl PetscFunctionReturn(0); 384971f87433Sdalcinl } 385071f87433Sdalcinl 385171f87433Sdalcinl #undef __FUNCT__ 3852fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 3853fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 385471f87433Sdalcinl { 385571f87433Sdalcinl PetscErrorCode ierr; 3856fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 385771f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 385871f87433Sdalcinl 385971f87433Sdalcinl PetscFunctionBegin; 3860e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 386171f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 386271f87433Sdalcinl rtol = kctx->rtol_0; 386371f87433Sdalcinl } else { 386471f87433Sdalcinl if (kctx->version == 1) { 386571f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 386671f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 386771f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 386871f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 386971f87433Sdalcinl } else if (kctx->version == 2) { 387071f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 387171f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 387271f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 387371f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 387471f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 387571f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 387671f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 387771f87433Sdalcinl stol = PetscMax(rtol,stol); 387871f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 387971f87433Sdalcinl /* safeguard: avoid oversolving */ 388071f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 388171f87433Sdalcinl stol = PetscMax(rtol,stol); 388271f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 3883e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 388471f87433Sdalcinl } 388571f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 388671f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 388771f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 388871f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 388971f87433Sdalcinl PetscFunctionReturn(0); 389071f87433Sdalcinl } 389171f87433Sdalcinl 389271f87433Sdalcinl #undef __FUNCT__ 3893fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 3894fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 389571f87433Sdalcinl { 389671f87433Sdalcinl PetscErrorCode ierr; 3897fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 389871f87433Sdalcinl PCSide pcside; 389971f87433Sdalcinl Vec lres; 390071f87433Sdalcinl 390171f87433Sdalcinl PetscFunctionBegin; 3902e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 390371f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 390471f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 390571f87433Sdalcinl if (kctx->version == 1) { 3906b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 390771f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 390871f87433Sdalcinl /* KSP residual is true linear residual */ 390971f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 391071f87433Sdalcinl } else { 391171f87433Sdalcinl /* KSP residual is preconditioned residual */ 391271f87433Sdalcinl /* compute true linear residual norm */ 391371f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 391471f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 391571f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 391671f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 39176bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 391871f87433Sdalcinl } 391971f87433Sdalcinl } 392071f87433Sdalcinl PetscFunctionReturn(0); 392171f87433Sdalcinl } 392271f87433Sdalcinl 392371f87433Sdalcinl #undef __FUNCT__ 392471f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 392571f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 392671f87433Sdalcinl { 392771f87433Sdalcinl PetscErrorCode ierr; 392871f87433Sdalcinl 392971f87433Sdalcinl PetscFunctionBegin; 3930fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 393171f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 3932fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 393371f87433Sdalcinl PetscFunctionReturn(0); 393471f87433Sdalcinl } 39356c699258SBarry Smith 39366c699258SBarry Smith #undef __FUNCT__ 39376c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 39386c699258SBarry Smith /*@ 39396c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 39406c699258SBarry Smith 39413f9fe445SBarry Smith Logically Collective on SNES 39426c699258SBarry Smith 39436c699258SBarry Smith Input Parameters: 39446c699258SBarry Smith + snes - the preconditioner context 39456c699258SBarry Smith - dm - the dm 39466c699258SBarry Smith 39476c699258SBarry Smith Level: intermediate 39486c699258SBarry Smith 39496c699258SBarry Smith 39506c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 39516c699258SBarry Smith @*/ 39527087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 39536c699258SBarry Smith { 39546c699258SBarry Smith PetscErrorCode ierr; 3955345fed2cSBarry Smith KSP ksp; 39566c699258SBarry Smith 39576c699258SBarry Smith PetscFunctionBegin; 39580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3959d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 39606bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 39616c699258SBarry Smith snes->dm = dm; 3962345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 3963345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 3964f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 39652c155ee1SBarry Smith if (snes->pc) { 39662c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 39672c155ee1SBarry Smith } 39686c699258SBarry Smith PetscFunctionReturn(0); 39696c699258SBarry Smith } 39706c699258SBarry Smith 39716c699258SBarry Smith #undef __FUNCT__ 39726c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 39736c699258SBarry Smith /*@ 39746c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 39756c699258SBarry Smith 39763f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 39776c699258SBarry Smith 39786c699258SBarry Smith Input Parameter: 39796c699258SBarry Smith . snes - the preconditioner context 39806c699258SBarry Smith 39816c699258SBarry Smith Output Parameter: 39826c699258SBarry Smith . dm - the dm 39836c699258SBarry Smith 39846c699258SBarry Smith Level: intermediate 39856c699258SBarry Smith 39866c699258SBarry Smith 39876c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 39886c699258SBarry Smith @*/ 39897087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 39906c699258SBarry Smith { 39916c699258SBarry Smith PetscFunctionBegin; 39920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39936c699258SBarry Smith *dm = snes->dm; 39946c699258SBarry Smith PetscFunctionReturn(0); 39956c699258SBarry Smith } 39960807856dSBarry Smith 399731823bd8SMatthew G Knepley #undef __FUNCT__ 399831823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 399931823bd8SMatthew G Knepley /*@ 4000fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 400131823bd8SMatthew G Knepley 400231823bd8SMatthew G Knepley Collective on SNES 400331823bd8SMatthew G Knepley 400431823bd8SMatthew G Knepley Input Parameters: 400531823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 400631823bd8SMatthew G Knepley - pc - the preconditioner object 400731823bd8SMatthew G Knepley 400831823bd8SMatthew G Knepley Notes: 400931823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 401031823bd8SMatthew G Knepley to configure it using the API). 401131823bd8SMatthew G Knepley 401231823bd8SMatthew G Knepley Level: developer 401331823bd8SMatthew G Knepley 401431823bd8SMatthew G Knepley .keywords: SNES, set, precondition 401531823bd8SMatthew G Knepley .seealso: SNESGetPC() 401631823bd8SMatthew G Knepley @*/ 401731823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 401831823bd8SMatthew G Knepley { 401931823bd8SMatthew G Knepley PetscErrorCode ierr; 402031823bd8SMatthew G Knepley 402131823bd8SMatthew G Knepley PetscFunctionBegin; 402231823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 402331823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 402431823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 402531823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4026bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 402731823bd8SMatthew G Knepley snes->pc = pc; 402831823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 402931823bd8SMatthew G Knepley PetscFunctionReturn(0); 403031823bd8SMatthew G Knepley } 403131823bd8SMatthew G Knepley 403231823bd8SMatthew G Knepley #undef __FUNCT__ 403331823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 403431823bd8SMatthew G Knepley /*@ 4035fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 403631823bd8SMatthew G Knepley 403731823bd8SMatthew G Knepley Not Collective 403831823bd8SMatthew G Knepley 403931823bd8SMatthew G Knepley Input Parameter: 404031823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 404131823bd8SMatthew G Knepley 404231823bd8SMatthew G Knepley Output Parameter: 404331823bd8SMatthew G Knepley . pc - preconditioner context 404431823bd8SMatthew G Knepley 404531823bd8SMatthew G Knepley Level: developer 404631823bd8SMatthew G Knepley 404731823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 404831823bd8SMatthew G Knepley .seealso: SNESSetPC() 404931823bd8SMatthew G Knepley @*/ 405031823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 405131823bd8SMatthew G Knepley { 405231823bd8SMatthew G Knepley PetscErrorCode ierr; 405331823bd8SMatthew G Knepley 405431823bd8SMatthew G Knepley PetscFunctionBegin; 405531823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 405631823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 405731823bd8SMatthew G Knepley if (!snes->pc) { 405831823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr); 40594a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr); 406031823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 406131823bd8SMatthew G Knepley } 406231823bd8SMatthew G Knepley *pc = snes->pc; 406331823bd8SMatthew G Knepley PetscFunctionReturn(0); 406431823bd8SMatthew G Knepley } 406531823bd8SMatthew G Knepley 406669b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4067c6db04a5SJed Brown #include <mex.h> 406869b4f73cSBarry Smith 40698f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 40708f6e6473SBarry Smith 40710807856dSBarry Smith #undef __FUNCT__ 40720807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 40730807856dSBarry Smith /* 40740807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 40750807856dSBarry Smith SNESSetFunctionMatlab(). 40760807856dSBarry Smith 40770807856dSBarry Smith Collective on SNES 40780807856dSBarry Smith 40790807856dSBarry Smith Input Parameters: 40800807856dSBarry Smith + snes - the SNES context 40810807856dSBarry Smith - x - input vector 40820807856dSBarry Smith 40830807856dSBarry Smith Output Parameter: 40840807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 40850807856dSBarry Smith 40860807856dSBarry Smith Notes: 40870807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 40880807856dSBarry Smith implementations, so most users would not generally call this routine 40890807856dSBarry Smith themselves. 40900807856dSBarry Smith 40910807856dSBarry Smith Level: developer 40920807856dSBarry Smith 40930807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 40940807856dSBarry Smith 40950807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 409661b2408cSBarry Smith */ 40977087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 40980807856dSBarry Smith { 4099e650e774SBarry Smith PetscErrorCode ierr; 41008f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 41018f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 41028f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 410391621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4104e650e774SBarry Smith 41050807856dSBarry Smith PetscFunctionBegin; 41060807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41070807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 41080807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 41090807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 41100807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 41110807856dSBarry Smith 41120807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4113e650e774SBarry Smith 411491621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4115e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4116e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 411791621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 411891621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 411991621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 41208f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 41218f6e6473SBarry Smith prhs[4] = sctx->ctx; 4122b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4123e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4124e650e774SBarry Smith mxDestroyArray(prhs[0]); 4125e650e774SBarry Smith mxDestroyArray(prhs[1]); 4126e650e774SBarry Smith mxDestroyArray(prhs[2]); 41278f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4128e650e774SBarry Smith mxDestroyArray(plhs[0]); 41290807856dSBarry Smith PetscFunctionReturn(0); 41300807856dSBarry Smith } 41310807856dSBarry Smith 41320807856dSBarry Smith 41330807856dSBarry Smith #undef __FUNCT__ 41340807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 413561b2408cSBarry Smith /* 41360807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 41370807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4138e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 41390807856dSBarry Smith 41400807856dSBarry Smith Logically Collective on SNES 41410807856dSBarry Smith 41420807856dSBarry Smith Input Parameters: 41430807856dSBarry Smith + snes - the SNES context 41440807856dSBarry Smith . r - vector to store function value 41450807856dSBarry Smith - func - function evaluation routine 41460807856dSBarry Smith 41470807856dSBarry Smith Calling sequence of func: 414861b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 41490807856dSBarry Smith 41500807856dSBarry Smith 41510807856dSBarry Smith Notes: 41520807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 41530807856dSBarry Smith $ f'(x) x = -f(x), 41540807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 41550807856dSBarry Smith 41560807856dSBarry Smith Level: beginner 41570807856dSBarry Smith 41580807856dSBarry Smith .keywords: SNES, nonlinear, set, function 41590807856dSBarry Smith 41600807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 416161b2408cSBarry Smith */ 41627087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 41630807856dSBarry Smith { 41640807856dSBarry Smith PetscErrorCode ierr; 41658f6e6473SBarry Smith SNESMatlabContext *sctx; 41660807856dSBarry Smith 41670807856dSBarry Smith PetscFunctionBegin; 41688f6e6473SBarry Smith /* currently sctx is memory bleed */ 41698f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 41708f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 41718f6e6473SBarry Smith /* 41728f6e6473SBarry Smith This should work, but it doesn't 41738f6e6473SBarry Smith sctx->ctx = ctx; 41748f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 41758f6e6473SBarry Smith */ 41768f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 41778f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 41780807856dSBarry Smith PetscFunctionReturn(0); 41790807856dSBarry Smith } 418069b4f73cSBarry Smith 418161b2408cSBarry Smith #undef __FUNCT__ 418261b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 418361b2408cSBarry Smith /* 418461b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 418561b2408cSBarry Smith SNESSetJacobianMatlab(). 418661b2408cSBarry Smith 418761b2408cSBarry Smith Collective on SNES 418861b2408cSBarry Smith 418961b2408cSBarry Smith Input Parameters: 419061b2408cSBarry Smith + snes - the SNES context 419161b2408cSBarry Smith . x - input vector 419261b2408cSBarry Smith . A, B - the matrices 419361b2408cSBarry Smith - ctx - user context 419461b2408cSBarry Smith 419561b2408cSBarry Smith Output Parameter: 419661b2408cSBarry Smith . flag - structure of the matrix 419761b2408cSBarry Smith 419861b2408cSBarry Smith Level: developer 419961b2408cSBarry Smith 420061b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 420161b2408cSBarry Smith 420261b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 420361b2408cSBarry Smith @*/ 42047087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 420561b2408cSBarry Smith { 420661b2408cSBarry Smith PetscErrorCode ierr; 420761b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 420861b2408cSBarry Smith int nlhs = 2,nrhs = 6; 420961b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 421061b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 421161b2408cSBarry Smith 421261b2408cSBarry Smith PetscFunctionBegin; 421361b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 421461b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 421561b2408cSBarry Smith 421661b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 421761b2408cSBarry Smith 421861b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 421961b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 422061b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 422161b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 422261b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 422361b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 422461b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 422561b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 422661b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 422761b2408cSBarry Smith prhs[5] = sctx->ctx; 4228b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 422961b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 423061b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 423161b2408cSBarry Smith mxDestroyArray(prhs[0]); 423261b2408cSBarry Smith mxDestroyArray(prhs[1]); 423361b2408cSBarry Smith mxDestroyArray(prhs[2]); 423461b2408cSBarry Smith mxDestroyArray(prhs[3]); 423561b2408cSBarry Smith mxDestroyArray(prhs[4]); 423661b2408cSBarry Smith mxDestroyArray(plhs[0]); 423761b2408cSBarry Smith mxDestroyArray(plhs[1]); 423861b2408cSBarry Smith PetscFunctionReturn(0); 423961b2408cSBarry Smith } 424061b2408cSBarry Smith 424161b2408cSBarry Smith 424261b2408cSBarry Smith #undef __FUNCT__ 424361b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 424461b2408cSBarry Smith /* 424561b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 424661b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4247e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 424861b2408cSBarry Smith 424961b2408cSBarry Smith Logically Collective on SNES 425061b2408cSBarry Smith 425161b2408cSBarry Smith Input Parameters: 425261b2408cSBarry Smith + snes - the SNES context 425361b2408cSBarry Smith . A,B - Jacobian matrices 425461b2408cSBarry Smith . func - function evaluation routine 425561b2408cSBarry Smith - ctx - user context 425661b2408cSBarry Smith 425761b2408cSBarry Smith Calling sequence of func: 425861b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 425961b2408cSBarry Smith 426061b2408cSBarry Smith 426161b2408cSBarry Smith Level: developer 426261b2408cSBarry Smith 426361b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 426461b2408cSBarry Smith 426561b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 426661b2408cSBarry Smith */ 42677087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 426861b2408cSBarry Smith { 426961b2408cSBarry Smith PetscErrorCode ierr; 427061b2408cSBarry Smith SNESMatlabContext *sctx; 427161b2408cSBarry Smith 427261b2408cSBarry Smith PetscFunctionBegin; 427361b2408cSBarry Smith /* currently sctx is memory bleed */ 427461b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 427561b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 427661b2408cSBarry Smith /* 427761b2408cSBarry Smith This should work, but it doesn't 427861b2408cSBarry Smith sctx->ctx = ctx; 427961b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 428061b2408cSBarry Smith */ 428161b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 428261b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 428361b2408cSBarry Smith PetscFunctionReturn(0); 428461b2408cSBarry Smith } 428569b4f73cSBarry Smith 4286f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4287f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4288f9eb7ae2SShri Abhyankar /* 4289f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4290f9eb7ae2SShri Abhyankar 4291f9eb7ae2SShri Abhyankar Collective on SNES 4292f9eb7ae2SShri Abhyankar 4293f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4294f9eb7ae2SShri Abhyankar @*/ 42957087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4296f9eb7ae2SShri Abhyankar { 4297f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 429848f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4299f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4300f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4301f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4302f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4303f9eb7ae2SShri Abhyankar 4304f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4305f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4306f9eb7ae2SShri Abhyankar 4307f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4308f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4309f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4310f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4311f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4312f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4313f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4314f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4315f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4316f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4317f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4318f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4319f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4320f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4321f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4322f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4323f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4324f9eb7ae2SShri Abhyankar } 4325f9eb7ae2SShri Abhyankar 4326f9eb7ae2SShri Abhyankar 4327f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4328f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4329f9eb7ae2SShri Abhyankar /* 4330e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4331f9eb7ae2SShri Abhyankar 4332f9eb7ae2SShri Abhyankar Level: developer 4333f9eb7ae2SShri Abhyankar 4334f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4335f9eb7ae2SShri Abhyankar 4336f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4337f9eb7ae2SShri Abhyankar */ 43387087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4339f9eb7ae2SShri Abhyankar { 4340f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4341f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4342f9eb7ae2SShri Abhyankar 4343f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4344f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4345f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4346f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4347f9eb7ae2SShri Abhyankar /* 4348f9eb7ae2SShri Abhyankar This should work, but it doesn't 4349f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4350f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4351f9eb7ae2SShri Abhyankar */ 4352f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4353f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4354f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4355f9eb7ae2SShri Abhyankar } 4356f9eb7ae2SShri Abhyankar 435769b4f73cSBarry Smith #endif 4358