19b94acceSBarry Smith 2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h> /*I "petscsnes.h" I*/ 36cab3a1bSJed Brown #include <petscdmshell.h> /*I "petscdmshell.h" I*/ 4a64e098fSPeter Brune #include <petscsys.h> /*I "petscsys.h" I*/ 59b94acceSBarry Smith 6ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 78ba1e511SMatthew Knepley PetscFList SNESList = PETSC_NULL; 88ba1e511SMatthew Knepley 98ba1e511SMatthew Knepley /* Logging support */ 107087cfbeSBarry Smith PetscClassId SNES_CLASSID; 11f1c6b773SPeter Brune PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval; 12a09944afSBarry Smith 13a09944afSBarry Smith #undef __FUNCT__ 14e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged" 15e113a28aSBarry Smith /*@ 16e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 17e113a28aSBarry Smith 183f9fe445SBarry Smith Logically Collective on SNES 19e113a28aSBarry Smith 20e113a28aSBarry Smith Input Parameters: 21e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 22e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 23e113a28aSBarry Smith 24e113a28aSBarry Smith Options database keys: 25e113a28aSBarry Smith . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false) 26e113a28aSBarry Smith 27e113a28aSBarry Smith Level: intermediate 28e113a28aSBarry Smith 29e113a28aSBarry Smith Notes: 30e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 31e113a28aSBarry Smith to determine if it has converged. 32e113a28aSBarry Smith 33e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 34e113a28aSBarry Smith 35e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 36e113a28aSBarry Smith @*/ 377087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 38e113a28aSBarry Smith { 39e113a28aSBarry Smith PetscFunctionBegin; 40e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 41acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 42e113a28aSBarry Smith snes->errorifnotconverged = flg; 43dd568438SSatish Balay 44e113a28aSBarry Smith PetscFunctionReturn(0); 45e113a28aSBarry Smith } 46e113a28aSBarry Smith 47e113a28aSBarry Smith #undef __FUNCT__ 48e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged" 49e113a28aSBarry Smith /*@ 50e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 51e113a28aSBarry Smith 52e113a28aSBarry Smith Not Collective 53e113a28aSBarry Smith 54e113a28aSBarry Smith Input Parameter: 55e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 56e113a28aSBarry Smith 57e113a28aSBarry Smith Output Parameter: 58e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 59e113a28aSBarry Smith 60e113a28aSBarry Smith Level: intermediate 61e113a28aSBarry Smith 62e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero 63e113a28aSBarry Smith 64e113a28aSBarry Smith .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged() 65e113a28aSBarry Smith @*/ 667087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 67e113a28aSBarry Smith { 68e113a28aSBarry Smith PetscFunctionBegin; 69e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 70e113a28aSBarry Smith PetscValidPointer(flag,2); 71e113a28aSBarry Smith *flag = snes->errorifnotconverged; 72e113a28aSBarry Smith PetscFunctionReturn(0); 73e113a28aSBarry Smith } 74e113a28aSBarry Smith 75e113a28aSBarry Smith #undef __FUNCT__ 764936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError" 77e725d27bSBarry Smith /*@ 784936397dSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not 794936397dSBarry Smith in the functions domain. For example, negative pressure. 804936397dSBarry Smith 813f9fe445SBarry Smith Logically Collective on SNES 824936397dSBarry Smith 834936397dSBarry Smith Input Parameters: 846a388c36SPeter Brune . snes - the SNES context 854936397dSBarry Smith 8628529972SSatish Balay Level: advanced 874936397dSBarry Smith 884936397dSBarry Smith .keywords: SNES, view 894936397dSBarry Smith 904936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction() 914936397dSBarry Smith @*/ 927087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 934936397dSBarry Smith { 944936397dSBarry Smith PetscFunctionBegin; 950700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 964936397dSBarry Smith snes->domainerror = PETSC_TRUE; 974936397dSBarry Smith PetscFunctionReturn(0); 984936397dSBarry Smith } 994936397dSBarry Smith 1006a388c36SPeter Brune 1016a388c36SPeter Brune #undef __FUNCT__ 1026a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError" 1036a388c36SPeter Brune /*@ 104c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 1056a388c36SPeter Brune 1066a388c36SPeter Brune Logically Collective on SNES 1076a388c36SPeter Brune 1086a388c36SPeter Brune Input Parameters: 1096a388c36SPeter Brune . snes - the SNES context 1106a388c36SPeter Brune 1116a388c36SPeter Brune Output Parameters: 1126a388c36SPeter Brune . domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 1136a388c36SPeter Brune 1146a388c36SPeter Brune Level: advanced 1156a388c36SPeter Brune 1166a388c36SPeter Brune .keywords: SNES, view 1176a388c36SPeter Brune 1186a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction() 1196a388c36SPeter Brune @*/ 1206a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 1216a388c36SPeter Brune { 1226a388c36SPeter Brune PetscFunctionBegin; 1236a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1246a388c36SPeter Brune PetscValidPointer(domainerror, 2); 1256a388c36SPeter Brune *domainerror = snes->domainerror; 1266a388c36SPeter Brune PetscFunctionReturn(0); 1276a388c36SPeter Brune } 1286a388c36SPeter Brune 1296a388c36SPeter Brune 1304936397dSBarry Smith #undef __FUNCT__ 1314a2ae208SSatish Balay #define __FUNCT__ "SNESView" 1327e2c5f70SBarry Smith /*@C 1339b94acceSBarry Smith SNESView - Prints the SNES data structure. 1349b94acceSBarry Smith 1354c49b128SBarry Smith Collective on SNES 136fee21e36SBarry Smith 137c7afd0dbSLois Curfman McInnes Input Parameters: 138c7afd0dbSLois Curfman McInnes + SNES - the SNES context 139c7afd0dbSLois Curfman McInnes - viewer - visualization context 140c7afd0dbSLois Curfman McInnes 1419b94acceSBarry Smith Options Database Key: 142c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 1439b94acceSBarry Smith 1449b94acceSBarry Smith Notes: 1459b94acceSBarry Smith The available visualization contexts include 146b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 147b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 148c8a8ba5cSLois Curfman McInnes output where only the first processor opens 149c8a8ba5cSLois Curfman McInnes the file. All other processors send their 150c8a8ba5cSLois Curfman McInnes data to the first processor to print. 1519b94acceSBarry Smith 1523e081fefSLois Curfman McInnes The user can open an alternative visualization context with 153b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 1549b94acceSBarry Smith 15536851e7fSLois Curfman McInnes Level: beginner 15636851e7fSLois Curfman McInnes 1579b94acceSBarry Smith .keywords: SNES, view 1589b94acceSBarry Smith 159b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen() 1609b94acceSBarry Smith @*/ 1617087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 1629b94acceSBarry Smith { 163fa9f3622SBarry Smith SNESKSPEW *kctx; 164dfbe8321SBarry Smith PetscErrorCode ierr; 16594b7f48cSBarry Smith KSP ksp; 1667f1410a3SPeter Brune SNESLineSearch linesearch; 167ace3abfcSBarry Smith PetscBool iascii,isstring; 1689b94acceSBarry Smith 1693a40ed3dSBarry Smith PetscFunctionBegin; 1700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1713050cee2SBarry Smith if (!viewer) { 1727adad957SLisandro Dalcin ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 1733050cee2SBarry Smith } 1740700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 175c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 17674679c65SBarry Smith 177251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 178251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 17932077d6dSBarry Smith if (iascii) { 180317d6ea6SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr); 181e7788613SBarry Smith if (snes->ops->view) { 182b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 183e7788613SBarry Smith ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr); 184b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1850ef38995SBarry Smith } 18677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr); 187a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n", 188c60f73f4SPeter Brune snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr); 18977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr); 19077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr); 191*17fe4bdfSPeter Brune if (snes->gridsequence) { 192*17fe4bdfSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr); 193*17fe4bdfSPeter Brune } 1949b94acceSBarry Smith if (snes->ksp_ewconv) { 195fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 1969b94acceSBarry Smith if (kctx) { 19777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr); 198a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr); 199a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr); 2009b94acceSBarry Smith } 2019b94acceSBarry Smith } 202eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 203eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");CHKERRQ(ierr); 204eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 205eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr); 206eb1f6c34SBarry Smith } 207eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 208eb1f6c34SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");CHKERRQ(ierr); 209eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 21042f4f86dSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr); 211eb1f6c34SBarry Smith } 2120f5bd95cSBarry Smith } else if (isstring) { 213317d6ea6SBarry Smith const char *type; 214454a90a3SBarry Smith ierr = SNESGetType(snes,&type);CHKERRQ(ierr); 215b0a32e0cSBarry Smith ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 21619bcc07fSBarry Smith } 21742f4f86dSBarry Smith if (snes->pc && snes->usespc) { 2184a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2194a0c5b0cSMatthew G Knepley ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr); 2204a0c5b0cSMatthew G Knepley ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2214a0c5b0cSMatthew G Knepley } 2222c155ee1SBarry Smith if (snes->usesksp) { 2232c155ee1SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 224b0a32e0cSBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 22594b7f48cSBarry Smith ierr = KSPView(ksp,viewer);CHKERRQ(ierr); 226b0a32e0cSBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2272c155ee1SBarry Smith } 2287f1410a3SPeter Brune if (snes->linesearch) { 2297f1410a3SPeter Brune ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 2307f1410a3SPeter Brune ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr); 2317f1410a3SPeter Brune ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr); 2327f1410a3SPeter Brune ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 2337f1410a3SPeter Brune } 2343a40ed3dSBarry Smith PetscFunctionReturn(0); 2359b94acceSBarry Smith } 2369b94acceSBarry Smith 23776b2cf59SMatthew Knepley /* 23876b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 23976b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 24076b2cf59SMatthew Knepley */ 24176b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 242a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 2436849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 24476b2cf59SMatthew Knepley 245e74ef692SMatthew Knepley #undef __FUNCT__ 246e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker" 247ac226902SBarry Smith /*@C 24876b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 24976b2cf59SMatthew Knepley 25076b2cf59SMatthew Knepley Not Collective 25176b2cf59SMatthew Knepley 25276b2cf59SMatthew Knepley Input Parameter: 25376b2cf59SMatthew Knepley . snescheck - function that checks for options 25476b2cf59SMatthew Knepley 25576b2cf59SMatthew Knepley Level: developer 25676b2cf59SMatthew Knepley 25776b2cf59SMatthew Knepley .seealso: SNESSetFromOptions() 25876b2cf59SMatthew Knepley @*/ 2597087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 26076b2cf59SMatthew Knepley { 26176b2cf59SMatthew Knepley PetscFunctionBegin; 26276b2cf59SMatthew Knepley if (numberofsetfromoptions >= MAXSETFROMOPTIONS) { 263e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS); 26476b2cf59SMatthew Knepley } 26576b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 26676b2cf59SMatthew Knepley PetscFunctionReturn(0); 26776b2cf59SMatthew Knepley } 26876b2cf59SMatthew Knepley 2697087cfbeSBarry Smith extern PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 270aa3661deSLisandro Dalcin 271aa3661deSLisandro Dalcin #undef __FUNCT__ 272aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private" 273ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 274aa3661deSLisandro Dalcin { 275aa3661deSLisandro Dalcin Mat J; 276aa3661deSLisandro Dalcin KSP ksp; 277aa3661deSLisandro Dalcin PC pc; 278ace3abfcSBarry Smith PetscBool match; 279aa3661deSLisandro Dalcin PetscErrorCode ierr; 280aa3661deSLisandro Dalcin 281aa3661deSLisandro Dalcin PetscFunctionBegin; 2820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 283aa3661deSLisandro Dalcin 28498613b67SLisandro Dalcin if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 28598613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 28698613b67SLisandro Dalcin ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr); 28798613b67SLisandro Dalcin } 28898613b67SLisandro Dalcin 289aa3661deSLisandro Dalcin if (version == 1) { 290aa3661deSLisandro Dalcin ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 29198613b67SLisandro Dalcin ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 2929c6ac3b3SBarry Smith ierr = MatSetFromOptions(J);CHKERRQ(ierr); 293aa3661deSLisandro Dalcin } else if (version == 2) { 294e32f2f54SBarry Smith if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 29582a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 296aa3661deSLisandro Dalcin ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr); 297aa3661deSLisandro Dalcin #else 298e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)"); 299aa3661deSLisandro Dalcin #endif 300a8248277SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2"); 301aa3661deSLisandro Dalcin 302aa3661deSLisandro Dalcin ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr); 303d3462f78SMatthew Knepley if (hasOperator) { 304aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 305aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 306aa3661deSLisandro Dalcin ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr); 307aa3661deSLisandro Dalcin } else { 308aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 309aa3661deSLisandro Dalcin provided preconditioner matrix with the default matrix free version. */ 3106cab3a1bSJed Brown void *functx; 3116cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 3126cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 313aa3661deSLisandro Dalcin /* Force no preconditioner */ 314aa3661deSLisandro Dalcin ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 315aa3661deSLisandro Dalcin ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); 316251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr); 317aa3661deSLisandro Dalcin if (!match) { 318aa3661deSLisandro Dalcin ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr); 319aa3661deSLisandro Dalcin ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); 320aa3661deSLisandro Dalcin } 321aa3661deSLisandro Dalcin } 3226bf464f9SBarry Smith ierr = MatDestroy(&J);CHKERRQ(ierr); 323aa3661deSLisandro Dalcin PetscFunctionReturn(0); 324aa3661deSLisandro Dalcin } 325aa3661deSLisandro Dalcin 3264a2ae208SSatish Balay #undef __FUNCT__ 327dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol" 328dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 329dfe15315SJed Brown { 330dfe15315SJed Brown SNES snes = (SNES)ctx; 331dfe15315SJed Brown PetscErrorCode ierr; 332dfe15315SJed Brown Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse; 333dfe15315SJed Brown 334dfe15315SJed Brown PetscFunctionBegin; 335dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 336dfe15315SJed Brown else { 337dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 338dfe15315SJed Brown Xfine = Xfine_named; 339dfe15315SJed Brown } 340dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 341dfe15315SJed Brown ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 342dfe15315SJed Brown ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 343dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 344dfe15315SJed Brown if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 345dfe15315SJed Brown PetscFunctionReturn(0); 346dfe15315SJed Brown } 347dfe15315SJed Brown 348dfe15315SJed Brown #undef __FUNCT__ 349caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES" 350a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 351a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 352caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx) 353caa4e7f2SJed Brown { 354caa4e7f2SJed Brown SNES snes = (SNES)ctx; 355caa4e7f2SJed Brown PetscErrorCode ierr; 356caa4e7f2SJed Brown Mat Asave = A,Bsave = B; 357dfe15315SJed Brown Vec X,Xnamed = PETSC_NULL; 358dfe15315SJed Brown DM dmsave; 359caa4e7f2SJed Brown 360caa4e7f2SJed Brown PetscFunctionBegin; 361dfe15315SJed Brown dmsave = snes->dm; 362dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 363dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 364dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 365dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 366dfe15315SJed Brown X = Xnamed; 367dfe15315SJed Brown } 368dfe15315SJed Brown ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr); 369caa4e7f2SJed Brown if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time"); 370dfe15315SJed Brown if (Xnamed) { 371dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 372dfe15315SJed Brown } 373dfe15315SJed Brown snes->dm = dmsave; 374caa4e7f2SJed Brown PetscFunctionReturn(0); 375caa4e7f2SJed Brown } 376caa4e7f2SJed Brown 377caa4e7f2SJed Brown #undef __FUNCT__ 3786cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices" 3796cab3a1bSJed Brown /*@ 3806cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 3816cab3a1bSJed Brown 3826cab3a1bSJed Brown Collective 3836cab3a1bSJed Brown 3846cab3a1bSJed Brown Input Arguments: 3856cab3a1bSJed Brown . snes - snes to configure 3866cab3a1bSJed Brown 3876cab3a1bSJed Brown Level: developer 3886cab3a1bSJed Brown 3896cab3a1bSJed Brown .seealso: SNESSetUp() 3906cab3a1bSJed Brown @*/ 3916cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 3926cab3a1bSJed Brown { 3936cab3a1bSJed Brown PetscErrorCode ierr; 3946cab3a1bSJed Brown DM dm; 3956cab3a1bSJed Brown SNESDM sdm; 3966cab3a1bSJed Brown 3976cab3a1bSJed Brown PetscFunctionBegin; 3986cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3996cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 400caa4e7f2SJed Brown if (!sdm->computejacobian) { 40117842b4fSJed Brown SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_PLIB,"SNESDM not improperly configured"); 4026cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 4036cab3a1bSJed Brown Mat J; 4046cab3a1bSJed Brown void *functx; 4056cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4066cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4076cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4086cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4096cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 4106cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 411caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 4126cab3a1bSJed Brown Mat J,B; 4136cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4146cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4156cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4166cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 41706f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 41806f20277SJed Brown ierr = SNESSetJacobian(snes,J,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4196cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4206cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 421caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 4226cab3a1bSJed Brown Mat J,B; 4236cab3a1bSJed Brown J = snes->jacobian; 4246cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4256cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4266cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4276cab3a1bSJed Brown } 428caa4e7f2SJed Brown { 42960a3618bSJed Brown PetscBool flg = PETSC_FALSE; 430caa4e7f2SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr); 431caa4e7f2SJed Brown if (flg) { /* Plan to transition to this model */ 432caa4e7f2SJed Brown KSP ksp; 433caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 434caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 435dfe15315SJed Brown ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 436caa4e7f2SJed Brown } 437caa4e7f2SJed Brown } 4386cab3a1bSJed Brown PetscFunctionReturn(0); 4396cab3a1bSJed Brown } 4406cab3a1bSJed Brown 4416cab3a1bSJed Brown #undef __FUNCT__ 4424a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 4439b94acceSBarry Smith /*@ 44494b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 4459b94acceSBarry Smith 446c7afd0dbSLois Curfman McInnes Collective on SNES 447c7afd0dbSLois Curfman McInnes 4489b94acceSBarry Smith Input Parameter: 4499b94acceSBarry Smith . snes - the SNES context 4509b94acceSBarry Smith 45136851e7fSLois Curfman McInnes Options Database Keys: 452ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 45382738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 45482738288SBarry Smith of the change in the solution between steps 45570441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 456b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 457b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 458b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 4594839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 460ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 461a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 462e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 463b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 4642492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 46582738288SBarry Smith solver; hence iterations will continue until max_it 4661fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 46782738288SBarry Smith of convergence test 468e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 469e8105e01SRichard Katz filename given prints to stdout 470a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 471a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 472a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 473a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 474e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 4755968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 476fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 47782738288SBarry Smith 47882738288SBarry Smith Options Database for Eisenstat-Walker method: 479fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 4804b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 48136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 48236851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 48336851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 48436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 48536851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 48636851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 48782738288SBarry Smith 48811ca99fdSLois Curfman McInnes Notes: 48911ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 4900598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 49183e2fdc7SBarry Smith 49236851e7fSLois Curfman McInnes Level: beginner 49336851e7fSLois Curfman McInnes 4949b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 4959b94acceSBarry Smith 49669ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 4979b94acceSBarry Smith @*/ 4987087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 4999b94acceSBarry Smith { 500872b6db9SPeter Brune PetscBool flg,mf,mf_operator,pcset; 501efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 502aa3661deSLisandro Dalcin MatStructure matflag; 50385385478SLisandro Dalcin const char *deft = SNESLS; 50485385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 50585385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 506e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 507649052a6SBarry Smith PetscViewer monviewer; 50885385478SLisandro Dalcin PetscErrorCode ierr; 509a64e098fSPeter Brune const char *optionsprefix; 5109b94acceSBarry Smith 5113a40ed3dSBarry Smith PetscFunctionBegin; 5120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 513ca161407SBarry Smith 514186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 5153194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 5167adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 517b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 518d64ed03dSBarry Smith if (flg) { 519186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 5207adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 521186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 522d64ed03dSBarry Smith } 52390d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 524909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 52593c39befSBarry Smith 526c60f73f4SPeter Brune ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr); 52757034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 528186905e3SBarry Smith 52957034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 530b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 531b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 53224254dc1SJed Brown ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 533ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 534acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 53585385478SLisandro Dalcin 536a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 537a8054027SBarry Smith if (flg) { 538a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 539a8054027SBarry Smith } 540e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 541e35cf81dSBarry Smith if (flg) { 542e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 543e35cf81dSBarry Smith } 544efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 545efd51863SBarry Smith if (flg) { 546efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 547efd51863SBarry Smith } 548a8054027SBarry Smith 54985385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 55085385478SLisandro Dalcin if (flg) { 55185385478SLisandro Dalcin switch (indx) { 5527f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5537f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 55485385478SLisandro Dalcin } 55585385478SLisandro Dalcin } 55685385478SLisandro Dalcin 557acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 558186905e3SBarry Smith 559fdacfa88SPeter Brune ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr); 560fdacfa88SPeter Brune if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); } 561fdacfa88SPeter Brune 56285385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 56385385478SLisandro Dalcin 564acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 565186905e3SBarry Smith 566fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 567fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 568fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 569fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 570fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 571fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 572fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 573186905e3SBarry Smith 57490d69ab7SBarry Smith flg = PETSC_FALSE; 575acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 576a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 577eabae89aSBarry Smith 578a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 579e8105e01SRichard Katz if (flg) { 580649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 581649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 582e8105e01SRichard Katz } 583eabae89aSBarry Smith 584b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 585b271bb04SBarry Smith if (flg) { 586b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 587b271bb04SBarry Smith } 588b271bb04SBarry Smith 589a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 590eabae89aSBarry Smith if (flg) { 591649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 592f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 593e8105e01SRichard Katz } 594eabae89aSBarry Smith 595a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 596eabae89aSBarry Smith if (flg) { 597649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 598649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 599eabae89aSBarry Smith } 600eabae89aSBarry Smith 6015180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 6025180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 6035180491cSLisandro Dalcin 60490d69ab7SBarry Smith flg = PETSC_FALSE; 605acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 606a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 60790d69ab7SBarry Smith flg = PETSC_FALSE; 608acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 609a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 61090d69ab7SBarry Smith flg = PETSC_FALSE; 611acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 612a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 61390d69ab7SBarry Smith flg = PETSC_FALSE; 614acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 615a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 61690d69ab7SBarry Smith flg = PETSC_FALSE; 617acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 618b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 619e24b481bSBarry Smith 62090d69ab7SBarry Smith flg = PETSC_FALSE; 621acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6224b27c08aSLois Curfman McInnes if (flg) { 6236cab3a1bSJed Brown void *functx; 6246cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6256cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 626ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 6279b94acceSBarry Smith } 628639f9d9dSBarry Smith 629aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 630aa3661deSLisandro Dalcin flg = PETSC_FALSE; 631acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 632a8248277SBarry Smith if (flg && mf_operator) { 633a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 634a8248277SBarry Smith mf = PETSC_TRUE; 635a8248277SBarry Smith } 636aa3661deSLisandro Dalcin flg = PETSC_FALSE; 637acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 638aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 639aa3661deSLisandro Dalcin mf_version = 1; 640aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 641aa3661deSLisandro Dalcin 642d28543b3SPeter Brune 64389b92e6fSPeter Brune /* GS Options */ 64489b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 64589b92e6fSPeter Brune 64676b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 64776b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 64876b2cf59SMatthew Knepley } 64976b2cf59SMatthew Knepley 650e7788613SBarry Smith if (snes->ops->setfromoptions) { 651e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 652639f9d9dSBarry Smith } 6535d973c19SBarry Smith 6545d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6555d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 656b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6574bbc92c1SBarry Smith 658aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6591cee3971SBarry Smith 6601cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 661aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 662aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 66385385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 66493993e2dSLois Curfman McInnes 6659e764e56SPeter Brune if (!snes->linesearch) { 666f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6679e764e56SPeter Brune } 668f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6699e764e56SPeter Brune 67051e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 67151e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 67251e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 67351e86f29SPeter Brune if (pcset && (!snes->pc)) { 67451e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 67551e86f29SPeter Brune } 6763a40ed3dSBarry Smith PetscFunctionReturn(0); 6779b94acceSBarry Smith } 6789b94acceSBarry Smith 679d25893d9SBarry Smith #undef __FUNCT__ 680d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 681d25893d9SBarry Smith /*@ 682d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 683d25893d9SBarry Smith the nonlinear solvers. 684d25893d9SBarry Smith 685d25893d9SBarry Smith Logically Collective on SNES 686d25893d9SBarry Smith 687d25893d9SBarry Smith Input Parameters: 688d25893d9SBarry Smith + snes - the SNES context 689d25893d9SBarry Smith . compute - function to compute the context 690d25893d9SBarry Smith - destroy - function to destroy the context 691d25893d9SBarry Smith 692d25893d9SBarry Smith Level: intermediate 693d25893d9SBarry Smith 694d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 695d25893d9SBarry Smith 696d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 697d25893d9SBarry Smith @*/ 698d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 699d25893d9SBarry Smith { 700d25893d9SBarry Smith PetscFunctionBegin; 701d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 702d25893d9SBarry Smith snes->ops->usercompute = compute; 703d25893d9SBarry Smith snes->ops->userdestroy = destroy; 704d25893d9SBarry Smith PetscFunctionReturn(0); 705d25893d9SBarry Smith } 706a847f771SSatish Balay 7074a2ae208SSatish Balay #undef __FUNCT__ 7084a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 709b07ff414SBarry Smith /*@ 7109b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7119b94acceSBarry Smith the nonlinear solvers. 7129b94acceSBarry Smith 7133f9fe445SBarry Smith Logically Collective on SNES 714fee21e36SBarry Smith 715c7afd0dbSLois Curfman McInnes Input Parameters: 716c7afd0dbSLois Curfman McInnes + snes - the SNES context 717c7afd0dbSLois Curfman McInnes - usrP - optional user context 718c7afd0dbSLois Curfman McInnes 71936851e7fSLois Curfman McInnes Level: intermediate 72036851e7fSLois Curfman McInnes 7219b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7229b94acceSBarry Smith 723ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 7249b94acceSBarry Smith @*/ 7257087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7269b94acceSBarry Smith { 7271b2093e4SBarry Smith PetscErrorCode ierr; 728b07ff414SBarry Smith KSP ksp; 7291b2093e4SBarry Smith 7303a40ed3dSBarry Smith PetscFunctionBegin; 7310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 732b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 733b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7349b94acceSBarry Smith snes->user = usrP; 7353a40ed3dSBarry Smith PetscFunctionReturn(0); 7369b94acceSBarry Smith } 73774679c65SBarry Smith 7384a2ae208SSatish Balay #undef __FUNCT__ 7394a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 740b07ff414SBarry Smith /*@ 7419b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7429b94acceSBarry Smith nonlinear solvers. 7439b94acceSBarry Smith 744c7afd0dbSLois Curfman McInnes Not Collective 745c7afd0dbSLois Curfman McInnes 7469b94acceSBarry Smith Input Parameter: 7479b94acceSBarry Smith . snes - SNES context 7489b94acceSBarry Smith 7499b94acceSBarry Smith Output Parameter: 7509b94acceSBarry Smith . usrP - user context 7519b94acceSBarry Smith 75236851e7fSLois Curfman McInnes Level: intermediate 75336851e7fSLois Curfman McInnes 7549b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7559b94acceSBarry Smith 7569b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7579b94acceSBarry Smith @*/ 758e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7599b94acceSBarry Smith { 7603a40ed3dSBarry Smith PetscFunctionBegin; 7610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 762e71120c6SJed Brown *(void**)usrP = snes->user; 7633a40ed3dSBarry Smith PetscFunctionReturn(0); 7649b94acceSBarry Smith } 76574679c65SBarry Smith 7664a2ae208SSatish Balay #undef __FUNCT__ 7674a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7689b94acceSBarry Smith /*@ 769c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 770c8228a4eSBarry Smith at this time. 7719b94acceSBarry Smith 772c7afd0dbSLois Curfman McInnes Not Collective 773c7afd0dbSLois Curfman McInnes 7749b94acceSBarry Smith Input Parameter: 7759b94acceSBarry Smith . snes - SNES context 7769b94acceSBarry Smith 7779b94acceSBarry Smith Output Parameter: 7789b94acceSBarry Smith . iter - iteration number 7799b94acceSBarry Smith 780c8228a4eSBarry Smith Notes: 781c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 782c8228a4eSBarry Smith 783c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 78408405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 78508405cd6SLois Curfman McInnes .vb 78608405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 78708405cd6SLois Curfman McInnes if (!(it % 2)) { 78808405cd6SLois Curfman McInnes [compute Jacobian here] 78908405cd6SLois Curfman McInnes } 79008405cd6SLois Curfman McInnes .ve 791c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 79208405cd6SLois Curfman McInnes recomputed every second SNES iteration. 793c8228a4eSBarry Smith 79436851e7fSLois Curfman McInnes Level: intermediate 79536851e7fSLois Curfman McInnes 7962b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 7972b668275SBarry Smith 798b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 7999b94acceSBarry Smith @*/ 8007087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 8019b94acceSBarry Smith { 8023a40ed3dSBarry Smith PetscFunctionBegin; 8030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8044482741eSBarry Smith PetscValidIntPointer(iter,2); 8059b94acceSBarry Smith *iter = snes->iter; 8063a40ed3dSBarry Smith PetscFunctionReturn(0); 8079b94acceSBarry Smith } 80874679c65SBarry Smith 8094a2ae208SSatish Balay #undef __FUNCT__ 810360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 811360c497dSPeter Brune /*@ 812360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 813360c497dSPeter Brune 814360c497dSPeter Brune Not Collective 815360c497dSPeter Brune 816360c497dSPeter Brune Input Parameter: 817360c497dSPeter Brune . snes - SNES context 818360c497dSPeter Brune . iter - iteration number 819360c497dSPeter Brune 820360c497dSPeter Brune Level: developer 821360c497dSPeter Brune 822360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 823360c497dSPeter Brune 824360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 825360c497dSPeter Brune @*/ 826360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 827360c497dSPeter Brune { 828360c497dSPeter Brune PetscErrorCode ierr; 829360c497dSPeter Brune 830360c497dSPeter Brune PetscFunctionBegin; 831360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 832360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 833360c497dSPeter Brune snes->iter = iter; 834360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 835360c497dSPeter Brune PetscFunctionReturn(0); 836360c497dSPeter Brune } 837360c497dSPeter Brune 838360c497dSPeter Brune #undef __FUNCT__ 8394a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8409b94acceSBarry Smith /*@ 8419b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8429b94acceSBarry Smith with SNESSSetFunction(). 8439b94acceSBarry Smith 844c7afd0dbSLois Curfman McInnes Collective on SNES 845c7afd0dbSLois Curfman McInnes 8469b94acceSBarry Smith Input Parameter: 8479b94acceSBarry Smith . snes - SNES context 8489b94acceSBarry Smith 8499b94acceSBarry Smith Output Parameter: 8509b94acceSBarry Smith . fnorm - 2-norm of function 8519b94acceSBarry Smith 85236851e7fSLois Curfman McInnes Level: intermediate 85336851e7fSLois Curfman McInnes 8549b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 855a86d99e1SLois Curfman McInnes 856b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8579b94acceSBarry Smith @*/ 8587087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8599b94acceSBarry Smith { 8603a40ed3dSBarry Smith PetscFunctionBegin; 8610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8624482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8639b94acceSBarry Smith *fnorm = snes->norm; 8643a40ed3dSBarry Smith PetscFunctionReturn(0); 8659b94acceSBarry Smith } 86674679c65SBarry Smith 867360c497dSPeter Brune 868360c497dSPeter Brune #undef __FUNCT__ 869360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 870360c497dSPeter Brune /*@ 871360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 872360c497dSPeter Brune 873360c497dSPeter Brune Collective on SNES 874360c497dSPeter Brune 875360c497dSPeter Brune Input Parameter: 876360c497dSPeter Brune . snes - SNES context 877360c497dSPeter Brune . fnorm - 2-norm of function 878360c497dSPeter Brune 879360c497dSPeter Brune Level: developer 880360c497dSPeter Brune 881360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 882360c497dSPeter Brune 883360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 884360c497dSPeter Brune @*/ 885360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 886360c497dSPeter Brune { 887360c497dSPeter Brune 888360c497dSPeter Brune PetscErrorCode ierr; 889360c497dSPeter Brune 890360c497dSPeter Brune PetscFunctionBegin; 891360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 892360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 893360c497dSPeter Brune snes->norm = fnorm; 894360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 895360c497dSPeter Brune PetscFunctionReturn(0); 896360c497dSPeter Brune } 897360c497dSPeter Brune 8984a2ae208SSatish Balay #undef __FUNCT__ 899b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 9009b94acceSBarry Smith /*@ 901b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 9029b94acceSBarry Smith attempted by the nonlinear solver. 9039b94acceSBarry Smith 904c7afd0dbSLois Curfman McInnes Not Collective 905c7afd0dbSLois Curfman McInnes 9069b94acceSBarry Smith Input Parameter: 9079b94acceSBarry Smith . snes - SNES context 9089b94acceSBarry Smith 9099b94acceSBarry Smith Output Parameter: 9109b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9119b94acceSBarry Smith 912c96a6f78SLois Curfman McInnes Notes: 913c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 914c96a6f78SLois Curfman McInnes 91536851e7fSLois Curfman McInnes Level: intermediate 91636851e7fSLois Curfman McInnes 9179b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 91858ebbce7SBarry Smith 919e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 92058ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9219b94acceSBarry Smith @*/ 9227087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9239b94acceSBarry Smith { 9243a40ed3dSBarry Smith PetscFunctionBegin; 9250700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9264482741eSBarry Smith PetscValidIntPointer(nfails,2); 92750ffb88aSMatthew Knepley *nfails = snes->numFailures; 92850ffb88aSMatthew Knepley PetscFunctionReturn(0); 92950ffb88aSMatthew Knepley } 93050ffb88aSMatthew Knepley 93150ffb88aSMatthew Knepley #undef __FUNCT__ 932b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 93350ffb88aSMatthew Knepley /*@ 934b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 93550ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 93650ffb88aSMatthew Knepley 93750ffb88aSMatthew Knepley Not Collective 93850ffb88aSMatthew Knepley 93950ffb88aSMatthew Knepley Input Parameters: 94050ffb88aSMatthew Knepley + snes - SNES context 94150ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 94250ffb88aSMatthew Knepley 94350ffb88aSMatthew Knepley Level: intermediate 94450ffb88aSMatthew Knepley 94550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 94658ebbce7SBarry Smith 947e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 94858ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 94950ffb88aSMatthew Knepley @*/ 9507087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 95150ffb88aSMatthew Knepley { 95250ffb88aSMatthew Knepley PetscFunctionBegin; 9530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 95450ffb88aSMatthew Knepley snes->maxFailures = maxFails; 95550ffb88aSMatthew Knepley PetscFunctionReturn(0); 95650ffb88aSMatthew Knepley } 95750ffb88aSMatthew Knepley 95850ffb88aSMatthew Knepley #undef __FUNCT__ 959b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 96050ffb88aSMatthew Knepley /*@ 961b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 96250ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 96350ffb88aSMatthew Knepley 96450ffb88aSMatthew Knepley Not Collective 96550ffb88aSMatthew Knepley 96650ffb88aSMatthew Knepley Input Parameter: 96750ffb88aSMatthew Knepley . snes - SNES context 96850ffb88aSMatthew Knepley 96950ffb88aSMatthew Knepley Output Parameter: 97050ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 97150ffb88aSMatthew Knepley 97250ffb88aSMatthew Knepley Level: intermediate 97350ffb88aSMatthew Knepley 97450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 97558ebbce7SBarry Smith 976e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 97758ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 97858ebbce7SBarry Smith 97950ffb88aSMatthew Knepley @*/ 9807087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 98150ffb88aSMatthew Knepley { 98250ffb88aSMatthew Knepley PetscFunctionBegin; 9830700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9844482741eSBarry Smith PetscValidIntPointer(maxFails,2); 98550ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 9863a40ed3dSBarry Smith PetscFunctionReturn(0); 9879b94acceSBarry Smith } 988a847f771SSatish Balay 9894a2ae208SSatish Balay #undef __FUNCT__ 9902541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 9912541af92SBarry Smith /*@ 9922541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 9932541af92SBarry Smith done by SNES. 9942541af92SBarry Smith 9952541af92SBarry Smith Not Collective 9962541af92SBarry Smith 9972541af92SBarry Smith Input Parameter: 9982541af92SBarry Smith . snes - SNES context 9992541af92SBarry Smith 10002541af92SBarry Smith Output Parameter: 10012541af92SBarry Smith . nfuncs - number of evaluations 10022541af92SBarry Smith 10032541af92SBarry Smith Level: intermediate 10042541af92SBarry Smith 10052541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 100658ebbce7SBarry Smith 1007e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10082541af92SBarry Smith @*/ 10097087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10102541af92SBarry Smith { 10112541af92SBarry Smith PetscFunctionBegin; 10120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10132541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10142541af92SBarry Smith *nfuncs = snes->nfuncs; 10152541af92SBarry Smith PetscFunctionReturn(0); 10162541af92SBarry Smith } 10172541af92SBarry Smith 10182541af92SBarry Smith #undef __FUNCT__ 10193d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10203d4c4710SBarry Smith /*@ 10213d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10223d4c4710SBarry Smith linear solvers. 10233d4c4710SBarry Smith 10243d4c4710SBarry Smith Not Collective 10253d4c4710SBarry Smith 10263d4c4710SBarry Smith Input Parameter: 10273d4c4710SBarry Smith . snes - SNES context 10283d4c4710SBarry Smith 10293d4c4710SBarry Smith Output Parameter: 10303d4c4710SBarry Smith . nfails - number of failed solves 10313d4c4710SBarry Smith 10323d4c4710SBarry Smith Notes: 10333d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10343d4c4710SBarry Smith 10353d4c4710SBarry Smith Level: intermediate 10363d4c4710SBarry Smith 10373d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 103858ebbce7SBarry Smith 1039e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10403d4c4710SBarry Smith @*/ 10417087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10423d4c4710SBarry Smith { 10433d4c4710SBarry Smith PetscFunctionBegin; 10440700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10453d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10463d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10473d4c4710SBarry Smith PetscFunctionReturn(0); 10483d4c4710SBarry Smith } 10493d4c4710SBarry Smith 10503d4c4710SBarry Smith #undef __FUNCT__ 10513d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10523d4c4710SBarry Smith /*@ 10533d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10543d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10553d4c4710SBarry Smith 10563f9fe445SBarry Smith Logically Collective on SNES 10573d4c4710SBarry Smith 10583d4c4710SBarry Smith Input Parameters: 10593d4c4710SBarry Smith + snes - SNES context 10603d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10613d4c4710SBarry Smith 10623d4c4710SBarry Smith Level: intermediate 10633d4c4710SBarry Smith 1064a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10653d4c4710SBarry Smith 10663d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10673d4c4710SBarry Smith 106858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10693d4c4710SBarry Smith @*/ 10707087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 10713d4c4710SBarry Smith { 10723d4c4710SBarry Smith PetscFunctionBegin; 10730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1074c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 10753d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 10763d4c4710SBarry Smith PetscFunctionReturn(0); 10773d4c4710SBarry Smith } 10783d4c4710SBarry Smith 10793d4c4710SBarry Smith #undef __FUNCT__ 10803d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 10813d4c4710SBarry Smith /*@ 10823d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 10833d4c4710SBarry Smith are allowed before SNES terminates 10843d4c4710SBarry Smith 10853d4c4710SBarry Smith Not Collective 10863d4c4710SBarry Smith 10873d4c4710SBarry Smith Input Parameter: 10883d4c4710SBarry Smith . snes - SNES context 10893d4c4710SBarry Smith 10903d4c4710SBarry Smith Output Parameter: 10913d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 10923d4c4710SBarry Smith 10933d4c4710SBarry Smith Level: intermediate 10943d4c4710SBarry Smith 10953d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 10963d4c4710SBarry Smith 10973d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 10983d4c4710SBarry Smith 1099e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 11003d4c4710SBarry Smith @*/ 11017087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 11023d4c4710SBarry Smith { 11033d4c4710SBarry Smith PetscFunctionBegin; 11040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11053d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11063d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11073d4c4710SBarry Smith PetscFunctionReturn(0); 11083d4c4710SBarry Smith } 11093d4c4710SBarry Smith 11103d4c4710SBarry Smith #undef __FUNCT__ 1111b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1112c96a6f78SLois Curfman McInnes /*@ 1113b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1114c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1115c96a6f78SLois Curfman McInnes 1116c7afd0dbSLois Curfman McInnes Not Collective 1117c7afd0dbSLois Curfman McInnes 1118c96a6f78SLois Curfman McInnes Input Parameter: 1119c96a6f78SLois Curfman McInnes . snes - SNES context 1120c96a6f78SLois Curfman McInnes 1121c96a6f78SLois Curfman McInnes Output Parameter: 1122c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1123c96a6f78SLois Curfman McInnes 1124c96a6f78SLois Curfman McInnes Notes: 1125c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1126c96a6f78SLois Curfman McInnes 112736851e7fSLois Curfman McInnes Level: intermediate 112836851e7fSLois Curfman McInnes 1129c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11302b668275SBarry Smith 11318c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1132c96a6f78SLois Curfman McInnes @*/ 11337087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1134c96a6f78SLois Curfman McInnes { 11353a40ed3dSBarry Smith PetscFunctionBegin; 11360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11374482741eSBarry Smith PetscValidIntPointer(lits,2); 1138c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11393a40ed3dSBarry Smith PetscFunctionReturn(0); 1140c96a6f78SLois Curfman McInnes } 1141c96a6f78SLois Curfman McInnes 11424a2ae208SSatish Balay #undef __FUNCT__ 114394b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 114452baeb72SSatish Balay /*@ 114594b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11469b94acceSBarry Smith 114794b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1148c7afd0dbSLois Curfman McInnes 11499b94acceSBarry Smith Input Parameter: 11509b94acceSBarry Smith . snes - the SNES context 11519b94acceSBarry Smith 11529b94acceSBarry Smith Output Parameter: 115394b7f48cSBarry Smith . ksp - the KSP context 11549b94acceSBarry Smith 11559b94acceSBarry Smith Notes: 115694b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11579b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11582999313aSBarry Smith PC contexts as well. 11599b94acceSBarry Smith 116036851e7fSLois Curfman McInnes Level: beginner 116136851e7fSLois Curfman McInnes 116294b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11639b94acceSBarry Smith 11642999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11659b94acceSBarry Smith @*/ 11667087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11679b94acceSBarry Smith { 11681cee3971SBarry Smith PetscErrorCode ierr; 11691cee3971SBarry Smith 11703a40ed3dSBarry Smith PetscFunctionBegin; 11710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11724482741eSBarry Smith PetscValidPointer(ksp,2); 11731cee3971SBarry Smith 11741cee3971SBarry Smith if (!snes->ksp) { 11751cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 11761cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 11771cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 11781cee3971SBarry Smith } 117994b7f48cSBarry Smith *ksp = snes->ksp; 11803a40ed3dSBarry Smith PetscFunctionReturn(0); 11819b94acceSBarry Smith } 118282bf6240SBarry Smith 11834a2ae208SSatish Balay #undef __FUNCT__ 11842999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 11852999313aSBarry Smith /*@ 11862999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 11872999313aSBarry Smith 11882999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 11892999313aSBarry Smith 11902999313aSBarry Smith Input Parameters: 11912999313aSBarry Smith + snes - the SNES context 11922999313aSBarry Smith - ksp - the KSP context 11932999313aSBarry Smith 11942999313aSBarry Smith Notes: 11952999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 11962999313aSBarry Smith so this routine is rarely needed. 11972999313aSBarry Smith 11982999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 11992999313aSBarry Smith decreased by one. 12002999313aSBarry Smith 12012999313aSBarry Smith Level: developer 12022999313aSBarry Smith 12032999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12042999313aSBarry Smith 12052999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12062999313aSBarry Smith @*/ 12077087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12082999313aSBarry Smith { 12092999313aSBarry Smith PetscErrorCode ierr; 12102999313aSBarry Smith 12112999313aSBarry Smith PetscFunctionBegin; 12120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12130700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12142999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12157dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1216906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12172999313aSBarry Smith snes->ksp = ksp; 12182999313aSBarry Smith PetscFunctionReturn(0); 12192999313aSBarry Smith } 12202999313aSBarry Smith 12217adad957SLisandro Dalcin #if 0 12222999313aSBarry Smith #undef __FUNCT__ 12234a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12246849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1225e24b481bSBarry Smith { 1226e24b481bSBarry Smith PetscFunctionBegin; 1227e24b481bSBarry Smith PetscFunctionReturn(0); 1228e24b481bSBarry Smith } 12297adad957SLisandro Dalcin #endif 1230e24b481bSBarry Smith 12319b94acceSBarry Smith /* -----------------------------------------------------------*/ 12324a2ae208SSatish Balay #undef __FUNCT__ 12334a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 123452baeb72SSatish Balay /*@ 12359b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12369b94acceSBarry Smith 1237c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1238c7afd0dbSLois Curfman McInnes 1239c7afd0dbSLois Curfman McInnes Input Parameters: 1240906ed7ccSBarry Smith . comm - MPI communicator 12419b94acceSBarry Smith 12429b94acceSBarry Smith Output Parameter: 12439b94acceSBarry Smith . outsnes - the new SNES context 12449b94acceSBarry Smith 1245c7afd0dbSLois Curfman McInnes Options Database Keys: 1246c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1247c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1248c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1249c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1250c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1251c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1252c1f60f51SBarry Smith 125336851e7fSLois Curfman McInnes Level: beginner 125436851e7fSLois Curfman McInnes 12559b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12569b94acceSBarry Smith 1257a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1258a8054027SBarry Smith 12599b94acceSBarry Smith @*/ 12607087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12619b94acceSBarry Smith { 1262dfbe8321SBarry Smith PetscErrorCode ierr; 12639b94acceSBarry Smith SNES snes; 1264fa9f3622SBarry Smith SNESKSPEW *kctx; 126537fcc0dbSBarry Smith 12663a40ed3dSBarry Smith PetscFunctionBegin; 1267ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12688ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12698ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 12708ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 12718ba1e511SMatthew Knepley #endif 12728ba1e511SMatthew Knepley 12733194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 12747adad957SLisandro Dalcin 127585385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 12762c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 127788976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 12789b94acceSBarry Smith snes->max_its = 50; 12799750a799SBarry Smith snes->max_funcs = 10000; 12809b94acceSBarry Smith snes->norm = 0.0; 1281fdacfa88SPeter Brune snes->normtype = SNES_NORM_FUNCTION; 1282b4874afaSBarry Smith snes->rtol = 1.e-8; 1283b4874afaSBarry Smith snes->ttol = 0.0; 128470441072SBarry Smith snes->abstol = 1.e-50; 1285c60f73f4SPeter Brune snes->stol = 1.e-8; 12864b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 12879b94acceSBarry Smith snes->nfuncs = 0; 128850ffb88aSMatthew Knepley snes->numFailures = 0; 128950ffb88aSMatthew Knepley snes->maxFailures = 1; 12907a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1291e35cf81dSBarry Smith snes->lagjacobian = 1; 1292a8054027SBarry Smith snes->lagpreconditioner = 1; 1293639f9d9dSBarry Smith snes->numbermonitors = 0; 12949b94acceSBarry Smith snes->data = 0; 12954dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1296186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 12976f24a144SLois Curfman McInnes snes->nwork = 0; 129858c9b817SLisandro Dalcin snes->work = 0; 129958c9b817SLisandro Dalcin snes->nvwork = 0; 130058c9b817SLisandro Dalcin snes->vwork = 0; 1301758f92a0SBarry Smith snes->conv_hist_len = 0; 1302758f92a0SBarry Smith snes->conv_hist_max = 0; 1303758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1304758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1305758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1306e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1307e4ed7901SPeter Brune snes->norm_init = 0.; 1308e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 1309184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 131089b92e6fSPeter Brune snes->gssweeps = 1; 13119b94acceSBarry Smith 13123d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13133d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13143d4c4710SBarry Smith 13159b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 131638f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13179b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13189b94acceSBarry Smith kctx->version = 2; 13199b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13209b94acceSBarry Smith this was too large for some test cases */ 132175567043SBarry Smith kctx->rtol_last = 0.0; 13229b94acceSBarry Smith kctx->rtol_max = .9; 13239b94acceSBarry Smith kctx->gamma = 1.0; 132462d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 132571f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13269b94acceSBarry Smith kctx->threshold = .1; 132775567043SBarry Smith kctx->lresid_last = 0.0; 132875567043SBarry Smith kctx->norm_last = 0.0; 13299b94acceSBarry Smith 13309b94acceSBarry Smith *outsnes = snes; 13313a40ed3dSBarry Smith PetscFunctionReturn(0); 13329b94acceSBarry Smith } 13339b94acceSBarry Smith 13344a2ae208SSatish Balay #undef __FUNCT__ 13354a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13369b94acceSBarry Smith /*@C 13379b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13389b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13399b94acceSBarry Smith equations. 13409b94acceSBarry Smith 13413f9fe445SBarry Smith Logically Collective on SNES 1342fee21e36SBarry Smith 1343c7afd0dbSLois Curfman McInnes Input Parameters: 1344c7afd0dbSLois Curfman McInnes + snes - the SNES context 1345c7afd0dbSLois Curfman McInnes . r - vector to store function value 1346de044059SHong Zhang . func - function evaluation routine 1347c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1348c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13499b94acceSBarry Smith 1350c7afd0dbSLois Curfman McInnes Calling sequence of func: 13518d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1352c7afd0dbSLois Curfman McInnes 1353c586c404SJed Brown + snes - the SNES context 1354c586c404SJed Brown . x - state at which to evaluate residual 1355c586c404SJed Brown . f - vector to put residual 1356c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13579b94acceSBarry Smith 13589b94acceSBarry Smith Notes: 13599b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13609b94acceSBarry Smith $ f'(x) x = -f(x), 1361c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13629b94acceSBarry Smith 136336851e7fSLois Curfman McInnes Level: beginner 136436851e7fSLois Curfman McInnes 13659b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13669b94acceSBarry Smith 13678b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13689b94acceSBarry Smith @*/ 13697087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13709b94acceSBarry Smith { 137185385478SLisandro Dalcin PetscErrorCode ierr; 13726cab3a1bSJed Brown DM dm; 13736cab3a1bSJed Brown 13743a40ed3dSBarry Smith PetscFunctionBegin; 13750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1376d2a683ecSLisandro Dalcin if (r) { 1377d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1378d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 137985385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 13806bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 138185385478SLisandro Dalcin snes->vec_func = r; 1382d2a683ecSLisandro Dalcin } 13836cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 13846cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 13853a40ed3dSBarry Smith PetscFunctionReturn(0); 13869b94acceSBarry Smith } 13879b94acceSBarry Smith 1388646217ecSPeter Brune 1389646217ecSPeter Brune #undef __FUNCT__ 1390e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1391e4ed7901SPeter Brune /*@C 1392e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1393e4ed7901SPeter Brune function norm at the initialization of the method. In some 1394e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1395e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1396e4ed7901SPeter Brune to SNESComputeFunction in that case. 1397e4ed7901SPeter Brune 1398e4ed7901SPeter Brune Logically Collective on SNES 1399e4ed7901SPeter Brune 1400e4ed7901SPeter Brune Input Parameters: 1401e4ed7901SPeter Brune + snes - the SNES context 1402e4ed7901SPeter Brune - f - vector to store function value 1403e4ed7901SPeter Brune 1404e4ed7901SPeter Brune Notes: 1405e4ed7901SPeter Brune This should not be modified during the solution procedure. 1406e4ed7901SPeter Brune 1407e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1408e4ed7901SPeter Brune 1409e4ed7901SPeter Brune Level: developer 1410e4ed7901SPeter Brune 1411e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1412e4ed7901SPeter Brune 1413e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1414e4ed7901SPeter Brune @*/ 1415e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1416e4ed7901SPeter Brune { 1417e4ed7901SPeter Brune PetscErrorCode ierr; 1418e4ed7901SPeter Brune Vec vec_func; 1419e4ed7901SPeter Brune 1420e4ed7901SPeter Brune PetscFunctionBegin; 1421e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1422e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1423e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1424e4ed7901SPeter Brune ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1425e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1426217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1427e4ed7901SPeter Brune PetscFunctionReturn(0); 1428e4ed7901SPeter Brune } 1429e4ed7901SPeter Brune 1430e4ed7901SPeter Brune 1431e4ed7901SPeter Brune #undef __FUNCT__ 1432e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm" 1433e4ed7901SPeter Brune /*@C 1434e4ed7901SPeter Brune SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm 1435e4ed7901SPeter Brune at the initialization of the method. In some instances, the user has precomputed 1436e4ed7901SPeter Brune the function and its norm before calling SNESSolve. This function allows one to 1437e4ed7901SPeter Brune avoid a redundant call to SNESComputeFunction() and VecNorm() in that case. 1438e4ed7901SPeter Brune 1439e4ed7901SPeter Brune Logically Collective on SNES 1440e4ed7901SPeter Brune 1441e4ed7901SPeter Brune Input Parameters: 1442e4ed7901SPeter Brune + snes - the SNES context 1443e4ed7901SPeter Brune - fnorm - the norm of F as set by SNESSetInitialFunction() 1444e4ed7901SPeter Brune 1445e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1446e4ed7901SPeter Brune 1447e4ed7901SPeter Brune Level: developer 1448e4ed7901SPeter Brune 1449e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm 1450e4ed7901SPeter Brune 1451e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction() 1452e4ed7901SPeter Brune @*/ 1453e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm) 1454e4ed7901SPeter Brune { 1455e4ed7901SPeter Brune PetscFunctionBegin; 1456e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1457e4ed7901SPeter Brune snes->norm_init = fnorm; 1458e4ed7901SPeter Brune snes->norm_init_set = PETSC_TRUE; 1459e4ed7901SPeter Brune PetscFunctionReturn(0); 1460e4ed7901SPeter Brune } 1461e4ed7901SPeter Brune 1462e4ed7901SPeter Brune #undef __FUNCT__ 1463534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType" 1464534ebe21SPeter Brune /*@ 1465534ebe21SPeter Brune SNESSetNormType - Sets the SNESNormType used in covergence and monitoring 1466534ebe21SPeter Brune of the SNES method. 1467534ebe21SPeter Brune 1468534ebe21SPeter Brune Logically Collective on SNES 1469534ebe21SPeter Brune 1470534ebe21SPeter Brune Input Parameters: 1471534ebe21SPeter Brune + snes - the SNES context 1472534ebe21SPeter Brune - normtype - the type of the norm used 1473534ebe21SPeter Brune 1474534ebe21SPeter Brune Notes: 1475534ebe21SPeter Brune Only certain SNES methods support certain SNESNormTypes. Most require evaluation 1476534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1477534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1478534ebe21SPeter Brune (SNESGS) and the like do not require the norm of the function to be computed, and therfore 1479534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1480534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1481534ebe21SPeter Brune their solution. 1482534ebe21SPeter Brune 1483534ebe21SPeter Brune Level: developer 1484534ebe21SPeter Brune 1485534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1486534ebe21SPeter Brune 1487534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1488534ebe21SPeter Brune @*/ 1489534ebe21SPeter Brune PetscErrorCode SNESSetNormType(SNES snes, SNESNormType normtype) 1490534ebe21SPeter Brune { 1491534ebe21SPeter Brune PetscFunctionBegin; 1492534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1493534ebe21SPeter Brune snes->normtype = normtype; 1494534ebe21SPeter Brune PetscFunctionReturn(0); 1495534ebe21SPeter Brune } 1496534ebe21SPeter Brune 1497534ebe21SPeter Brune 1498534ebe21SPeter Brune #undef __FUNCT__ 1499534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType" 1500534ebe21SPeter Brune /*@ 1501534ebe21SPeter Brune SNESGetNormType - Gets the SNESNormType used in covergence and monitoring 1502534ebe21SPeter Brune of the SNES method. 1503534ebe21SPeter Brune 1504534ebe21SPeter Brune Logically Collective on SNES 1505534ebe21SPeter Brune 1506534ebe21SPeter Brune Input Parameters: 1507534ebe21SPeter Brune + snes - the SNES context 1508534ebe21SPeter Brune - normtype - the type of the norm used 1509534ebe21SPeter Brune 1510534ebe21SPeter Brune Level: advanced 1511534ebe21SPeter Brune 1512534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1513534ebe21SPeter Brune 1514534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1515534ebe21SPeter Brune @*/ 1516534ebe21SPeter Brune PetscErrorCode SNESGetNormType(SNES snes, SNESNormType *normtype) 1517534ebe21SPeter Brune { 1518534ebe21SPeter Brune PetscFunctionBegin; 1519534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1520534ebe21SPeter Brune *normtype = snes->normtype; 1521534ebe21SPeter Brune PetscFunctionReturn(0); 1522534ebe21SPeter Brune } 1523534ebe21SPeter Brune 1524534ebe21SPeter Brune #undef __FUNCT__ 1525646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1526c79ef259SPeter Brune /*@C 1527c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1528c79ef259SPeter Brune use with composed nonlinear solvers. 1529c79ef259SPeter Brune 1530c79ef259SPeter Brune Input Parameters: 1531c79ef259SPeter Brune + snes - the SNES context 1532c79ef259SPeter Brune . gsfunc - function evaluation routine 1533c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1534c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1535c79ef259SPeter Brune 1536c79ef259SPeter Brune Calling sequence of func: 1537c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1538c79ef259SPeter Brune 1539c79ef259SPeter Brune + X - solution vector 1540c79ef259SPeter Brune . B - RHS vector 1541d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1542c79ef259SPeter Brune 1543c79ef259SPeter Brune Notes: 1544c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1545c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1546c79ef259SPeter Brune 1547d28543b3SPeter Brune Level: intermediate 1548c79ef259SPeter Brune 1549d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1550c79ef259SPeter Brune 1551c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1552c79ef259SPeter Brune @*/ 15536cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 15546cab3a1bSJed Brown { 15556cab3a1bSJed Brown PetscErrorCode ierr; 15566cab3a1bSJed Brown DM dm; 15576cab3a1bSJed Brown 1558646217ecSPeter Brune PetscFunctionBegin; 15596cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15606cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 15616cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1562646217ecSPeter Brune PetscFunctionReturn(0); 1563646217ecSPeter Brune } 1564646217ecSPeter Brune 1565d25893d9SBarry Smith #undef __FUNCT__ 156689b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 156789b92e6fSPeter Brune /*@ 156889b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 156989b92e6fSPeter Brune 157089b92e6fSPeter Brune Input Parameters: 157189b92e6fSPeter Brune + snes - the SNES context 157289b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 157389b92e6fSPeter Brune 157489b92e6fSPeter Brune Level: intermediate 157589b92e6fSPeter Brune 157689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 157789b92e6fSPeter Brune 157889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 157989b92e6fSPeter Brune @*/ 158089b92e6fSPeter Brune 158189b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 158289b92e6fSPeter Brune PetscFunctionBegin; 158389b92e6fSPeter Brune snes->gssweeps = sweeps; 158489b92e6fSPeter Brune PetscFunctionReturn(0); 158589b92e6fSPeter Brune } 158689b92e6fSPeter Brune 158789b92e6fSPeter Brune 158889b92e6fSPeter Brune #undef __FUNCT__ 158989b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 159089b92e6fSPeter Brune /*@ 159189b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 159289b92e6fSPeter Brune 159389b92e6fSPeter Brune Input Parameters: 159489b92e6fSPeter Brune . snes - the SNES context 159589b92e6fSPeter Brune 159689b92e6fSPeter Brune Output Parameters: 159789b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 159889b92e6fSPeter Brune 159989b92e6fSPeter Brune Level: intermediate 160089b92e6fSPeter Brune 160189b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 160289b92e6fSPeter Brune 160389b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 160489b92e6fSPeter Brune @*/ 160589b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 160689b92e6fSPeter Brune PetscFunctionBegin; 160789b92e6fSPeter Brune *sweeps = snes->gssweeps; 160889b92e6fSPeter Brune PetscFunctionReturn(0); 160989b92e6fSPeter Brune } 161089b92e6fSPeter Brune 161189b92e6fSPeter Brune #undef __FUNCT__ 16128b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 16138b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 16148b0a5094SBarry Smith { 16158b0a5094SBarry Smith PetscErrorCode ierr; 16166cab3a1bSJed Brown void *functx,*jacctx; 16176cab3a1bSJed Brown 16188b0a5094SBarry Smith PetscFunctionBegin; 16196cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 16206cab3a1bSJed Brown ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr); 16218b0a5094SBarry Smith /* A(x)*x - b(x) */ 16226cab3a1bSJed Brown ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr); 16236cab3a1bSJed Brown ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr); 16248b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16258b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16268b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 16278b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 16288b0a5094SBarry Smith PetscFunctionReturn(0); 16298b0a5094SBarry Smith } 16308b0a5094SBarry Smith 16318b0a5094SBarry Smith #undef __FUNCT__ 16328b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 16338b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 16348b0a5094SBarry Smith { 16358b0a5094SBarry Smith PetscFunctionBegin; 16368b0a5094SBarry Smith *flag = snes->matstruct; 16378b0a5094SBarry Smith PetscFunctionReturn(0); 16388b0a5094SBarry Smith } 16398b0a5094SBarry Smith 16408b0a5094SBarry Smith #undef __FUNCT__ 16418b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 16428b0a5094SBarry Smith /*@C 16430d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 16448b0a5094SBarry Smith 16458b0a5094SBarry Smith Logically Collective on SNES 16468b0a5094SBarry Smith 16478b0a5094SBarry Smith Input Parameters: 16488b0a5094SBarry Smith + snes - the SNES context 16498b0a5094SBarry Smith . r - vector to store function value 16508b0a5094SBarry Smith . func - function evaluation routine 16518b0a5094SBarry 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) 16528b0a5094SBarry Smith . mat - matrix to store A 16538b0a5094SBarry Smith . mfunc - function to compute matrix value 16548b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 16558b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 16568b0a5094SBarry Smith 16578b0a5094SBarry Smith Calling sequence of func: 16588b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 16598b0a5094SBarry Smith 16608b0a5094SBarry Smith + f - function vector 16618b0a5094SBarry Smith - ctx - optional user-defined function context 16628b0a5094SBarry Smith 16638b0a5094SBarry Smith Calling sequence of mfunc: 16648b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 16658b0a5094SBarry Smith 16668b0a5094SBarry Smith + x - input vector 16678b0a5094SBarry 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(), 16688b0a5094SBarry Smith normally just pass mat in this location 16698b0a5094SBarry Smith . mat - form A(x) matrix 16708b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 16718b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 16728b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 16738b0a5094SBarry Smith 16748b0a5094SBarry Smith Notes: 16758b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 16768b0a5094SBarry Smith 16778b0a5094SBarry 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} 16788b0a5094SBarry 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. 16798b0a5094SBarry Smith 16808b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 16818b0a5094SBarry Smith 16820d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 16830d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 16848b0a5094SBarry Smith 16858b0a5094SBarry 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 16868b0a5094SBarry 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 16878b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 16888b0a5094SBarry Smith 16898b0a5094SBarry Smith Level: beginner 16908b0a5094SBarry Smith 16918b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 16928b0a5094SBarry Smith 16930d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 16948b0a5094SBarry Smith @*/ 16958b0a5094SBarry 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) 16968b0a5094SBarry Smith { 16978b0a5094SBarry Smith PetscErrorCode ierr; 16988b0a5094SBarry Smith PetscFunctionBegin; 16998b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17008b0a5094SBarry Smith snes->ops->computepfunction = func; 17018b0a5094SBarry Smith snes->ops->computepjacobian = mfunc; 17028b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 17038b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 17048b0a5094SBarry Smith PetscFunctionReturn(0); 17058b0a5094SBarry Smith } 17068b0a5094SBarry Smith 17078b0a5094SBarry Smith #undef __FUNCT__ 1708d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1709d25893d9SBarry Smith /*@C 1710d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1711d25893d9SBarry Smith 1712d25893d9SBarry Smith Logically Collective on SNES 1713d25893d9SBarry Smith 1714d25893d9SBarry Smith Input Parameters: 1715d25893d9SBarry Smith + snes - the SNES context 1716d25893d9SBarry Smith . func - function evaluation routine 1717d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1718d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1719d25893d9SBarry Smith 1720d25893d9SBarry Smith Calling sequence of func: 1721d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1722d25893d9SBarry Smith 1723d25893d9SBarry Smith . f - function vector 1724d25893d9SBarry Smith - ctx - optional user-defined function context 1725d25893d9SBarry Smith 1726d25893d9SBarry Smith Level: intermediate 1727d25893d9SBarry Smith 1728d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1729d25893d9SBarry Smith 1730d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1731d25893d9SBarry Smith @*/ 1732d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1733d25893d9SBarry Smith { 1734d25893d9SBarry Smith PetscFunctionBegin; 1735d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1736d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1737d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1738d25893d9SBarry Smith PetscFunctionReturn(0); 1739d25893d9SBarry Smith } 1740d25893d9SBarry Smith 17413ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 17423ab0aad5SBarry Smith #undef __FUNCT__ 17431096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 17441096aae1SMatthew Knepley /*@C 17451096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 17461096aae1SMatthew Knepley it assumes a zero right hand side. 17471096aae1SMatthew Knepley 17483f9fe445SBarry Smith Logically Collective on SNES 17491096aae1SMatthew Knepley 17501096aae1SMatthew Knepley Input Parameter: 17511096aae1SMatthew Knepley . snes - the SNES context 17521096aae1SMatthew Knepley 17531096aae1SMatthew Knepley Output Parameter: 1754bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 17551096aae1SMatthew Knepley 17561096aae1SMatthew Knepley Level: intermediate 17571096aae1SMatthew Knepley 17581096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 17591096aae1SMatthew Knepley 176085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 17611096aae1SMatthew Knepley @*/ 17627087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 17631096aae1SMatthew Knepley { 17641096aae1SMatthew Knepley PetscFunctionBegin; 17650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17661096aae1SMatthew Knepley PetscValidPointer(rhs,2); 176785385478SLisandro Dalcin *rhs = snes->vec_rhs; 17681096aae1SMatthew Knepley PetscFunctionReturn(0); 17691096aae1SMatthew Knepley } 17701096aae1SMatthew Knepley 17711096aae1SMatthew Knepley #undef __FUNCT__ 17724a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 17739b94acceSBarry Smith /*@ 177436851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 17759b94acceSBarry Smith SNESSetFunction(). 17769b94acceSBarry Smith 1777c7afd0dbSLois Curfman McInnes Collective on SNES 1778c7afd0dbSLois Curfman McInnes 17799b94acceSBarry Smith Input Parameters: 1780c7afd0dbSLois Curfman McInnes + snes - the SNES context 1781c7afd0dbSLois Curfman McInnes - x - input vector 17829b94acceSBarry Smith 17839b94acceSBarry Smith Output Parameter: 17843638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 17859b94acceSBarry Smith 17861bffabb2SLois Curfman McInnes Notes: 178736851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 178836851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 178936851e7fSLois Curfman McInnes themselves. 179036851e7fSLois Curfman McInnes 179136851e7fSLois Curfman McInnes Level: developer 179236851e7fSLois Curfman McInnes 17939b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 17949b94acceSBarry Smith 1795a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 17969b94acceSBarry Smith @*/ 17977087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 17989b94acceSBarry Smith { 1799dfbe8321SBarry Smith PetscErrorCode ierr; 18006cab3a1bSJed Brown DM dm; 18016cab3a1bSJed Brown SNESDM sdm; 18029b94acceSBarry Smith 18033a40ed3dSBarry Smith PetscFunctionBegin; 18040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18050700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 18060700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1807c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1808c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 18094ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1810184914b5SBarry Smith 18116cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18126cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1813d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18146cab3a1bSJed Brown if (sdm->computefunction) { 1815d64ed03dSBarry Smith PetscStackPush("SNES user function"); 18166cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1817d64ed03dSBarry Smith PetscStackPop; 181873250ac0SBarry Smith } else if (snes->dm) { 1819644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1820c90fad12SPeter Brune } else if (snes->vec_rhs) { 1821c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1822644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 182385385478SLisandro Dalcin if (snes->vec_rhs) { 182485385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 18253ab0aad5SBarry Smith } 1826ae3c334cSLois Curfman McInnes snes->nfuncs++; 1827d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18284ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 18293a40ed3dSBarry Smith PetscFunctionReturn(0); 18309b94acceSBarry Smith } 18319b94acceSBarry Smith 18324a2ae208SSatish Balay #undef __FUNCT__ 1833646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1834c79ef259SPeter Brune /*@ 1835c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1836c79ef259SPeter Brune SNESSetGS(). 1837c79ef259SPeter Brune 1838c79ef259SPeter Brune Collective on SNES 1839c79ef259SPeter Brune 1840c79ef259SPeter Brune Input Parameters: 1841c79ef259SPeter Brune + snes - the SNES context 1842c79ef259SPeter Brune . x - input vector 1843c79ef259SPeter Brune - b - rhs vector 1844c79ef259SPeter Brune 1845c79ef259SPeter Brune Output Parameter: 1846c79ef259SPeter Brune . x - new solution vector 1847c79ef259SPeter Brune 1848c79ef259SPeter Brune Notes: 1849c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1850c79ef259SPeter Brune implementations, so most users would not generally call this routine 1851c79ef259SPeter Brune themselves. 1852c79ef259SPeter Brune 1853c79ef259SPeter Brune Level: developer 1854c79ef259SPeter Brune 1855c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1856c79ef259SPeter Brune 1857c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1858c79ef259SPeter Brune @*/ 1859646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1860646217ecSPeter Brune { 1861646217ecSPeter Brune PetscErrorCode ierr; 186289b92e6fSPeter Brune PetscInt i; 18636cab3a1bSJed Brown DM dm; 18646cab3a1bSJed Brown SNESDM sdm; 1865646217ecSPeter Brune 1866646217ecSPeter Brune PetscFunctionBegin; 1867646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1868646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1869646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1870646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1871646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 18724ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1873701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 18746cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18756cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 18766cab3a1bSJed Brown if (sdm->computegs) { 187789b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1878646217ecSPeter Brune PetscStackPush("SNES user GS"); 18796cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1880646217ecSPeter Brune PetscStackPop; 188189b92e6fSPeter Brune } 1882646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1883701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 18844ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1885646217ecSPeter Brune PetscFunctionReturn(0); 1886646217ecSPeter Brune } 1887646217ecSPeter Brune 1888646217ecSPeter Brune 1889646217ecSPeter Brune #undef __FUNCT__ 18904a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 189162fef451SLois Curfman McInnes /*@ 189262fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 189362fef451SLois Curfman McInnes set with SNESSetJacobian(). 189462fef451SLois Curfman McInnes 1895c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1896c7afd0dbSLois Curfman McInnes 189762fef451SLois Curfman McInnes Input Parameters: 1898c7afd0dbSLois Curfman McInnes + snes - the SNES context 1899c7afd0dbSLois Curfman McInnes - x - input vector 190062fef451SLois Curfman McInnes 190162fef451SLois Curfman McInnes Output Parameters: 1902c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 190362fef451SLois Curfman McInnes . B - optional preconditioning matrix 19042b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1905fee21e36SBarry Smith 1906e35cf81dSBarry Smith Options Database Keys: 1907e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1908693365a8SJed Brown . -snes_lag_jacobian <lag> 1909693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1910693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1911693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 19124c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1913c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1914c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1915c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1916c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1917c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 19184c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1919c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1920c01495d3SJed Brown 1921e35cf81dSBarry Smith 192262fef451SLois Curfman McInnes Notes: 192362fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 192462fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 192562fef451SLois Curfman McInnes 192694b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1927dc5a77f8SLois Curfman McInnes flag parameter. 192862fef451SLois Curfman McInnes 192936851e7fSLois Curfman McInnes Level: developer 193036851e7fSLois Curfman McInnes 193162fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 193262fef451SLois Curfman McInnes 1933e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 193462fef451SLois Curfman McInnes @*/ 19357087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 19369b94acceSBarry Smith { 1937dfbe8321SBarry Smith PetscErrorCode ierr; 1938ace3abfcSBarry Smith PetscBool flag; 19396cab3a1bSJed Brown DM dm; 19406cab3a1bSJed Brown SNESDM sdm; 19413a40ed3dSBarry Smith 19423a40ed3dSBarry Smith PetscFunctionBegin; 19430700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 19440700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 19454482741eSBarry Smith PetscValidPointer(flg,5); 1946c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 19474ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 19486cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19496cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19506cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 1951ebd3b9afSBarry Smith 1952ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 1953ebd3b9afSBarry Smith 1954fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 1955fe3ffe1eSBarry Smith snes->lagjacobian = -1; 1956fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 1957fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 1958e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1959e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 1960251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1961ebd3b9afSBarry Smith if (flag) { 1962ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1963ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1964ebd3b9afSBarry Smith } 1965e35cf81dSBarry Smith PetscFunctionReturn(0); 1966e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 1967e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 1968e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 1969251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 1970ebd3b9afSBarry Smith if (flag) { 1971ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1972ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1973ebd3b9afSBarry Smith } 1974e35cf81dSBarry Smith PetscFunctionReturn(0); 1975e35cf81dSBarry Smith } 1976e35cf81dSBarry Smith 1977c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 1978e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1979d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 19806cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 1981d64ed03dSBarry Smith PetscStackPop; 1982d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 1983a8054027SBarry Smith 19843b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 19853b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 19863b4f5425SBarry Smith snes->lagpreconditioner = -1; 19873b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 1988a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1989a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 1990a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 1991a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 1992a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 1993a8054027SBarry Smith } 1994a8054027SBarry Smith 19956d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 19960700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 19970700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 1998693365a8SJed Brown { 1999693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2000693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 2001693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 2002693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 2003693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 2004693365a8SJed Brown if (flag || flag_draw || flag_contour) { 2005693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 2006693365a8SJed Brown MatStructure mstruct; 2007693365a8SJed Brown PetscViewer vdraw,vstdout; 20086b3a5b13SJed Brown PetscBool flg; 2009693365a8SJed Brown if (flag_operator) { 2010693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 2011693365a8SJed Brown Bexp = Bexp_mine; 2012693365a8SJed Brown } else { 2013693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2014251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2015693365a8SJed Brown if (flg) Bexp = *B; 2016693365a8SJed Brown else { 2017693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2018693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 2019693365a8SJed Brown Bexp = Bexp_mine; 2020693365a8SJed Brown } 2021693365a8SJed Brown } 2022693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2023693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 2024693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 2025693365a8SJed Brown if (flag_draw || flag_contour) { 2026693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2027693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2028693365a8SJed Brown } else vdraw = PETSC_NULL; 2029693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 2030693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2031693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2032693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2033693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2034693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2035693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2036693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2037693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2038693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2039693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2040693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2041693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2042693365a8SJed Brown } 2043693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2044693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2045693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2046693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2047693365a8SJed Brown } 2048693365a8SJed Brown } 20494c30e9fbSJed Brown { 20506719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 20516719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 20524c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 20536719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 20544c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 20554c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 20566719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 20576719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 20586719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 20596719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 20604c30e9fbSJed Brown Mat Bfd; 20614c30e9fbSJed Brown MatStructure mstruct; 20624c30e9fbSJed Brown PetscViewer vdraw,vstdout; 20634c30e9fbSJed Brown ISColoring iscoloring; 20644c30e9fbSJed Brown MatFDColoring matfdcoloring; 20654c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 20664c30e9fbSJed Brown void *funcctx; 20676719d8e4SJed Brown PetscReal norm1,norm2,normmax; 20684c30e9fbSJed Brown 20694c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 20704c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 20714c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 20724c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 20734c30e9fbSJed Brown 20744c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 20754c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 20764c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 20774c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 20784c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 20794c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 20804c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 20814c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 20824c30e9fbSJed Brown 20834c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 20844c30e9fbSJed Brown if (flag_draw || flag_contour) { 20854c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 20864c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 20874c30e9fbSJed Brown } else vdraw = PETSC_NULL; 20884c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 20896719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 20904c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 20914c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 20926719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 20934c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 20944c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 20954c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 20966719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 20974c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 20986719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 20996719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21004c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 21014c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 21024c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 21034c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 21044c30e9fbSJed Brown } 21054c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 21066719d8e4SJed Brown 21076719d8e4SJed Brown if (flag_threshold) { 21086719d8e4SJed Brown PetscInt bs,rstart,rend,i; 21096719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 21106719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 21116719d8e4SJed Brown for (i=rstart; i<rend; i++) { 21126719d8e4SJed Brown const PetscScalar *ba,*ca; 21136719d8e4SJed Brown const PetscInt *bj,*cj; 21146719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 21156719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 21166719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21176719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21186719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 21196719d8e4SJed Brown for (j=0; j<bn; j++) { 21206719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21216719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 21226719d8e4SJed Brown maxentrycol = bj[j]; 21236719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 21246719d8e4SJed Brown } 21256719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 21266719d8e4SJed Brown maxdiffcol = bj[j]; 21276719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 21286719d8e4SJed Brown } 21296719d8e4SJed Brown if (rdiff > maxrdiff) { 21306719d8e4SJed Brown maxrdiffcol = bj[j]; 21316719d8e4SJed Brown maxrdiff = rdiff; 21326719d8e4SJed Brown } 21336719d8e4SJed Brown } 21346719d8e4SJed Brown if (maxrdiff > 1) { 21356719d8e4SJed 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); 21366719d8e4SJed Brown for (j=0; j<bn; j++) { 21376719d8e4SJed Brown PetscReal rdiff; 21386719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21396719d8e4SJed Brown if (rdiff > 1) { 21406719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 21416719d8e4SJed Brown } 21426719d8e4SJed Brown } 21436719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 21446719d8e4SJed Brown } 21456719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21466719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21476719d8e4SJed Brown } 21486719d8e4SJed Brown } 21494c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 21504c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 21514c30e9fbSJed Brown } 21524c30e9fbSJed Brown } 21533a40ed3dSBarry Smith PetscFunctionReturn(0); 21549b94acceSBarry Smith } 21559b94acceSBarry Smith 21564a2ae208SSatish Balay #undef __FUNCT__ 21574a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 21589b94acceSBarry Smith /*@C 21599b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2160044dda88SLois Curfman McInnes location to store the matrix. 21619b94acceSBarry Smith 21623f9fe445SBarry Smith Logically Collective on SNES and Mat 2163c7afd0dbSLois Curfman McInnes 21649b94acceSBarry Smith Input Parameters: 2165c7afd0dbSLois Curfman McInnes + snes - the SNES context 21669b94acceSBarry Smith . A - Jacobian matrix 21679b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2168efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2169c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2170efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 21719b94acceSBarry Smith 21729b94acceSBarry Smith Calling sequence of func: 21738d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 21749b94acceSBarry Smith 2175c7afd0dbSLois Curfman McInnes + x - input vector 21769b94acceSBarry Smith . A - Jacobian matrix 21779b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2178ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 21792b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2180c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 21819b94acceSBarry Smith 21829b94acceSBarry Smith Notes: 218394b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 21842cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2185ac21db08SLois Curfman McInnes 2186ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 21879b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 21889b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 21899b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 21909b94acceSBarry Smith throughout the global iterations. 21919b94acceSBarry Smith 219216913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 219316913363SBarry Smith each matrix. 219416913363SBarry Smith 2195a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2196a8a26c1eSJed Brown must be a MatFDColoring. 2197a8a26c1eSJed Brown 2198c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2199c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2200c3cc8fd1SJed Brown 220136851e7fSLois Curfman McInnes Level: beginner 220236851e7fSLois Curfman McInnes 22039b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 22049b94acceSBarry Smith 22053ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 22069b94acceSBarry Smith @*/ 22077087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 22089b94acceSBarry Smith { 2209dfbe8321SBarry Smith PetscErrorCode ierr; 22106cab3a1bSJed Brown DM dm; 22113a7fca6bSBarry Smith 22123a40ed3dSBarry Smith PetscFunctionBegin; 22130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22140700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 22150700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2216c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 221706975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 22186cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22196cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 22203a7fca6bSBarry Smith if (A) { 22217dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22226bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22239b94acceSBarry Smith snes->jacobian = A; 22243a7fca6bSBarry Smith } 22253a7fca6bSBarry Smith if (B) { 22267dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 22276bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 22289b94acceSBarry Smith snes->jacobian_pre = B; 22293a7fca6bSBarry Smith } 22303a40ed3dSBarry Smith PetscFunctionReturn(0); 22319b94acceSBarry Smith } 223262fef451SLois Curfman McInnes 22334a2ae208SSatish Balay #undef __FUNCT__ 22344a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2235c2aafc4cSSatish Balay /*@C 2236b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2237b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2238b4fd4287SBarry Smith 2239c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2240c7afd0dbSLois Curfman McInnes 2241b4fd4287SBarry Smith Input Parameter: 2242b4fd4287SBarry Smith . snes - the nonlinear solver context 2243b4fd4287SBarry Smith 2244b4fd4287SBarry Smith Output Parameters: 2245c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2246b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 224770e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 224870e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2249fee21e36SBarry Smith 225036851e7fSLois Curfman McInnes Level: advanced 225136851e7fSLois Curfman McInnes 2252b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2253b4fd4287SBarry Smith @*/ 22547087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2255b4fd4287SBarry Smith { 22566cab3a1bSJed Brown PetscErrorCode ierr; 22576cab3a1bSJed Brown DM dm; 22586cab3a1bSJed Brown SNESDM sdm; 22596cab3a1bSJed Brown 22603a40ed3dSBarry Smith PetscFunctionBegin; 22610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2262b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2263b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 22646cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22656cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 22666cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 22676cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 22683a40ed3dSBarry Smith PetscFunctionReturn(0); 2269b4fd4287SBarry Smith } 2270b4fd4287SBarry Smith 22719b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 22729b94acceSBarry Smith 22734a2ae208SSatish Balay #undef __FUNCT__ 22744a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 22759b94acceSBarry Smith /*@ 22769b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2277272ac6f2SLois Curfman McInnes of a nonlinear solver. 22789b94acceSBarry Smith 2279fee21e36SBarry Smith Collective on SNES 2280fee21e36SBarry Smith 2281c7afd0dbSLois Curfman McInnes Input Parameters: 228270e92668SMatthew Knepley . snes - the SNES context 2283c7afd0dbSLois Curfman McInnes 2284272ac6f2SLois Curfman McInnes Notes: 2285272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2286272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2287272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2288272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2289272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2290272ac6f2SLois Curfman McInnes 229136851e7fSLois Curfman McInnes Level: advanced 229236851e7fSLois Curfman McInnes 22939b94acceSBarry Smith .keywords: SNES, nonlinear, setup 22949b94acceSBarry Smith 22959b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 22969b94acceSBarry Smith @*/ 22977087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 22989b94acceSBarry Smith { 2299dfbe8321SBarry Smith PetscErrorCode ierr; 23006cab3a1bSJed Brown DM dm; 23016cab3a1bSJed Brown SNESDM sdm; 23026e2a1849SPeter Brune SNESLineSearch linesearch; 23036e2a1849SPeter Brune SNESLineSearch pclinesearch; 23046e2a1849SPeter Brune void *lsprectx,*lspostctx; 23056e2a1849SPeter Brune SNESLineSearchPreCheckFunc lsprefunc; 23066e2a1849SPeter Brune SNESLineSearchPostCheckFunc lspostfunc; 23076e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 23086e2a1849SPeter Brune Vec f,fpc; 23096e2a1849SPeter Brune void *funcctx; 23106e2a1849SPeter Brune PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 23116e2a1849SPeter Brune void *jacctx; 23126e2a1849SPeter Brune Mat A,B; 23133a40ed3dSBarry Smith 23143a40ed3dSBarry Smith PetscFunctionBegin; 23150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23164dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 23179b94acceSBarry Smith 23187adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 231985385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 232085385478SLisandro Dalcin } 232185385478SLisandro Dalcin 2322a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 232317186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 232458c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 232558c9b817SLisandro Dalcin 232658c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 232758c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 232858c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 232958c9b817SLisandro Dalcin } 233058c9b817SLisandro Dalcin 23316cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23326cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 23336cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23346cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 23356cab3a1bSJed Brown if (!snes->vec_func) { 23366cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2337214df951SJed Brown } 2338efd51863SBarry Smith 2339b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2340b710008aSBarry Smith 2341f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 23429e764e56SPeter Brune 2343d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2344d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2345d25893d9SBarry Smith } 2346d25893d9SBarry Smith 23476e2a1849SPeter Brune if (snes->pc) { 23486e2a1849SPeter Brune /* copy the DM over */ 23496e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23506e2a1849SPeter Brune ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr); 23516e2a1849SPeter Brune 23526e2a1849SPeter Brune /* copy the legacy SNES context not related to the DM over*/ 23536e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 23546e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 23556e2a1849SPeter Brune ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr); 23566e2a1849SPeter Brune ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr); 23576e2a1849SPeter Brune ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr); 23586e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 23596e2a1849SPeter Brune 23606e2a1849SPeter Brune /* copy the function pointers over */ 23616e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr); 23626e2a1849SPeter Brune 23636e2a1849SPeter Brune /* default to 1 iteration */ 23646e2a1849SPeter Brune ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr); 23656e2a1849SPeter Brune ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 23666e2a1849SPeter Brune ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 23676e2a1849SPeter Brune 23686e2a1849SPeter Brune /* copy the line search context over */ 23696e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr); 23706e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr); 23716e2a1849SPeter Brune ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr); 23726e2a1849SPeter Brune ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr); 23736e2a1849SPeter Brune ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr); 23746e2a1849SPeter Brune ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr); 23756e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 23766e2a1849SPeter Brune } 23776e2a1849SPeter Brune 2378410397dcSLisandro Dalcin if (snes->ops->setup) { 2379410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2380410397dcSLisandro Dalcin } 238158c9b817SLisandro Dalcin 23827aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 23833a40ed3dSBarry Smith PetscFunctionReturn(0); 23849b94acceSBarry Smith } 23859b94acceSBarry Smith 23864a2ae208SSatish Balay #undef __FUNCT__ 238737596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 238837596af1SLisandro Dalcin /*@ 238937596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 239037596af1SLisandro Dalcin 239137596af1SLisandro Dalcin Collective on SNES 239237596af1SLisandro Dalcin 239337596af1SLisandro Dalcin Input Parameter: 239437596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 239537596af1SLisandro Dalcin 2396d25893d9SBarry Smith Level: intermediate 2397d25893d9SBarry Smith 2398d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 239937596af1SLisandro Dalcin 240037596af1SLisandro Dalcin .keywords: SNES, destroy 240137596af1SLisandro Dalcin 240237596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 240337596af1SLisandro Dalcin @*/ 240437596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 240537596af1SLisandro Dalcin { 240637596af1SLisandro Dalcin PetscErrorCode ierr; 240737596af1SLisandro Dalcin 240837596af1SLisandro Dalcin PetscFunctionBegin; 240937596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2410d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2411d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2412d25893d9SBarry Smith snes->user = PETSC_NULL; 2413d25893d9SBarry Smith } 24148a23116dSBarry Smith if (snes->pc) { 24158a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 24168a23116dSBarry Smith } 24178a23116dSBarry Smith 241837596af1SLisandro Dalcin if (snes->ops->reset) { 241937596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 242037596af1SLisandro Dalcin } 24219e764e56SPeter Brune if (snes->ksp) { 24229e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 24239e764e56SPeter Brune } 24249e764e56SPeter Brune 24259e764e56SPeter Brune if (snes->linesearch) { 2426f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 24279e764e56SPeter Brune } 24289e764e56SPeter Brune 24296bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 24306bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 24316bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 24326bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 24336bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 24346bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2435c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2436c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 243737596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 243837596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 243937596af1SLisandro Dalcin PetscFunctionReturn(0); 244037596af1SLisandro Dalcin } 244137596af1SLisandro Dalcin 244237596af1SLisandro Dalcin #undef __FUNCT__ 24434a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 244452baeb72SSatish Balay /*@ 24459b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 24469b94acceSBarry Smith with SNESCreate(). 24479b94acceSBarry Smith 2448c7afd0dbSLois Curfman McInnes Collective on SNES 2449c7afd0dbSLois Curfman McInnes 24509b94acceSBarry Smith Input Parameter: 24519b94acceSBarry Smith . snes - the SNES context 24529b94acceSBarry Smith 245336851e7fSLois Curfman McInnes Level: beginner 245436851e7fSLois Curfman McInnes 24559b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 24569b94acceSBarry Smith 245763a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 24589b94acceSBarry Smith @*/ 24596bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 24609b94acceSBarry Smith { 24616849ba73SBarry Smith PetscErrorCode ierr; 24623a40ed3dSBarry Smith 24633a40ed3dSBarry Smith PetscFunctionBegin; 24646bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 24656bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 24666bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2467d4bb536fSBarry Smith 24686bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 24698a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 24706b8b9a38SLisandro Dalcin 2471be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 24726bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 24736bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 24746d4c513bSLisandro Dalcin 24756bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 24766bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2477f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 24786b8b9a38SLisandro Dalcin 24796bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 24806bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 24816bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 24826b8b9a38SLisandro Dalcin } 24836bf464f9SBarry Smith if ((*snes)->conv_malloc) { 24846bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 24856bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 248658c9b817SLisandro Dalcin } 24876bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2488a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 24893a40ed3dSBarry Smith PetscFunctionReturn(0); 24909b94acceSBarry Smith } 24919b94acceSBarry Smith 24929b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 24939b94acceSBarry Smith 24944a2ae208SSatish Balay #undef __FUNCT__ 2495a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2496a8054027SBarry Smith /*@ 2497a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2498a8054027SBarry Smith 24993f9fe445SBarry Smith Logically Collective on SNES 2500a8054027SBarry Smith 2501a8054027SBarry Smith Input Parameters: 2502a8054027SBarry Smith + snes - the SNES context 2503a8054027SBarry 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 25043b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2505a8054027SBarry Smith 2506a8054027SBarry Smith Options Database Keys: 2507a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2508a8054027SBarry Smith 2509a8054027SBarry Smith Notes: 2510a8054027SBarry Smith The default is 1 2511a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2512a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2513a8054027SBarry Smith 2514a8054027SBarry Smith Level: intermediate 2515a8054027SBarry Smith 2516a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2517a8054027SBarry Smith 2518e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2519a8054027SBarry Smith 2520a8054027SBarry Smith @*/ 25217087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2522a8054027SBarry Smith { 2523a8054027SBarry Smith PetscFunctionBegin; 25240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2525e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2526e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2527c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2528a8054027SBarry Smith snes->lagpreconditioner = lag; 2529a8054027SBarry Smith PetscFunctionReturn(0); 2530a8054027SBarry Smith } 2531a8054027SBarry Smith 2532a8054027SBarry Smith #undef __FUNCT__ 2533efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2534efd51863SBarry Smith /*@ 2535efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2536efd51863SBarry Smith 2537efd51863SBarry Smith Logically Collective on SNES 2538efd51863SBarry Smith 2539efd51863SBarry Smith Input Parameters: 2540efd51863SBarry Smith + snes - the SNES context 2541efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2542efd51863SBarry Smith 2543efd51863SBarry Smith Options Database Keys: 2544efd51863SBarry Smith . -snes_grid_sequence <steps> 2545efd51863SBarry Smith 2546efd51863SBarry Smith Level: intermediate 2547efd51863SBarry Smith 2548c0df2a02SJed Brown Notes: 2549c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2550c0df2a02SJed Brown 2551efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2552efd51863SBarry Smith 2553efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2554efd51863SBarry Smith 2555efd51863SBarry Smith @*/ 2556efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2557efd51863SBarry Smith { 2558efd51863SBarry Smith PetscFunctionBegin; 2559efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2560efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2561efd51863SBarry Smith snes->gridsequence = steps; 2562efd51863SBarry Smith PetscFunctionReturn(0); 2563efd51863SBarry Smith } 2564efd51863SBarry Smith 2565efd51863SBarry Smith #undef __FUNCT__ 2566a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2567a8054027SBarry Smith /*@ 2568a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2569a8054027SBarry Smith 25703f9fe445SBarry Smith Not Collective 2571a8054027SBarry Smith 2572a8054027SBarry Smith Input Parameter: 2573a8054027SBarry Smith . snes - the SNES context 2574a8054027SBarry Smith 2575a8054027SBarry Smith Output Parameter: 2576a8054027SBarry 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 25773b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2578a8054027SBarry Smith 2579a8054027SBarry Smith Options Database Keys: 2580a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2581a8054027SBarry Smith 2582a8054027SBarry Smith Notes: 2583a8054027SBarry Smith The default is 1 2584a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2585a8054027SBarry Smith 2586a8054027SBarry Smith Level: intermediate 2587a8054027SBarry Smith 2588a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2589a8054027SBarry Smith 2590a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2591a8054027SBarry Smith 2592a8054027SBarry Smith @*/ 25937087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2594a8054027SBarry Smith { 2595a8054027SBarry Smith PetscFunctionBegin; 25960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2597a8054027SBarry Smith *lag = snes->lagpreconditioner; 2598a8054027SBarry Smith PetscFunctionReturn(0); 2599a8054027SBarry Smith } 2600a8054027SBarry Smith 2601a8054027SBarry Smith #undef __FUNCT__ 2602e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2603e35cf81dSBarry Smith /*@ 2604e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2605e35cf81dSBarry Smith often the preconditioner is rebuilt. 2606e35cf81dSBarry Smith 26073f9fe445SBarry Smith Logically Collective on SNES 2608e35cf81dSBarry Smith 2609e35cf81dSBarry Smith Input Parameters: 2610e35cf81dSBarry Smith + snes - the SNES context 2611e35cf81dSBarry 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 2612fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2613e35cf81dSBarry Smith 2614e35cf81dSBarry Smith Options Database Keys: 2615e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2616e35cf81dSBarry Smith 2617e35cf81dSBarry Smith Notes: 2618e35cf81dSBarry Smith The default is 1 2619e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2620fe3ffe1eSBarry 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 2621fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2622e35cf81dSBarry Smith 2623e35cf81dSBarry Smith Level: intermediate 2624e35cf81dSBarry Smith 2625e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2626e35cf81dSBarry Smith 2627e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2628e35cf81dSBarry Smith 2629e35cf81dSBarry Smith @*/ 26307087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2631e35cf81dSBarry Smith { 2632e35cf81dSBarry Smith PetscFunctionBegin; 26330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2634e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2635e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2636c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2637e35cf81dSBarry Smith snes->lagjacobian = lag; 2638e35cf81dSBarry Smith PetscFunctionReturn(0); 2639e35cf81dSBarry Smith } 2640e35cf81dSBarry Smith 2641e35cf81dSBarry Smith #undef __FUNCT__ 2642e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2643e35cf81dSBarry Smith /*@ 2644e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2645e35cf81dSBarry Smith 26463f9fe445SBarry Smith Not Collective 2647e35cf81dSBarry Smith 2648e35cf81dSBarry Smith Input Parameter: 2649e35cf81dSBarry Smith . snes - the SNES context 2650e35cf81dSBarry Smith 2651e35cf81dSBarry Smith Output Parameter: 2652e35cf81dSBarry 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 2653e35cf81dSBarry Smith the Jacobian is built etc. 2654e35cf81dSBarry Smith 2655e35cf81dSBarry Smith Options Database Keys: 2656e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2657e35cf81dSBarry Smith 2658e35cf81dSBarry Smith Notes: 2659e35cf81dSBarry Smith The default is 1 2660e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2661e35cf81dSBarry Smith 2662e35cf81dSBarry Smith Level: intermediate 2663e35cf81dSBarry Smith 2664e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2665e35cf81dSBarry Smith 2666e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2667e35cf81dSBarry Smith 2668e35cf81dSBarry Smith @*/ 26697087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2670e35cf81dSBarry Smith { 2671e35cf81dSBarry Smith PetscFunctionBegin; 26720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2673e35cf81dSBarry Smith *lag = snes->lagjacobian; 2674e35cf81dSBarry Smith PetscFunctionReturn(0); 2675e35cf81dSBarry Smith } 2676e35cf81dSBarry Smith 2677e35cf81dSBarry Smith #undef __FUNCT__ 26784a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 26799b94acceSBarry Smith /*@ 2680d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 26819b94acceSBarry Smith 26823f9fe445SBarry Smith Logically Collective on SNES 2683c7afd0dbSLois Curfman McInnes 26849b94acceSBarry Smith Input Parameters: 2685c7afd0dbSLois Curfman McInnes + snes - the SNES context 268670441072SBarry Smith . abstol - absolute convergence tolerance 268733174efeSLois Curfman McInnes . rtol - relative convergence tolerance 268833174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 268933174efeSLois Curfman McInnes of the change in the solution between steps 269033174efeSLois Curfman McInnes . maxit - maximum number of iterations 2691c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2692fee21e36SBarry Smith 269333174efeSLois Curfman McInnes Options Database Keys: 269470441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2695c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2696c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2697c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2698c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 26999b94acceSBarry Smith 2700d7a720efSLois Curfman McInnes Notes: 27019b94acceSBarry Smith The default maximum number of iterations is 50. 27029b94acceSBarry Smith The default maximum number of function evaluations is 1000. 27039b94acceSBarry Smith 270436851e7fSLois Curfman McInnes Level: intermediate 270536851e7fSLois Curfman McInnes 270633174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 27079b94acceSBarry Smith 27082492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 27099b94acceSBarry Smith @*/ 27107087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 27119b94acceSBarry Smith { 27123a40ed3dSBarry Smith PetscFunctionBegin; 27130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2714c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2715c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2716c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2717c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2718c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2719c5eb9154SBarry Smith 2720ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2721ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2722ab54825eSJed Brown snes->abstol = abstol; 2723ab54825eSJed Brown } 2724ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2725ab54825eSJed 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); 2726ab54825eSJed Brown snes->rtol = rtol; 2727ab54825eSJed Brown } 2728ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2729ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2730c60f73f4SPeter Brune snes->stol = stol; 2731ab54825eSJed Brown } 2732ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2733ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2734ab54825eSJed Brown snes->max_its = maxit; 2735ab54825eSJed Brown } 2736ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2737ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2738ab54825eSJed Brown snes->max_funcs = maxf; 2739ab54825eSJed Brown } 274088976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 27413a40ed3dSBarry Smith PetscFunctionReturn(0); 27429b94acceSBarry Smith } 27439b94acceSBarry Smith 27444a2ae208SSatish Balay #undef __FUNCT__ 27454a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 27469b94acceSBarry Smith /*@ 274733174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 274833174efeSLois Curfman McInnes 2749c7afd0dbSLois Curfman McInnes Not Collective 2750c7afd0dbSLois Curfman McInnes 275133174efeSLois Curfman McInnes Input Parameters: 2752c7afd0dbSLois Curfman McInnes + snes - the SNES context 275385385478SLisandro Dalcin . atol - absolute convergence tolerance 275433174efeSLois Curfman McInnes . rtol - relative convergence tolerance 275533174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 275633174efeSLois Curfman McInnes of the change in the solution between steps 275733174efeSLois Curfman McInnes . maxit - maximum number of iterations 2758c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2759fee21e36SBarry Smith 276033174efeSLois Curfman McInnes Notes: 276133174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 276233174efeSLois Curfman McInnes 276336851e7fSLois Curfman McInnes Level: intermediate 276436851e7fSLois Curfman McInnes 276533174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 276633174efeSLois Curfman McInnes 276733174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 276833174efeSLois Curfman McInnes @*/ 27697087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 277033174efeSLois Curfman McInnes { 27713a40ed3dSBarry Smith PetscFunctionBegin; 27720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 277385385478SLisandro Dalcin if (atol) *atol = snes->abstol; 277433174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2775c60f73f4SPeter Brune if (stol) *stol = snes->stol; 277633174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 277733174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 27783a40ed3dSBarry Smith PetscFunctionReturn(0); 277933174efeSLois Curfman McInnes } 278033174efeSLois Curfman McInnes 27814a2ae208SSatish Balay #undef __FUNCT__ 27824a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 278333174efeSLois Curfman McInnes /*@ 27849b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 27859b94acceSBarry Smith 27863f9fe445SBarry Smith Logically Collective on SNES 2787fee21e36SBarry Smith 2788c7afd0dbSLois Curfman McInnes Input Parameters: 2789c7afd0dbSLois Curfman McInnes + snes - the SNES context 2790c7afd0dbSLois Curfman McInnes - tol - tolerance 2791c7afd0dbSLois Curfman McInnes 27929b94acceSBarry Smith Options Database Key: 2793c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 27949b94acceSBarry Smith 279536851e7fSLois Curfman McInnes Level: intermediate 279636851e7fSLois Curfman McInnes 27979b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 27989b94acceSBarry Smith 27992492ecdbSBarry Smith .seealso: SNESSetTolerances() 28009b94acceSBarry Smith @*/ 28017087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 28029b94acceSBarry Smith { 28033a40ed3dSBarry Smith PetscFunctionBegin; 28040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2805c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 28069b94acceSBarry Smith snes->deltatol = tol; 28073a40ed3dSBarry Smith PetscFunctionReturn(0); 28089b94acceSBarry Smith } 28099b94acceSBarry Smith 2810df9fa365SBarry Smith /* 2811df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2812df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2813df9fa365SBarry Smith macros instead of functions 2814df9fa365SBarry Smith */ 28154a2ae208SSatish Balay #undef __FUNCT__ 2816a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 28177087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2818ce1608b8SBarry Smith { 2819dfbe8321SBarry Smith PetscErrorCode ierr; 2820ce1608b8SBarry Smith 2821ce1608b8SBarry Smith PetscFunctionBegin; 28220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2823a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2824ce1608b8SBarry Smith PetscFunctionReturn(0); 2825ce1608b8SBarry Smith } 2826ce1608b8SBarry Smith 28274a2ae208SSatish Balay #undef __FUNCT__ 2828a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 28297087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2830df9fa365SBarry Smith { 2831dfbe8321SBarry Smith PetscErrorCode ierr; 2832df9fa365SBarry Smith 2833df9fa365SBarry Smith PetscFunctionBegin; 2834a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2835df9fa365SBarry Smith PetscFunctionReturn(0); 2836df9fa365SBarry Smith } 2837df9fa365SBarry Smith 28384a2ae208SSatish Balay #undef __FUNCT__ 2839a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 28406bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2841df9fa365SBarry Smith { 2842dfbe8321SBarry Smith PetscErrorCode ierr; 2843df9fa365SBarry Smith 2844df9fa365SBarry Smith PetscFunctionBegin; 2845a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2846df9fa365SBarry Smith PetscFunctionReturn(0); 2847df9fa365SBarry Smith } 2848df9fa365SBarry Smith 28497087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2850b271bb04SBarry Smith #undef __FUNCT__ 2851b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 28527087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2853b271bb04SBarry Smith { 2854b271bb04SBarry Smith PetscDrawLG lg; 2855b271bb04SBarry Smith PetscErrorCode ierr; 2856b271bb04SBarry Smith PetscReal x,y,per; 2857b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2858b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2859b271bb04SBarry Smith PetscDraw draw; 2860b271bb04SBarry Smith PetscFunctionBegin; 2861b271bb04SBarry Smith if (!monctx) { 2862b271bb04SBarry Smith MPI_Comm comm; 2863b271bb04SBarry Smith 2864b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2865b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2866b271bb04SBarry Smith } 2867b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2868b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2869b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2870b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2871b271bb04SBarry Smith x = (PetscReal) n; 2872b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2873b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2874b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2875b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2876b271bb04SBarry Smith } 2877b271bb04SBarry Smith 2878b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2879b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2880b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2881b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2882b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2883b271bb04SBarry Smith x = (PetscReal) n; 2884b271bb04SBarry Smith y = 100.0*per; 2885b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2886b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2887b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2888b271bb04SBarry Smith } 2889b271bb04SBarry Smith 2890b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2891b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2892b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2893b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2894b271bb04SBarry Smith x = (PetscReal) n; 2895b271bb04SBarry Smith y = (prev - rnorm)/prev; 2896b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2897b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2898b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2899b271bb04SBarry Smith } 2900b271bb04SBarry Smith 2901b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2902b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2903b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2904b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2905b271bb04SBarry Smith x = (PetscReal) n; 2906b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2907b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2908b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2909b271bb04SBarry Smith } 2910b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2911b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2912b271bb04SBarry Smith } 2913b271bb04SBarry Smith prev = rnorm; 2914b271bb04SBarry Smith PetscFunctionReturn(0); 2915b271bb04SBarry Smith } 2916b271bb04SBarry Smith 2917b271bb04SBarry Smith #undef __FUNCT__ 2918b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 29197087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2920b271bb04SBarry Smith { 2921b271bb04SBarry Smith PetscErrorCode ierr; 2922b271bb04SBarry Smith 2923b271bb04SBarry Smith PetscFunctionBegin; 2924b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2925b271bb04SBarry Smith PetscFunctionReturn(0); 2926b271bb04SBarry Smith } 2927b271bb04SBarry Smith 2928b271bb04SBarry Smith #undef __FUNCT__ 2929b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 29306bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2931b271bb04SBarry Smith { 2932b271bb04SBarry Smith PetscErrorCode ierr; 2933b271bb04SBarry Smith 2934b271bb04SBarry Smith PetscFunctionBegin; 2935b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2936b271bb04SBarry Smith PetscFunctionReturn(0); 2937b271bb04SBarry Smith } 2938b271bb04SBarry Smith 29397a03ce2fSLisandro Dalcin #undef __FUNCT__ 29407a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2941228d79bcSJed Brown /*@ 2942228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 2943228d79bcSJed Brown 2944228d79bcSJed Brown Collective on SNES 2945228d79bcSJed Brown 2946228d79bcSJed Brown Input Parameters: 2947228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 2948228d79bcSJed Brown . iter - iteration number 2949228d79bcSJed Brown - rnorm - relative norm of the residual 2950228d79bcSJed Brown 2951228d79bcSJed Brown Notes: 2952228d79bcSJed Brown This routine is called by the SNES implementations. 2953228d79bcSJed Brown It does not typically need to be called by the user. 2954228d79bcSJed Brown 2955228d79bcSJed Brown Level: developer 2956228d79bcSJed Brown 2957228d79bcSJed Brown .seealso: SNESMonitorSet() 2958228d79bcSJed Brown @*/ 29597a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 29607a03ce2fSLisandro Dalcin { 29617a03ce2fSLisandro Dalcin PetscErrorCode ierr; 29627a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 29637a03ce2fSLisandro Dalcin 29647a03ce2fSLisandro Dalcin PetscFunctionBegin; 29657a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 29667a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 29677a03ce2fSLisandro Dalcin } 29687a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 29697a03ce2fSLisandro Dalcin } 29707a03ce2fSLisandro Dalcin 29719b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 29729b94acceSBarry Smith 29734a2ae208SSatish Balay #undef __FUNCT__ 2974a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 29759b94acceSBarry Smith /*@C 2976a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 29779b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 29789b94acceSBarry Smith progress. 29799b94acceSBarry Smith 29803f9fe445SBarry Smith Logically Collective on SNES 2981fee21e36SBarry Smith 2982c7afd0dbSLois Curfman McInnes Input Parameters: 2983c7afd0dbSLois Curfman McInnes + snes - the SNES context 2984c7afd0dbSLois Curfman McInnes . func - monitoring routine 2985b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 2986e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 2987b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 2988b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 29899b94acceSBarry Smith 2990c7afd0dbSLois Curfman McInnes Calling sequence of func: 2991a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 2992c7afd0dbSLois Curfman McInnes 2993c7afd0dbSLois Curfman McInnes + snes - the SNES context 2994c7afd0dbSLois Curfman McInnes . its - iteration number 2995c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 299640a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 29979b94acceSBarry Smith 29989665c990SLois Curfman McInnes Options Database Keys: 2999a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 3000a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 3001a6570f20SBarry Smith uses SNESMonitorLGCreate() 3002cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3003c7afd0dbSLois Curfman McInnes been hardwired into a code by 3004a6570f20SBarry Smith calls to SNESMonitorSet(), but 3005c7afd0dbSLois Curfman McInnes does not cancel those set via 3006c7afd0dbSLois Curfman McInnes the options database. 30079665c990SLois Curfman McInnes 3008639f9d9dSBarry Smith Notes: 30096bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3010a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 30116bc08f3fSLois Curfman McInnes order in which they were set. 3012639f9d9dSBarry Smith 3013025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3014025f1a04SBarry Smith 301536851e7fSLois Curfman McInnes Level: intermediate 301636851e7fSLois Curfman McInnes 30179b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 30189b94acceSBarry Smith 3019a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 30209b94acceSBarry Smith @*/ 3021c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 30229b94acceSBarry Smith { 3023b90d0a6eSBarry Smith PetscInt i; 3024649052a6SBarry Smith PetscErrorCode ierr; 3025b90d0a6eSBarry Smith 30263a40ed3dSBarry Smith PetscFunctionBegin; 30270700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 302817186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3029b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 3030649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 3031649052a6SBarry Smith if (monitordestroy) { 3032c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3033649052a6SBarry Smith } 3034b90d0a6eSBarry Smith PetscFunctionReturn(0); 3035b90d0a6eSBarry Smith } 3036b90d0a6eSBarry Smith } 3037b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 3038b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3039639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 30403a40ed3dSBarry Smith PetscFunctionReturn(0); 30419b94acceSBarry Smith } 30429b94acceSBarry Smith 30434a2ae208SSatish Balay #undef __FUNCT__ 3044a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 30455cd90555SBarry Smith /*@C 3046a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 30475cd90555SBarry Smith 30483f9fe445SBarry Smith Logically Collective on SNES 3049c7afd0dbSLois Curfman McInnes 30505cd90555SBarry Smith Input Parameters: 30515cd90555SBarry Smith . snes - the SNES context 30525cd90555SBarry Smith 30531a480d89SAdministrator Options Database Key: 3054a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3055a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3056c7afd0dbSLois Curfman McInnes set via the options database 30575cd90555SBarry Smith 30585cd90555SBarry Smith Notes: 30595cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 30605cd90555SBarry Smith 306136851e7fSLois Curfman McInnes Level: intermediate 306236851e7fSLois Curfman McInnes 30635cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 30645cd90555SBarry Smith 3065a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 30665cd90555SBarry Smith @*/ 30677087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 30685cd90555SBarry Smith { 3069d952e501SBarry Smith PetscErrorCode ierr; 3070d952e501SBarry Smith PetscInt i; 3071d952e501SBarry Smith 30725cd90555SBarry Smith PetscFunctionBegin; 30730700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3074d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3075d952e501SBarry Smith if (snes->monitordestroy[i]) { 30763c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3077d952e501SBarry Smith } 3078d952e501SBarry Smith } 30795cd90555SBarry Smith snes->numbermonitors = 0; 30805cd90555SBarry Smith PetscFunctionReturn(0); 30815cd90555SBarry Smith } 30825cd90555SBarry Smith 30834a2ae208SSatish Balay #undef __FUNCT__ 30844a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 30859b94acceSBarry Smith /*@C 30869b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 30879b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 30889b94acceSBarry Smith 30893f9fe445SBarry Smith Logically Collective on SNES 3090fee21e36SBarry Smith 3091c7afd0dbSLois Curfman McInnes Input Parameters: 3092c7afd0dbSLois Curfman McInnes + snes - the SNES context 3093c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 30947f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 30957f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 30969b94acceSBarry Smith 3097c7afd0dbSLois Curfman McInnes Calling sequence of func: 309806ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3099c7afd0dbSLois Curfman McInnes 3100c7afd0dbSLois Curfman McInnes + snes - the SNES context 310106ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3102c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3103184914b5SBarry Smith . reason - reason for convergence/divergence 3104c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 31054b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 31064b27c08aSLois Curfman McInnes - f - 2-norm of function 31079b94acceSBarry Smith 310836851e7fSLois Curfman McInnes Level: advanced 310936851e7fSLois Curfman McInnes 31109b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 31119b94acceSBarry Smith 311285385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 31139b94acceSBarry Smith @*/ 31147087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 31159b94acceSBarry Smith { 31167f7931b9SBarry Smith PetscErrorCode ierr; 31177f7931b9SBarry Smith 31183a40ed3dSBarry Smith PetscFunctionBegin; 31190700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 312085385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 31217f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 31227f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 31237f7931b9SBarry Smith } 312485385478SLisandro Dalcin snes->ops->converged = func; 31257f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 312685385478SLisandro Dalcin snes->cnvP = cctx; 31273a40ed3dSBarry Smith PetscFunctionReturn(0); 31289b94acceSBarry Smith } 31299b94acceSBarry Smith 31304a2ae208SSatish Balay #undef __FUNCT__ 31314a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 313252baeb72SSatish Balay /*@ 3133184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3134184914b5SBarry Smith 3135184914b5SBarry Smith Not Collective 3136184914b5SBarry Smith 3137184914b5SBarry Smith Input Parameter: 3138184914b5SBarry Smith . snes - the SNES context 3139184914b5SBarry Smith 3140184914b5SBarry Smith Output Parameter: 31414d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3142184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3143184914b5SBarry Smith 3144184914b5SBarry Smith Level: intermediate 3145184914b5SBarry Smith 3146184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3147184914b5SBarry Smith 3148184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3149184914b5SBarry Smith 315085385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3151184914b5SBarry Smith @*/ 31527087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3153184914b5SBarry Smith { 3154184914b5SBarry Smith PetscFunctionBegin; 31550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31564482741eSBarry Smith PetscValidPointer(reason,2); 3157184914b5SBarry Smith *reason = snes->reason; 3158184914b5SBarry Smith PetscFunctionReturn(0); 3159184914b5SBarry Smith } 3160184914b5SBarry Smith 31614a2ae208SSatish Balay #undef __FUNCT__ 31624a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3163c9005455SLois Curfman McInnes /*@ 3164c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3165c9005455SLois Curfman McInnes 31663f9fe445SBarry Smith Logically Collective on SNES 3167fee21e36SBarry Smith 3168c7afd0dbSLois Curfman McInnes Input Parameters: 3169c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 31708c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3171cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3172758f92a0SBarry Smith . na - size of a and its 317364731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3174758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3175c7afd0dbSLois Curfman McInnes 3176308dcc3eSBarry Smith Notes: 3177308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3178308dcc3eSBarry Smith default array of length 10000 is allocated. 3179308dcc3eSBarry Smith 3180c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3181c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3182c9005455SLois Curfman McInnes during the section of code that is being timed. 3183c9005455SLois Curfman McInnes 318436851e7fSLois Curfman McInnes Level: intermediate 318536851e7fSLois Curfman McInnes 3186c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3187758f92a0SBarry Smith 318808405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3189758f92a0SBarry Smith 3190c9005455SLois Curfman McInnes @*/ 31917087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3192c9005455SLois Curfman McInnes { 3193308dcc3eSBarry Smith PetscErrorCode ierr; 3194308dcc3eSBarry Smith 31953a40ed3dSBarry Smith PetscFunctionBegin; 31960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 31974482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3198a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3199308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3200308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3201308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3202308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3203308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3204308dcc3eSBarry Smith } 3205c9005455SLois Curfman McInnes snes->conv_hist = a; 3206758f92a0SBarry Smith snes->conv_hist_its = its; 3207758f92a0SBarry Smith snes->conv_hist_max = na; 3208a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3209758f92a0SBarry Smith snes->conv_hist_reset = reset; 3210758f92a0SBarry Smith PetscFunctionReturn(0); 3211758f92a0SBarry Smith } 3212758f92a0SBarry Smith 3213308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3214c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3215c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3216308dcc3eSBarry Smith EXTERN_C_BEGIN 3217308dcc3eSBarry Smith #undef __FUNCT__ 3218308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3219308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3220308dcc3eSBarry Smith { 3221308dcc3eSBarry Smith mxArray *mat; 3222308dcc3eSBarry Smith PetscInt i; 3223308dcc3eSBarry Smith PetscReal *ar; 3224308dcc3eSBarry Smith 3225308dcc3eSBarry Smith PetscFunctionBegin; 3226308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3227308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3228308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3229308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3230308dcc3eSBarry Smith } 3231308dcc3eSBarry Smith PetscFunctionReturn(mat); 3232308dcc3eSBarry Smith } 3233308dcc3eSBarry Smith EXTERN_C_END 3234308dcc3eSBarry Smith #endif 3235308dcc3eSBarry Smith 3236308dcc3eSBarry Smith 32374a2ae208SSatish Balay #undef __FUNCT__ 32384a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 32390c4c9dddSBarry Smith /*@C 3240758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3241758f92a0SBarry Smith 32423f9fe445SBarry Smith Not Collective 3243758f92a0SBarry Smith 3244758f92a0SBarry Smith Input Parameter: 3245758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3246758f92a0SBarry Smith 3247758f92a0SBarry Smith Output Parameters: 3248758f92a0SBarry Smith . a - array to hold history 3249758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3250758f92a0SBarry Smith negative if not converged) for each solve. 3251758f92a0SBarry Smith - na - size of a and its 3252758f92a0SBarry Smith 3253758f92a0SBarry Smith Notes: 3254758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3255758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3256758f92a0SBarry Smith 3257758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3258758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3259758f92a0SBarry Smith during the section of code that is being timed. 3260758f92a0SBarry Smith 3261758f92a0SBarry Smith Level: intermediate 3262758f92a0SBarry Smith 3263758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3264758f92a0SBarry Smith 3265758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3266758f92a0SBarry Smith 3267758f92a0SBarry Smith @*/ 32687087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3269758f92a0SBarry Smith { 3270758f92a0SBarry Smith PetscFunctionBegin; 32710700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3272758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3273758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3274758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 32753a40ed3dSBarry Smith PetscFunctionReturn(0); 3276c9005455SLois Curfman McInnes } 3277c9005455SLois Curfman McInnes 3278e74ef692SMatthew Knepley #undef __FUNCT__ 3279e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3280ac226902SBarry Smith /*@C 328176b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3282eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 32837e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 328476b2cf59SMatthew Knepley 32853f9fe445SBarry Smith Logically Collective on SNES 328676b2cf59SMatthew Knepley 328776b2cf59SMatthew Knepley Input Parameters: 328876b2cf59SMatthew Knepley . snes - The nonlinear solver context 328976b2cf59SMatthew Knepley . func - The function 329076b2cf59SMatthew Knepley 329176b2cf59SMatthew Knepley Calling sequence of func: 3292b5d30489SBarry Smith . func (SNES snes, PetscInt step); 329376b2cf59SMatthew Knepley 329476b2cf59SMatthew Knepley . step - The current step of the iteration 329576b2cf59SMatthew Knepley 3296fe97e370SBarry Smith Level: advanced 3297fe97e370SBarry Smith 3298fe97e370SBarry 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() 3299fe97e370SBarry Smith This is not used by most users. 330076b2cf59SMatthew Knepley 330176b2cf59SMatthew Knepley .keywords: SNES, update 3302b5d30489SBarry Smith 330385385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 330476b2cf59SMatthew Knepley @*/ 33057087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 330676b2cf59SMatthew Knepley { 330776b2cf59SMatthew Knepley PetscFunctionBegin; 33080700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3309e7788613SBarry Smith snes->ops->update = func; 331076b2cf59SMatthew Knepley PetscFunctionReturn(0); 331176b2cf59SMatthew Knepley } 331276b2cf59SMatthew Knepley 3313e74ef692SMatthew Knepley #undef __FUNCT__ 3314e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 331576b2cf59SMatthew Knepley /*@ 331676b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 331776b2cf59SMatthew Knepley 331876b2cf59SMatthew Knepley Not collective 331976b2cf59SMatthew Knepley 332076b2cf59SMatthew Knepley Input Parameters: 332176b2cf59SMatthew Knepley . snes - The nonlinear solver context 332276b2cf59SMatthew Knepley . step - The current step of the iteration 332376b2cf59SMatthew Knepley 3324205452f4SMatthew Knepley Level: intermediate 3325205452f4SMatthew Knepley 332676b2cf59SMatthew Knepley .keywords: SNES, update 3327a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 332876b2cf59SMatthew Knepley @*/ 33297087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 333076b2cf59SMatthew Knepley { 333176b2cf59SMatthew Knepley PetscFunctionBegin; 333276b2cf59SMatthew Knepley PetscFunctionReturn(0); 333376b2cf59SMatthew Knepley } 333476b2cf59SMatthew Knepley 33354a2ae208SSatish Balay #undef __FUNCT__ 33364a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 33379b94acceSBarry Smith /* 33389b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 33399b94acceSBarry Smith positive parameter delta. 33409b94acceSBarry Smith 33419b94acceSBarry Smith Input Parameters: 3342c7afd0dbSLois Curfman McInnes + snes - the SNES context 33439b94acceSBarry Smith . y - approximate solution of linear system 33449b94acceSBarry Smith . fnorm - 2-norm of current function 3345c7afd0dbSLois Curfman McInnes - delta - trust region size 33469b94acceSBarry Smith 33479b94acceSBarry Smith Output Parameters: 3348c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 33499b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 33509b94acceSBarry Smith region, and exceeds zero otherwise. 3351c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 33529b94acceSBarry Smith 33539b94acceSBarry Smith Note: 33544b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 33559b94acceSBarry Smith is set to be the maximum allowable step size. 33569b94acceSBarry Smith 33579b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 33589b94acceSBarry Smith */ 3359dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 33609b94acceSBarry Smith { 3361064f8208SBarry Smith PetscReal nrm; 3362ea709b57SSatish Balay PetscScalar cnorm; 3363dfbe8321SBarry Smith PetscErrorCode ierr; 33643a40ed3dSBarry Smith 33653a40ed3dSBarry Smith PetscFunctionBegin; 33660700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 33670700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3368c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3369184914b5SBarry Smith 3370064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3371064f8208SBarry Smith if (nrm > *delta) { 3372064f8208SBarry Smith nrm = *delta/nrm; 3373064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3374064f8208SBarry Smith cnorm = nrm; 33752dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 33769b94acceSBarry Smith *ynorm = *delta; 33779b94acceSBarry Smith } else { 33789b94acceSBarry Smith *gpnorm = 0.0; 3379064f8208SBarry Smith *ynorm = nrm; 33809b94acceSBarry Smith } 33813a40ed3dSBarry Smith PetscFunctionReturn(0); 33829b94acceSBarry Smith } 33839b94acceSBarry Smith 33844a2ae208SSatish Balay #undef __FUNCT__ 33854a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 33866ce558aeSBarry Smith /*@C 3387f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3388f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 33899b94acceSBarry Smith 3390c7afd0dbSLois Curfman McInnes Collective on SNES 3391c7afd0dbSLois Curfman McInnes 3392b2002411SLois Curfman McInnes Input Parameters: 3393c7afd0dbSLois Curfman McInnes + snes - the SNES context 33943cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 339585385478SLisandro Dalcin - x - the solution vector. 33969b94acceSBarry Smith 3397b2002411SLois Curfman McInnes Notes: 33988ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 33998ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 34008ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 34018ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 34028ddd3da0SLois Curfman McInnes 340336851e7fSLois Curfman McInnes Level: beginner 340436851e7fSLois Curfman McInnes 34059b94acceSBarry Smith .keywords: SNES, nonlinear, solve 34069b94acceSBarry Smith 3407c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 34089b94acceSBarry Smith @*/ 34097087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 34109b94acceSBarry Smith { 3411dfbe8321SBarry Smith PetscErrorCode ierr; 3412ace3abfcSBarry Smith PetscBool flg; 3413eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3414eabae89aSBarry Smith PetscViewer viewer; 3415efd51863SBarry Smith PetscInt grid; 3416a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3417caa4e7f2SJed Brown DM dm; 3418052efed2SBarry Smith 34193a40ed3dSBarry Smith PetscFunctionBegin; 34200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3421a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3422a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 34230700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 342485385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 342585385478SLisandro Dalcin 3426caa4e7f2SJed Brown if (!x) { 3427caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3428caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3429a69afd8bSBarry Smith x = xcreated; 3430a69afd8bSBarry Smith } 3431a69afd8bSBarry Smith 3432a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3433efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3434efd51863SBarry Smith 343585385478SLisandro Dalcin /* set solution vector */ 3436efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 34376bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 343885385478SLisandro Dalcin snes->vec_sol = x; 3439caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3440caa4e7f2SJed Brown 3441caa4e7f2SJed Brown /* set affine vector if provided */ 344285385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 34436bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 344485385478SLisandro Dalcin snes->vec_rhs = b; 344585385478SLisandro Dalcin 344670e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 34473f149594SLisandro Dalcin 34487eee914bSBarry Smith if (!grid) { 34497eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3450d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3451dd568438SSatish Balay } else if (snes->dm) { 3452dd568438SSatish Balay PetscBool ig; 3453dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3454dd568438SSatish Balay if (ig) { 34557eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 34567eee914bSBarry Smith } 3457d25893d9SBarry Smith } 3458dd568438SSatish Balay } 3459d25893d9SBarry Smith 3460abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 346150ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3462d5e45103SBarry Smith 34633f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34644936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 346585385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 34664936397dSBarry Smith if (snes->domainerror){ 34674936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 34684936397dSBarry Smith snes->domainerror = PETSC_FALSE; 34694936397dSBarry Smith } 347017186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 34713f149594SLisandro Dalcin 347290d69ab7SBarry Smith flg = PETSC_FALSE; 3473acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3474da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 34755968eb51SBarry Smith if (snes->printreason) { 3476a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34775968eb51SBarry Smith if (snes->reason > 0) { 3478c7e7b494SJed Brown ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 34795968eb51SBarry Smith } else { 3480c7e7b494SJed Brown ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr); 34815968eb51SBarry Smith } 3482a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 34835968eb51SBarry Smith } 34845968eb51SBarry Smith 3485e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3486efd51863SBarry Smith if (grid < snes->gridsequence) { 3487efd51863SBarry Smith DM fine; 3488efd51863SBarry Smith Vec xnew; 3489efd51863SBarry Smith Mat interp; 3490efd51863SBarry Smith 3491efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3492c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3493e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3494efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3495efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3496c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 3497efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3498efd51863SBarry Smith x = xnew; 3499efd51863SBarry Smith 3500efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3501efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3502efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3503a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3504efd51863SBarry Smith } 3505efd51863SBarry Smith } 35063f7e2da0SPeter Brune /* monitoring and viewing */ 35073f7e2da0SPeter Brune flg = PETSC_FALSE; 35083f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 35093f7e2da0SPeter Brune if (flg && !PetscPreLoadingOn) { 35103f7e2da0SPeter Brune ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 35113f7e2da0SPeter Brune ierr = SNESView(snes,viewer);CHKERRQ(ierr); 35123f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 35133f7e2da0SPeter Brune } 35143f7e2da0SPeter Brune 35153f7e2da0SPeter Brune flg = PETSC_FALSE; 35163f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 35173f7e2da0SPeter Brune if (flg) { 35183f7e2da0SPeter Brune PetscViewer viewer; 35193f7e2da0SPeter Brune ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 35203f7e2da0SPeter Brune ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 35213f7e2da0SPeter Brune ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 35223f7e2da0SPeter Brune ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 35233f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 35243f7e2da0SPeter Brune } 35253f7e2da0SPeter Brune 3526a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 35273a40ed3dSBarry Smith PetscFunctionReturn(0); 35289b94acceSBarry Smith } 35299b94acceSBarry Smith 35309b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 35319b94acceSBarry Smith 35324a2ae208SSatish Balay #undef __FUNCT__ 35334a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 353482bf6240SBarry Smith /*@C 35354b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 35369b94acceSBarry Smith 3537fee21e36SBarry Smith Collective on SNES 3538fee21e36SBarry Smith 3539c7afd0dbSLois Curfman McInnes Input Parameters: 3540c7afd0dbSLois Curfman McInnes + snes - the SNES context 3541454a90a3SBarry Smith - type - a known method 3542c7afd0dbSLois Curfman McInnes 3543c7afd0dbSLois Curfman McInnes Options Database Key: 3544454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3545c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3546ae12b187SLois Curfman McInnes 35479b94acceSBarry Smith Notes: 3548e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 35494b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3550c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35514b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3552c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 35539b94acceSBarry Smith 3554ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3555ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3556ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3557ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3558ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3559ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3560ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3561ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3562ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3563b0a32e0cSBarry Smith appropriate method. 356436851e7fSLois Curfman McInnes 356536851e7fSLois Curfman McInnes Level: intermediate 3566a703fe33SLois Curfman McInnes 3567454a90a3SBarry Smith .keywords: SNES, set, type 3568435da068SBarry Smith 3569435da068SBarry Smith .seealso: SNESType, SNESCreate() 3570435da068SBarry Smith 35719b94acceSBarry Smith @*/ 35727087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 35739b94acceSBarry Smith { 3574dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3575ace3abfcSBarry Smith PetscBool match; 35763a40ed3dSBarry Smith 35773a40ed3dSBarry Smith PetscFunctionBegin; 35780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 35794482741eSBarry Smith PetscValidCharPointer(type,2); 358082bf6240SBarry Smith 3581251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 35820f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 358392ff6ae8SBarry Smith 35844b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3585e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 358675396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3587b5c23020SJed Brown if (snes->ops->destroy) { 3588b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3589b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3590b5c23020SJed Brown } 359175396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 359275396ef9SLisandro Dalcin snes->ops->setup = 0; 359375396ef9SLisandro Dalcin snes->ops->solve = 0; 359475396ef9SLisandro Dalcin snes->ops->view = 0; 359575396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 359675396ef9SLisandro Dalcin snes->ops->destroy = 0; 359775396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 359875396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3599454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 360003bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 36019fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 36029fb22e1aSBarry Smith if (PetscAMSPublishAll) { 36039fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 36049fb22e1aSBarry Smith } 36059fb22e1aSBarry Smith #endif 36063a40ed3dSBarry Smith PetscFunctionReturn(0); 36079b94acceSBarry Smith } 36089b94acceSBarry Smith 3609a847f771SSatish Balay 36109b94acceSBarry Smith /* --------------------------------------------------------------------- */ 36114a2ae208SSatish Balay #undef __FUNCT__ 36124a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 361352baeb72SSatish Balay /*@ 36149b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3615f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 36169b94acceSBarry Smith 3617fee21e36SBarry Smith Not Collective 3618fee21e36SBarry Smith 361936851e7fSLois Curfman McInnes Level: advanced 362036851e7fSLois Curfman McInnes 36219b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 36229b94acceSBarry Smith 36239b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 36249b94acceSBarry Smith @*/ 36257087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 36269b94acceSBarry Smith { 3627dfbe8321SBarry Smith PetscErrorCode ierr; 362882bf6240SBarry Smith 36293a40ed3dSBarry Smith PetscFunctionBegin; 36301441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 36314c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 36323a40ed3dSBarry Smith PetscFunctionReturn(0); 36339b94acceSBarry Smith } 36349b94acceSBarry Smith 36354a2ae208SSatish Balay #undef __FUNCT__ 36364a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 36379b94acceSBarry Smith /*@C 36389a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 36399b94acceSBarry Smith 3640c7afd0dbSLois Curfman McInnes Not Collective 3641c7afd0dbSLois Curfman McInnes 36429b94acceSBarry Smith Input Parameter: 36434b0e389bSBarry Smith . snes - nonlinear solver context 36449b94acceSBarry Smith 36459b94acceSBarry Smith Output Parameter: 36463a7fca6bSBarry Smith . type - SNES method (a character string) 36479b94acceSBarry Smith 364836851e7fSLois Curfman McInnes Level: intermediate 364936851e7fSLois Curfman McInnes 3650454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 36519b94acceSBarry Smith @*/ 36527087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 36539b94acceSBarry Smith { 36543a40ed3dSBarry Smith PetscFunctionBegin; 36550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36564482741eSBarry Smith PetscValidPointer(type,2); 36577adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 36583a40ed3dSBarry Smith PetscFunctionReturn(0); 36599b94acceSBarry Smith } 36609b94acceSBarry Smith 36614a2ae208SSatish Balay #undef __FUNCT__ 36624a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 366352baeb72SSatish Balay /*@ 36649b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3665c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 36669b94acceSBarry Smith 3667c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3668c7afd0dbSLois Curfman McInnes 36699b94acceSBarry Smith Input Parameter: 36709b94acceSBarry Smith . snes - the SNES context 36719b94acceSBarry Smith 36729b94acceSBarry Smith Output Parameter: 36739b94acceSBarry Smith . x - the solution 36749b94acceSBarry Smith 367570e92668SMatthew Knepley Level: intermediate 367636851e7fSLois Curfman McInnes 36779b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 36789b94acceSBarry Smith 367985385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 36809b94acceSBarry Smith @*/ 36817087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 36829b94acceSBarry Smith { 36833a40ed3dSBarry Smith PetscFunctionBegin; 36840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36854482741eSBarry Smith PetscValidPointer(x,2); 368685385478SLisandro Dalcin *x = snes->vec_sol; 368770e92668SMatthew Knepley PetscFunctionReturn(0); 368870e92668SMatthew Knepley } 368970e92668SMatthew Knepley 369070e92668SMatthew Knepley #undef __FUNCT__ 36914a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 369252baeb72SSatish Balay /*@ 36939b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 36949b94acceSBarry Smith stored. 36959b94acceSBarry Smith 3696c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3697c7afd0dbSLois Curfman McInnes 36989b94acceSBarry Smith Input Parameter: 36999b94acceSBarry Smith . snes - the SNES context 37009b94acceSBarry Smith 37019b94acceSBarry Smith Output Parameter: 37029b94acceSBarry Smith . x - the solution update 37039b94acceSBarry Smith 370436851e7fSLois Curfman McInnes Level: advanced 370536851e7fSLois Curfman McInnes 37069b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 37079b94acceSBarry Smith 370885385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 37099b94acceSBarry Smith @*/ 37107087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 37119b94acceSBarry Smith { 37123a40ed3dSBarry Smith PetscFunctionBegin; 37130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37144482741eSBarry Smith PetscValidPointer(x,2); 371585385478SLisandro Dalcin *x = snes->vec_sol_update; 37163a40ed3dSBarry Smith PetscFunctionReturn(0); 37179b94acceSBarry Smith } 37189b94acceSBarry Smith 37194a2ae208SSatish Balay #undef __FUNCT__ 37204a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 37219b94acceSBarry Smith /*@C 37223638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 37239b94acceSBarry Smith 3724a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3725c7afd0dbSLois Curfman McInnes 37269b94acceSBarry Smith Input Parameter: 37279b94acceSBarry Smith . snes - the SNES context 37289b94acceSBarry Smith 37299b94acceSBarry Smith Output Parameter: 37307bf4e008SBarry Smith + r - the function (or PETSC_NULL) 373170e92668SMatthew Knepley . func - the function (or PETSC_NULL) 373270e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 37339b94acceSBarry Smith 373436851e7fSLois Curfman McInnes Level: advanced 373536851e7fSLois Curfman McInnes 3736a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 37379b94acceSBarry Smith 37384b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 37399b94acceSBarry Smith @*/ 37407087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 37419b94acceSBarry Smith { 3742a63bb30eSJed Brown PetscErrorCode ierr; 37436cab3a1bSJed Brown DM dm; 3744a63bb30eSJed Brown 37453a40ed3dSBarry Smith PetscFunctionBegin; 37460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3747a63bb30eSJed Brown if (r) { 3748a63bb30eSJed Brown if (!snes->vec_func) { 3749a63bb30eSJed Brown if (snes->vec_rhs) { 3750a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3751a63bb30eSJed Brown } else if (snes->vec_sol) { 3752a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3753a63bb30eSJed Brown } else if (snes->dm) { 3754a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3755a63bb30eSJed Brown } 3756a63bb30eSJed Brown } 3757a63bb30eSJed Brown *r = snes->vec_func; 3758a63bb30eSJed Brown } 37596cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37606cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 37613a40ed3dSBarry Smith PetscFunctionReturn(0); 37629b94acceSBarry Smith } 37639b94acceSBarry Smith 3764c79ef259SPeter Brune /*@C 3765c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3766c79ef259SPeter Brune 3767c79ef259SPeter Brune Input Parameter: 3768c79ef259SPeter Brune . snes - the SNES context 3769c79ef259SPeter Brune 3770c79ef259SPeter Brune Output Parameter: 3771c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3772c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3773c79ef259SPeter Brune 3774c79ef259SPeter Brune Level: advanced 3775c79ef259SPeter Brune 3776c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3777c79ef259SPeter Brune 3778c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3779c79ef259SPeter Brune @*/ 3780c79ef259SPeter Brune 37814a2ae208SSatish Balay #undef __FUNCT__ 3782646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3783646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3784646217ecSPeter Brune { 37856cab3a1bSJed Brown PetscErrorCode ierr; 37866cab3a1bSJed Brown DM dm; 37876cab3a1bSJed Brown 3788646217ecSPeter Brune PetscFunctionBegin; 3789646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37906cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 37916cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3792646217ecSPeter Brune PetscFunctionReturn(0); 3793646217ecSPeter Brune } 3794646217ecSPeter Brune 37954a2ae208SSatish Balay #undef __FUNCT__ 37964a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 37973c7409f5SSatish Balay /*@C 37983c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3799d850072dSLois Curfman McInnes SNES options in the database. 38003c7409f5SSatish Balay 38013f9fe445SBarry Smith Logically Collective on SNES 3802fee21e36SBarry Smith 3803c7afd0dbSLois Curfman McInnes Input Parameter: 3804c7afd0dbSLois Curfman McInnes + snes - the SNES context 3805c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3806c7afd0dbSLois Curfman McInnes 3807d850072dSLois Curfman McInnes Notes: 3808a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3809c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3810d850072dSLois Curfman McInnes 381136851e7fSLois Curfman McInnes Level: advanced 381236851e7fSLois Curfman McInnes 38133c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3814a86d99e1SLois Curfman McInnes 3815a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 38163c7409f5SSatish Balay @*/ 38177087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 38183c7409f5SSatish Balay { 3819dfbe8321SBarry Smith PetscErrorCode ierr; 38203c7409f5SSatish Balay 38213a40ed3dSBarry Smith PetscFunctionBegin; 38220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3823639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38241cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 382594b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38263a40ed3dSBarry Smith PetscFunctionReturn(0); 38273c7409f5SSatish Balay } 38283c7409f5SSatish Balay 38294a2ae208SSatish Balay #undef __FUNCT__ 38304a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 38313c7409f5SSatish Balay /*@C 3832f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3833d850072dSLois Curfman McInnes SNES options in the database. 38343c7409f5SSatish Balay 38353f9fe445SBarry Smith Logically Collective on SNES 3836fee21e36SBarry Smith 3837c7afd0dbSLois Curfman McInnes Input Parameters: 3838c7afd0dbSLois Curfman McInnes + snes - the SNES context 3839c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3840c7afd0dbSLois Curfman McInnes 3841d850072dSLois Curfman McInnes Notes: 3842a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3843c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3844d850072dSLois Curfman McInnes 384536851e7fSLois Curfman McInnes Level: advanced 384636851e7fSLois Curfman McInnes 38473c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3848a86d99e1SLois Curfman McInnes 3849a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 38503c7409f5SSatish Balay @*/ 38517087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 38523c7409f5SSatish Balay { 3853dfbe8321SBarry Smith PetscErrorCode ierr; 38543c7409f5SSatish Balay 38553a40ed3dSBarry Smith PetscFunctionBegin; 38560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3857639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38581cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 385994b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38603a40ed3dSBarry Smith PetscFunctionReturn(0); 38613c7409f5SSatish Balay } 38623c7409f5SSatish Balay 38634a2ae208SSatish Balay #undef __FUNCT__ 38644a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 38659ab63eb5SSatish Balay /*@C 38663c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 38673c7409f5SSatish Balay SNES options in the database. 38683c7409f5SSatish Balay 3869c7afd0dbSLois Curfman McInnes Not Collective 3870c7afd0dbSLois Curfman McInnes 38713c7409f5SSatish Balay Input Parameter: 38723c7409f5SSatish Balay . snes - the SNES context 38733c7409f5SSatish Balay 38743c7409f5SSatish Balay Output Parameter: 38753c7409f5SSatish Balay . prefix - pointer to the prefix string used 38763c7409f5SSatish Balay 38774ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 38789ab63eb5SSatish Balay sufficient length to hold the prefix. 38799ab63eb5SSatish Balay 388036851e7fSLois Curfman McInnes Level: advanced 388136851e7fSLois Curfman McInnes 38823c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3883a86d99e1SLois Curfman McInnes 3884a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 38853c7409f5SSatish Balay @*/ 38867087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 38873c7409f5SSatish Balay { 3888dfbe8321SBarry Smith PetscErrorCode ierr; 38893c7409f5SSatish Balay 38903a40ed3dSBarry Smith PetscFunctionBegin; 38910700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3892639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38933a40ed3dSBarry Smith PetscFunctionReturn(0); 38943c7409f5SSatish Balay } 38953c7409f5SSatish Balay 3896b2002411SLois Curfman McInnes 38974a2ae208SSatish Balay #undef __FUNCT__ 38984a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 38993cea93caSBarry Smith /*@C 39003cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 39013cea93caSBarry Smith 39027f6c08e0SMatthew Knepley Level: advanced 39033cea93caSBarry Smith @*/ 39047087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3905b2002411SLois Curfman McInnes { 3906e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3907dfbe8321SBarry Smith PetscErrorCode ierr; 3908b2002411SLois Curfman McInnes 3909b2002411SLois Curfman McInnes PetscFunctionBegin; 3910b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3911c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3912b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3913b2002411SLois Curfman McInnes } 3914da9b6338SBarry Smith 3915da9b6338SBarry Smith #undef __FUNCT__ 3916da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 39177087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3918da9b6338SBarry Smith { 3919dfbe8321SBarry Smith PetscErrorCode ierr; 392077431f27SBarry Smith PetscInt N,i,j; 3921da9b6338SBarry Smith Vec u,uh,fh; 3922da9b6338SBarry Smith PetscScalar value; 3923da9b6338SBarry Smith PetscReal norm; 3924da9b6338SBarry Smith 3925da9b6338SBarry Smith PetscFunctionBegin; 3926da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3927da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3928da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3929da9b6338SBarry Smith 3930da9b6338SBarry Smith /* currently only works for sequential */ 3931da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3932da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3933da9b6338SBarry Smith for (i=0; i<N; i++) { 3934da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 393577431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3936da9b6338SBarry Smith for (j=-10; j<11; j++) { 3937ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3938da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 39393ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3940da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 394177431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3942da9b6338SBarry Smith value = -value; 3943da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 3944da9b6338SBarry Smith } 3945da9b6338SBarry Smith } 39466bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 39476bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 3948da9b6338SBarry Smith PetscFunctionReturn(0); 3949da9b6338SBarry Smith } 395071f87433Sdalcinl 395171f87433Sdalcinl #undef __FUNCT__ 3952fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 395371f87433Sdalcinl /*@ 3954fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 395571f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 395671f87433Sdalcinl Newton method. 395771f87433Sdalcinl 39583f9fe445SBarry Smith Logically Collective on SNES 395971f87433Sdalcinl 396071f87433Sdalcinl Input Parameters: 396171f87433Sdalcinl + snes - SNES context 396271f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 396371f87433Sdalcinl 396464ba62caSBarry Smith Options Database: 396564ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 396664ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 396764ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 396864ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 396964ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 397064ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 397164ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 397264ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 397364ba62caSBarry Smith 397471f87433Sdalcinl Notes: 397571f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 397671f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 397771f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 397871f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 397971f87433Sdalcinl solver. 398071f87433Sdalcinl 398171f87433Sdalcinl Level: advanced 398271f87433Sdalcinl 398371f87433Sdalcinl Reference: 398471f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 398571f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 398671f87433Sdalcinl 398771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 398871f87433Sdalcinl 3989fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 399071f87433Sdalcinl @*/ 39917087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 399271f87433Sdalcinl { 399371f87433Sdalcinl PetscFunctionBegin; 39940700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3995acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 399671f87433Sdalcinl snes->ksp_ewconv = flag; 399771f87433Sdalcinl PetscFunctionReturn(0); 399871f87433Sdalcinl } 399971f87433Sdalcinl 400071f87433Sdalcinl #undef __FUNCT__ 4001fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 400271f87433Sdalcinl /*@ 4003fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 400471f87433Sdalcinl for computing relative tolerance for linear solvers within an 400571f87433Sdalcinl inexact Newton method. 400671f87433Sdalcinl 400771f87433Sdalcinl Not Collective 400871f87433Sdalcinl 400971f87433Sdalcinl Input Parameter: 401071f87433Sdalcinl . snes - SNES context 401171f87433Sdalcinl 401271f87433Sdalcinl Output Parameter: 401371f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 401471f87433Sdalcinl 401571f87433Sdalcinl Notes: 401671f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 401771f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 401871f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 401971f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 402071f87433Sdalcinl solver. 402171f87433Sdalcinl 402271f87433Sdalcinl Level: advanced 402371f87433Sdalcinl 402471f87433Sdalcinl Reference: 402571f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 402671f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 402771f87433Sdalcinl 402871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 402971f87433Sdalcinl 4030fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 403171f87433Sdalcinl @*/ 40327087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 403371f87433Sdalcinl { 403471f87433Sdalcinl PetscFunctionBegin; 40350700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 403671f87433Sdalcinl PetscValidPointer(flag,2); 403771f87433Sdalcinl *flag = snes->ksp_ewconv; 403871f87433Sdalcinl PetscFunctionReturn(0); 403971f87433Sdalcinl } 404071f87433Sdalcinl 404171f87433Sdalcinl #undef __FUNCT__ 4042fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 404371f87433Sdalcinl /*@ 4044fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 404571f87433Sdalcinl convergence criteria for the linear solvers within an inexact 404671f87433Sdalcinl Newton method. 404771f87433Sdalcinl 40483f9fe445SBarry Smith Logically Collective on SNES 404971f87433Sdalcinl 405071f87433Sdalcinl Input Parameters: 405171f87433Sdalcinl + snes - SNES context 405271f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 405371f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 405471f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 405571f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 405671f87433Sdalcinl (0 <= gamma2 <= 1) 405771f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 405871f87433Sdalcinl . alpha2 - power for safeguard 405971f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 406071f87433Sdalcinl 406171f87433Sdalcinl Note: 406271f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 406371f87433Sdalcinl 406471f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 406571f87433Sdalcinl 406671f87433Sdalcinl Level: advanced 406771f87433Sdalcinl 406871f87433Sdalcinl Reference: 406971f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 407071f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 407171f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 407271f87433Sdalcinl 407371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 407471f87433Sdalcinl 4075fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 407671f87433Sdalcinl @*/ 40777087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 407871f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 407971f87433Sdalcinl { 4080fa9f3622SBarry Smith SNESKSPEW *kctx; 408171f87433Sdalcinl PetscFunctionBegin; 40820700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4083fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4084e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4085c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4086c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4087c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4088c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4089c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4090c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4091c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 409271f87433Sdalcinl 409371f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 409471f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 409571f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 409671f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 409771f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 409871f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 409971f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 410071f87433Sdalcinl 410171f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4102e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 410371f87433Sdalcinl } 410471f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4105e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 410671f87433Sdalcinl } 410771f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4108e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 410971f87433Sdalcinl } 411071f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4111e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 411271f87433Sdalcinl } 411371f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4114e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 411571f87433Sdalcinl } 411671f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4117e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 411871f87433Sdalcinl } 411971f87433Sdalcinl PetscFunctionReturn(0); 412071f87433Sdalcinl } 412171f87433Sdalcinl 412271f87433Sdalcinl #undef __FUNCT__ 4123fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 412471f87433Sdalcinl /*@ 4125fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 412671f87433Sdalcinl convergence criteria for the linear solvers within an inexact 412771f87433Sdalcinl Newton method. 412871f87433Sdalcinl 412971f87433Sdalcinl Not Collective 413071f87433Sdalcinl 413171f87433Sdalcinl Input Parameters: 413271f87433Sdalcinl snes - SNES context 413371f87433Sdalcinl 413471f87433Sdalcinl Output Parameters: 413571f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 413671f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 413771f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 413871f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 413971f87433Sdalcinl (0 <= gamma2 <= 1) 414071f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 414171f87433Sdalcinl . alpha2 - power for safeguard 414271f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 414371f87433Sdalcinl 414471f87433Sdalcinl Level: advanced 414571f87433Sdalcinl 414671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 414771f87433Sdalcinl 4148fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 414971f87433Sdalcinl @*/ 41507087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 415171f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 415271f87433Sdalcinl { 4153fa9f3622SBarry Smith SNESKSPEW *kctx; 415471f87433Sdalcinl PetscFunctionBegin; 41550700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4156fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4157e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 415871f87433Sdalcinl if(version) *version = kctx->version; 415971f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 416071f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 416171f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 416271f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 416371f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 416471f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 416571f87433Sdalcinl PetscFunctionReturn(0); 416671f87433Sdalcinl } 416771f87433Sdalcinl 416871f87433Sdalcinl #undef __FUNCT__ 4169fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4170fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 417171f87433Sdalcinl { 417271f87433Sdalcinl PetscErrorCode ierr; 4173fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 417471f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 417571f87433Sdalcinl 417671f87433Sdalcinl PetscFunctionBegin; 4177e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 417871f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 417971f87433Sdalcinl rtol = kctx->rtol_0; 418071f87433Sdalcinl } else { 418171f87433Sdalcinl if (kctx->version == 1) { 418271f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 418371f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 418471f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 418571f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 418671f87433Sdalcinl } else if (kctx->version == 2) { 418771f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 418871f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 418971f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 419071f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 419171f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 419271f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 419371f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 419471f87433Sdalcinl stol = PetscMax(rtol,stol); 419571f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 419671f87433Sdalcinl /* safeguard: avoid oversolving */ 419771f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 419871f87433Sdalcinl stol = PetscMax(rtol,stol); 419971f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4200e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 420171f87433Sdalcinl } 420271f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 420371f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 420471f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 420571f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 420671f87433Sdalcinl PetscFunctionReturn(0); 420771f87433Sdalcinl } 420871f87433Sdalcinl 420971f87433Sdalcinl #undef __FUNCT__ 4210fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4211fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 421271f87433Sdalcinl { 421371f87433Sdalcinl PetscErrorCode ierr; 4214fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 421571f87433Sdalcinl PCSide pcside; 421671f87433Sdalcinl Vec lres; 421771f87433Sdalcinl 421871f87433Sdalcinl PetscFunctionBegin; 4219e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 422071f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 422171f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 422271f87433Sdalcinl if (kctx->version == 1) { 4223b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 422471f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 422571f87433Sdalcinl /* KSP residual is true linear residual */ 422671f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 422771f87433Sdalcinl } else { 422871f87433Sdalcinl /* KSP residual is preconditioned residual */ 422971f87433Sdalcinl /* compute true linear residual norm */ 423071f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 423171f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 423271f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 423371f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 42346bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 423571f87433Sdalcinl } 423671f87433Sdalcinl } 423771f87433Sdalcinl PetscFunctionReturn(0); 423871f87433Sdalcinl } 423971f87433Sdalcinl 424071f87433Sdalcinl #undef __FUNCT__ 424171f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 424271f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 424371f87433Sdalcinl { 424471f87433Sdalcinl PetscErrorCode ierr; 424571f87433Sdalcinl 424671f87433Sdalcinl PetscFunctionBegin; 4247fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 424871f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4249fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 425071f87433Sdalcinl PetscFunctionReturn(0); 425171f87433Sdalcinl } 42526c699258SBarry Smith 42536c699258SBarry Smith #undef __FUNCT__ 42546c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 42556c699258SBarry Smith /*@ 42566c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 42576c699258SBarry Smith 42583f9fe445SBarry Smith Logically Collective on SNES 42596c699258SBarry Smith 42606c699258SBarry Smith Input Parameters: 42616c699258SBarry Smith + snes - the preconditioner context 42626c699258SBarry Smith - dm - the dm 42636c699258SBarry Smith 42646c699258SBarry Smith Level: intermediate 42656c699258SBarry Smith 42666c699258SBarry Smith 42676c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 42686c699258SBarry Smith @*/ 42697087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 42706c699258SBarry Smith { 42716c699258SBarry Smith PetscErrorCode ierr; 4272345fed2cSBarry Smith KSP ksp; 42736cab3a1bSJed Brown SNESDM sdm; 42746c699258SBarry Smith 42756c699258SBarry Smith PetscFunctionBegin; 42760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4277d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 42786cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 42796cab3a1bSJed Brown PetscContainer oldcontainer,container; 42806cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 42816cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 42826cab3a1bSJed Brown if (oldcontainer && !container) { 42836cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 42846cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 42856cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 42866cab3a1bSJed Brown sdm->originaldm = dm; 42876cab3a1bSJed Brown } 42886cab3a1bSJed Brown } 42896bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 42906cab3a1bSJed Brown } 42916c699258SBarry Smith snes->dm = dm; 4292345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4293345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4294f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 42952c155ee1SBarry Smith if (snes->pc) { 42962c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 42972c155ee1SBarry Smith } 42986c699258SBarry Smith PetscFunctionReturn(0); 42996c699258SBarry Smith } 43006c699258SBarry Smith 43016c699258SBarry Smith #undef __FUNCT__ 43026c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 43036c699258SBarry Smith /*@ 43046c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 43056c699258SBarry Smith 43063f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 43076c699258SBarry Smith 43086c699258SBarry Smith Input Parameter: 43096c699258SBarry Smith . snes - the preconditioner context 43106c699258SBarry Smith 43116c699258SBarry Smith Output Parameter: 43126c699258SBarry Smith . dm - the dm 43136c699258SBarry Smith 43146c699258SBarry Smith Level: intermediate 43156c699258SBarry Smith 43166c699258SBarry Smith 43176c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 43186c699258SBarry Smith @*/ 43197087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 43206c699258SBarry Smith { 43216cab3a1bSJed Brown PetscErrorCode ierr; 43226cab3a1bSJed Brown 43236c699258SBarry Smith PetscFunctionBegin; 43240700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43256cab3a1bSJed Brown if (!snes->dm) { 43266cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 43276cab3a1bSJed Brown } 43286c699258SBarry Smith *dm = snes->dm; 43296c699258SBarry Smith PetscFunctionReturn(0); 43306c699258SBarry Smith } 43310807856dSBarry Smith 433231823bd8SMatthew G Knepley #undef __FUNCT__ 433331823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 433431823bd8SMatthew G Knepley /*@ 4335fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 433631823bd8SMatthew G Knepley 433731823bd8SMatthew G Knepley Collective on SNES 433831823bd8SMatthew G Knepley 433931823bd8SMatthew G Knepley Input Parameters: 434031823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 434131823bd8SMatthew G Knepley - pc - the preconditioner object 434231823bd8SMatthew G Knepley 434331823bd8SMatthew G Knepley Notes: 434431823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 434531823bd8SMatthew G Knepley to configure it using the API). 434631823bd8SMatthew G Knepley 434731823bd8SMatthew G Knepley Level: developer 434831823bd8SMatthew G Knepley 434931823bd8SMatthew G Knepley .keywords: SNES, set, precondition 435031823bd8SMatthew G Knepley .seealso: SNESGetPC() 435131823bd8SMatthew G Knepley @*/ 435231823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 435331823bd8SMatthew G Knepley { 435431823bd8SMatthew G Knepley PetscErrorCode ierr; 435531823bd8SMatthew G Knepley 435631823bd8SMatthew G Knepley PetscFunctionBegin; 435731823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 435831823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 435931823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 436031823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4361bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 436231823bd8SMatthew G Knepley snes->pc = pc; 436331823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 436431823bd8SMatthew G Knepley PetscFunctionReturn(0); 436531823bd8SMatthew G Knepley } 436631823bd8SMatthew G Knepley 436731823bd8SMatthew G Knepley #undef __FUNCT__ 436831823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 436931823bd8SMatthew G Knepley /*@ 4370fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 437131823bd8SMatthew G Knepley 437231823bd8SMatthew G Knepley Not Collective 437331823bd8SMatthew G Knepley 437431823bd8SMatthew G Knepley Input Parameter: 437531823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 437631823bd8SMatthew G Knepley 437731823bd8SMatthew G Knepley Output Parameter: 437831823bd8SMatthew G Knepley . pc - preconditioner context 437931823bd8SMatthew G Knepley 438031823bd8SMatthew G Knepley Level: developer 438131823bd8SMatthew G Knepley 438231823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 438331823bd8SMatthew G Knepley .seealso: SNESSetPC() 438431823bd8SMatthew G Knepley @*/ 438531823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 438631823bd8SMatthew G Knepley { 438731823bd8SMatthew G Knepley PetscErrorCode ierr; 4388a64e098fSPeter Brune const char *optionsprefix; 438931823bd8SMatthew G Knepley 439031823bd8SMatthew G Knepley PetscFunctionBegin; 439131823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 439231823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 439331823bd8SMatthew G Knepley if (!snes->pc) { 439431823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr); 43954a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr); 439631823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr); 4397a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 4398a64e098fSPeter Brune ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr); 4399a64e098fSPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr); 440031823bd8SMatthew G Knepley } 440131823bd8SMatthew G Knepley *pc = snes->pc; 440231823bd8SMatthew G Knepley PetscFunctionReturn(0); 440331823bd8SMatthew G Knepley } 440431823bd8SMatthew G Knepley 44059e764e56SPeter Brune #undef __FUNCT__ 4406f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 44079e764e56SPeter Brune /*@ 44088141a3b9SPeter Brune SNESSetSNESLineSearch - Sets the linesearch on the SNES instance. 44099e764e56SPeter Brune 44109e764e56SPeter Brune Collective on SNES 44119e764e56SPeter Brune 44129e764e56SPeter Brune Input Parameters: 44139e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 44149e764e56SPeter Brune - linesearch - the linesearch object 44159e764e56SPeter Brune 44169e764e56SPeter Brune Notes: 4417f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 44189e764e56SPeter Brune to configure it using the API). 44199e764e56SPeter Brune 44209e764e56SPeter Brune Level: developer 44219e764e56SPeter Brune 44229e764e56SPeter Brune .keywords: SNES, set, linesearch 4423f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 44249e764e56SPeter Brune @*/ 4425f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 44269e764e56SPeter Brune { 44279e764e56SPeter Brune PetscErrorCode ierr; 44289e764e56SPeter Brune 44299e764e56SPeter Brune PetscFunctionBegin; 44309e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4431f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 44329e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 44339e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4434f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 44359e764e56SPeter Brune snes->linesearch = linesearch; 44369e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44379e764e56SPeter Brune PetscFunctionReturn(0); 44389e764e56SPeter Brune } 44399e764e56SPeter Brune 44409e764e56SPeter Brune #undef __FUNCT__ 4441f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4442ea5d4fccSPeter Brune /*@C 44438141a3b9SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 44448141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 44459e764e56SPeter Brune 44469e764e56SPeter Brune Not Collective 44479e764e56SPeter Brune 44489e764e56SPeter Brune Input Parameter: 44499e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 44509e764e56SPeter Brune 44519e764e56SPeter Brune Output Parameter: 44529e764e56SPeter Brune . linesearch - linesearch context 44539e764e56SPeter Brune 44549e764e56SPeter Brune Level: developer 44559e764e56SPeter Brune 44569e764e56SPeter Brune .keywords: SNES, get, linesearch 4457f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 44589e764e56SPeter Brune @*/ 4459f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 44609e764e56SPeter Brune { 44619e764e56SPeter Brune PetscErrorCode ierr; 44629e764e56SPeter Brune const char *optionsprefix; 44639e764e56SPeter Brune 44649e764e56SPeter Brune PetscFunctionBegin; 44659e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 44669e764e56SPeter Brune PetscValidPointer(linesearch, 2); 44679e764e56SPeter Brune if (!snes->linesearch) { 44689e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4469f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4470f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4471b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 44729e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 44739e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44749e764e56SPeter Brune } 44759e764e56SPeter Brune *linesearch = snes->linesearch; 44769e764e56SPeter Brune PetscFunctionReturn(0); 44779e764e56SPeter Brune } 44789e764e56SPeter Brune 447969b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4480c6db04a5SJed Brown #include <mex.h> 448169b4f73cSBarry Smith 44828f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 44838f6e6473SBarry Smith 44840807856dSBarry Smith #undef __FUNCT__ 44850807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 44860807856dSBarry Smith /* 44870807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 44880807856dSBarry Smith SNESSetFunctionMatlab(). 44890807856dSBarry Smith 44900807856dSBarry Smith Collective on SNES 44910807856dSBarry Smith 44920807856dSBarry Smith Input Parameters: 44930807856dSBarry Smith + snes - the SNES context 44940807856dSBarry Smith - x - input vector 44950807856dSBarry Smith 44960807856dSBarry Smith Output Parameter: 44970807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 44980807856dSBarry Smith 44990807856dSBarry Smith Notes: 45000807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 45010807856dSBarry Smith implementations, so most users would not generally call this routine 45020807856dSBarry Smith themselves. 45030807856dSBarry Smith 45040807856dSBarry Smith Level: developer 45050807856dSBarry Smith 45060807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 45070807856dSBarry Smith 45080807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 450961b2408cSBarry Smith */ 45107087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 45110807856dSBarry Smith { 4512e650e774SBarry Smith PetscErrorCode ierr; 45138f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 45148f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 45158f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 451691621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4517e650e774SBarry Smith 45180807856dSBarry Smith PetscFunctionBegin; 45190807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 45200807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 45210807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 45220807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 45230807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 45240807856dSBarry Smith 45250807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4526e650e774SBarry Smith 452791621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4528e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4529e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 453091621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 453191621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 453291621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 45338f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 45348f6e6473SBarry Smith prhs[4] = sctx->ctx; 4535b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4536e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4537e650e774SBarry Smith mxDestroyArray(prhs[0]); 4538e650e774SBarry Smith mxDestroyArray(prhs[1]); 4539e650e774SBarry Smith mxDestroyArray(prhs[2]); 45408f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4541e650e774SBarry Smith mxDestroyArray(plhs[0]); 45420807856dSBarry Smith PetscFunctionReturn(0); 45430807856dSBarry Smith } 45440807856dSBarry Smith 45450807856dSBarry Smith 45460807856dSBarry Smith #undef __FUNCT__ 45470807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 454861b2408cSBarry Smith /* 45490807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 45500807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4551e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 45520807856dSBarry Smith 45530807856dSBarry Smith Logically Collective on SNES 45540807856dSBarry Smith 45550807856dSBarry Smith Input Parameters: 45560807856dSBarry Smith + snes - the SNES context 45570807856dSBarry Smith . r - vector to store function value 45580807856dSBarry Smith - func - function evaluation routine 45590807856dSBarry Smith 45600807856dSBarry Smith Calling sequence of func: 456161b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 45620807856dSBarry Smith 45630807856dSBarry Smith 45640807856dSBarry Smith Notes: 45650807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 45660807856dSBarry Smith $ f'(x) x = -f(x), 45670807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 45680807856dSBarry Smith 45690807856dSBarry Smith Level: beginner 45700807856dSBarry Smith 45710807856dSBarry Smith .keywords: SNES, nonlinear, set, function 45720807856dSBarry Smith 45730807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 457461b2408cSBarry Smith */ 45757087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 45760807856dSBarry Smith { 45770807856dSBarry Smith PetscErrorCode ierr; 45788f6e6473SBarry Smith SNESMatlabContext *sctx; 45790807856dSBarry Smith 45800807856dSBarry Smith PetscFunctionBegin; 45818f6e6473SBarry Smith /* currently sctx is memory bleed */ 45828f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 45838f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 45848f6e6473SBarry Smith /* 45858f6e6473SBarry Smith This should work, but it doesn't 45868f6e6473SBarry Smith sctx->ctx = ctx; 45878f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 45888f6e6473SBarry Smith */ 45898f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 45908f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 45910807856dSBarry Smith PetscFunctionReturn(0); 45920807856dSBarry Smith } 459369b4f73cSBarry Smith 459461b2408cSBarry Smith #undef __FUNCT__ 459561b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 459661b2408cSBarry Smith /* 459761b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 459861b2408cSBarry Smith SNESSetJacobianMatlab(). 459961b2408cSBarry Smith 460061b2408cSBarry Smith Collective on SNES 460161b2408cSBarry Smith 460261b2408cSBarry Smith Input Parameters: 460361b2408cSBarry Smith + snes - the SNES context 460461b2408cSBarry Smith . x - input vector 460561b2408cSBarry Smith . A, B - the matrices 460661b2408cSBarry Smith - ctx - user context 460761b2408cSBarry Smith 460861b2408cSBarry Smith Output Parameter: 460961b2408cSBarry Smith . flag - structure of the matrix 461061b2408cSBarry Smith 461161b2408cSBarry Smith Level: developer 461261b2408cSBarry Smith 461361b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 461461b2408cSBarry Smith 461561b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 461661b2408cSBarry Smith @*/ 46177087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 461861b2408cSBarry Smith { 461961b2408cSBarry Smith PetscErrorCode ierr; 462061b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 462161b2408cSBarry Smith int nlhs = 2,nrhs = 6; 462261b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 462361b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 462461b2408cSBarry Smith 462561b2408cSBarry Smith PetscFunctionBegin; 462661b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 462761b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 462861b2408cSBarry Smith 462961b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 463061b2408cSBarry Smith 463161b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 463261b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 463361b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 463461b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 463561b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 463661b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 463761b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 463861b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 463961b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 464061b2408cSBarry Smith prhs[5] = sctx->ctx; 4641b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 464261b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 464361b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 464461b2408cSBarry Smith mxDestroyArray(prhs[0]); 464561b2408cSBarry Smith mxDestroyArray(prhs[1]); 464661b2408cSBarry Smith mxDestroyArray(prhs[2]); 464761b2408cSBarry Smith mxDestroyArray(prhs[3]); 464861b2408cSBarry Smith mxDestroyArray(prhs[4]); 464961b2408cSBarry Smith mxDestroyArray(plhs[0]); 465061b2408cSBarry Smith mxDestroyArray(plhs[1]); 465161b2408cSBarry Smith PetscFunctionReturn(0); 465261b2408cSBarry Smith } 465361b2408cSBarry Smith 465461b2408cSBarry Smith 465561b2408cSBarry Smith #undef __FUNCT__ 465661b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 465761b2408cSBarry Smith /* 465861b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 465961b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4660e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 466161b2408cSBarry Smith 466261b2408cSBarry Smith Logically Collective on SNES 466361b2408cSBarry Smith 466461b2408cSBarry Smith Input Parameters: 466561b2408cSBarry Smith + snes - the SNES context 466661b2408cSBarry Smith . A,B - Jacobian matrices 466761b2408cSBarry Smith . func - function evaluation routine 466861b2408cSBarry Smith - ctx - user context 466961b2408cSBarry Smith 467061b2408cSBarry Smith Calling sequence of func: 467161b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 467261b2408cSBarry Smith 467361b2408cSBarry Smith 467461b2408cSBarry Smith Level: developer 467561b2408cSBarry Smith 467661b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 467761b2408cSBarry Smith 467861b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 467961b2408cSBarry Smith */ 46807087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 468161b2408cSBarry Smith { 468261b2408cSBarry Smith PetscErrorCode ierr; 468361b2408cSBarry Smith SNESMatlabContext *sctx; 468461b2408cSBarry Smith 468561b2408cSBarry Smith PetscFunctionBegin; 468661b2408cSBarry Smith /* currently sctx is memory bleed */ 468761b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 468861b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 468961b2408cSBarry Smith /* 469061b2408cSBarry Smith This should work, but it doesn't 469161b2408cSBarry Smith sctx->ctx = ctx; 469261b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 469361b2408cSBarry Smith */ 469461b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 469561b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 469661b2408cSBarry Smith PetscFunctionReturn(0); 469761b2408cSBarry Smith } 469869b4f73cSBarry Smith 4699f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4700f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4701f9eb7ae2SShri Abhyankar /* 4702f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4703f9eb7ae2SShri Abhyankar 4704f9eb7ae2SShri Abhyankar Collective on SNES 4705f9eb7ae2SShri Abhyankar 4706f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4707f9eb7ae2SShri Abhyankar @*/ 47087087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4709f9eb7ae2SShri Abhyankar { 4710f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 471148f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4712f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4713f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4714f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4715f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4716f9eb7ae2SShri Abhyankar 4717f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4718f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4719f9eb7ae2SShri Abhyankar 4720f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4721f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4722f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4723f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4724f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4725f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4726f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4727f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4728f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4729f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4730f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4731f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4732f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4733f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4734f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4735f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4736f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4737f9eb7ae2SShri Abhyankar } 4738f9eb7ae2SShri Abhyankar 4739f9eb7ae2SShri Abhyankar 4740f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4741f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4742f9eb7ae2SShri Abhyankar /* 4743e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4744f9eb7ae2SShri Abhyankar 4745f9eb7ae2SShri Abhyankar Level: developer 4746f9eb7ae2SShri Abhyankar 4747f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4748f9eb7ae2SShri Abhyankar 4749f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4750f9eb7ae2SShri Abhyankar */ 47517087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4752f9eb7ae2SShri Abhyankar { 4753f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4754f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4755f9eb7ae2SShri Abhyankar 4756f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4757f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4758f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4759f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4760f9eb7ae2SShri Abhyankar /* 4761f9eb7ae2SShri Abhyankar This should work, but it doesn't 4762f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4763f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4764f9eb7ae2SShri Abhyankar */ 4765f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4766f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4767f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4768f9eb7ae2SShri Abhyankar } 4769f9eb7ae2SShri Abhyankar 477069b4f73cSBarry Smith #endif 4771