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); 19117fe4bdfSPeter Brune if (snes->gridsequence) { 19217fe4bdfSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr); 19317fe4bdfSPeter 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; 1616e03ab78fSPeter Brune DM dm; 1617e03ab78fSPeter Brune SNESDM sdm; 16186cab3a1bSJed Brown 16198b0a5094SBarry Smith PetscFunctionBegin; 1620e03ab78fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1621e03ab78fSPeter Brune ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 16228b0a5094SBarry Smith /* A(x)*x - b(x) */ 1623e03ab78fSPeter Brune if (sdm->computepfunction) { 1624e03ab78fSPeter Brune ierr = (*sdm->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 1625e03ab78fSPeter Brune } else if (snes->dm) { 1626e03ab78fSPeter Brune ierr = DMComputeFunction(snes->dm,x,f);CHKERRQ(ierr); 1627e03ab78fSPeter Brune } else { 1628e03ab78fSPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard function."); 1629e03ab78fSPeter Brune } 1630e03ab78fSPeter Brune 1631e03ab78fSPeter Brune if (sdm->computepjacobian) { 1632e03ab78fSPeter Brune ierr = (*sdm->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,sdm->pctx);CHKERRQ(ierr); 1633e03ab78fSPeter Brune } else if (snes->dm) { 1634e03ab78fSPeter Brune ierr = DMComputeJacobian(snes->dm,x,snes->jacobian,snes->jacobian_pre,&snes->matstruct);CHKERRQ(ierr); 1635e03ab78fSPeter Brune } else { 1636e03ab78fSPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard matrix."); 1637e03ab78fSPeter Brune } 1638e03ab78fSPeter Brune 16398b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16408b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16418b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 16428b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 16438b0a5094SBarry Smith PetscFunctionReturn(0); 16448b0a5094SBarry Smith } 16458b0a5094SBarry Smith 16468b0a5094SBarry Smith #undef __FUNCT__ 16478b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 16488b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 16498b0a5094SBarry Smith { 16508b0a5094SBarry Smith PetscFunctionBegin; 1651e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 16528b0a5094SBarry Smith *flag = snes->matstruct; 16538b0a5094SBarry Smith PetscFunctionReturn(0); 16548b0a5094SBarry Smith } 16558b0a5094SBarry Smith 16568b0a5094SBarry Smith #undef __FUNCT__ 16578b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 16588b0a5094SBarry Smith /*@C 16590d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 16608b0a5094SBarry Smith 16618b0a5094SBarry Smith Logically Collective on SNES 16628b0a5094SBarry Smith 16638b0a5094SBarry Smith Input Parameters: 16648b0a5094SBarry Smith + snes - the SNES context 16658b0a5094SBarry Smith . r - vector to store function value 16668b0a5094SBarry Smith . func - function evaluation routine 16678b0a5094SBarry 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) 16688b0a5094SBarry Smith . mat - matrix to store A 16698b0a5094SBarry Smith . mfunc - function to compute matrix value 16708b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 16718b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 16728b0a5094SBarry Smith 16738b0a5094SBarry Smith Calling sequence of func: 16748b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 16758b0a5094SBarry Smith 16768b0a5094SBarry Smith + f - function vector 16778b0a5094SBarry Smith - ctx - optional user-defined function context 16788b0a5094SBarry Smith 16798b0a5094SBarry Smith Calling sequence of mfunc: 16808b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 16818b0a5094SBarry Smith 16828b0a5094SBarry Smith + x - input vector 16838b0a5094SBarry 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(), 16848b0a5094SBarry Smith normally just pass mat in this location 16858b0a5094SBarry Smith . mat - form A(x) matrix 16868b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 16878b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 16888b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 16898b0a5094SBarry Smith 16908b0a5094SBarry Smith Notes: 16918b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 16928b0a5094SBarry Smith 16938b0a5094SBarry 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} 16948b0a5094SBarry 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. 16958b0a5094SBarry Smith 16968b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 16978b0a5094SBarry Smith 16980d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 16990d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 17008b0a5094SBarry Smith 17018b0a5094SBarry 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 17028b0a5094SBarry 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 17038b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 17048b0a5094SBarry Smith 17058b0a5094SBarry Smith Level: beginner 17068b0a5094SBarry Smith 17078b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 17088b0a5094SBarry Smith 17090d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 17108b0a5094SBarry Smith @*/ 17118b0a5094SBarry 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) 17128b0a5094SBarry Smith { 17138b0a5094SBarry Smith PetscErrorCode ierr; 1714e03ab78fSPeter Brune DM dm; 1715e03ab78fSPeter Brune 17168b0a5094SBarry Smith PetscFunctionBegin; 17178b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1718e03ab78fSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 1719e03ab78fSPeter Brune ierr = DMSNESSetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr); 17208b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 17218b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 17228b0a5094SBarry Smith PetscFunctionReturn(0); 17238b0a5094SBarry Smith } 17248b0a5094SBarry Smith 17257971a8bfSPeter Brune 17267971a8bfSPeter Brune #undef __FUNCT__ 17277971a8bfSPeter Brune #define __FUNCT__ "SNESGetPicard" 17287971a8bfSPeter Brune /*@C 17297971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 17307971a8bfSPeter Brune 17317971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 17327971a8bfSPeter Brune 17337971a8bfSPeter Brune Input Parameter: 17347971a8bfSPeter Brune . snes - the SNES context 17357971a8bfSPeter Brune 17367971a8bfSPeter Brune Output Parameter: 17377971a8bfSPeter Brune + r - the function (or PETSC_NULL) 17387971a8bfSPeter Brune . func - the function (or PETSC_NULL) 17397971a8bfSPeter Brune . jmat - the picard matrix (or PETSC_NULL) 17407971a8bfSPeter Brune . mat - the picard preconditioner matrix (or PETSC_NULL) 17417971a8bfSPeter Brune . mfunc - the function for matrix evaluation (or PETSC_NULL) 17427971a8bfSPeter Brune - ctx - the function context (or PETSC_NULL) 17437971a8bfSPeter Brune 17447971a8bfSPeter Brune Level: advanced 17457971a8bfSPeter Brune 17467971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function 17477971a8bfSPeter Brune 17487971a8bfSPeter Brune .seealso: SNESSetPicard, SNESGetFunction, SNESGetJacobian, SNESGetDM 17497971a8bfSPeter Brune @*/ 17507971a8bfSPeter Brune PetscErrorCode SNESGetPicard(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),Mat *jmat, Mat *mat, PetscErrorCode (**mfunc)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 17517971a8bfSPeter Brune { 17527971a8bfSPeter Brune PetscErrorCode ierr; 17537971a8bfSPeter Brune DM dm; 17547971a8bfSPeter Brune 17557971a8bfSPeter Brune PetscFunctionBegin; 17567971a8bfSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17577971a8bfSPeter Brune ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 17587971a8bfSPeter Brune ierr = SNESGetJacobian(snes,jmat,mat,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 17597971a8bfSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 17607971a8bfSPeter Brune ierr = DMSNESGetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr); 17617971a8bfSPeter Brune PetscFunctionReturn(0); 17627971a8bfSPeter Brune } 17637971a8bfSPeter Brune 17648b0a5094SBarry Smith #undef __FUNCT__ 1765d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1766d25893d9SBarry Smith /*@C 1767d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1768d25893d9SBarry Smith 1769d25893d9SBarry Smith Logically Collective on SNES 1770d25893d9SBarry Smith 1771d25893d9SBarry Smith Input Parameters: 1772d25893d9SBarry Smith + snes - the SNES context 1773d25893d9SBarry Smith . func - function evaluation routine 1774d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1775d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1776d25893d9SBarry Smith 1777d25893d9SBarry Smith Calling sequence of func: 1778d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1779d25893d9SBarry Smith 1780d25893d9SBarry Smith . f - function vector 1781d25893d9SBarry Smith - ctx - optional user-defined function context 1782d25893d9SBarry Smith 1783d25893d9SBarry Smith Level: intermediate 1784d25893d9SBarry Smith 1785d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1786d25893d9SBarry Smith 1787d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1788d25893d9SBarry Smith @*/ 1789d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1790d25893d9SBarry Smith { 1791d25893d9SBarry Smith PetscFunctionBegin; 1792d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1793d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1794d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1795d25893d9SBarry Smith PetscFunctionReturn(0); 1796d25893d9SBarry Smith } 1797d25893d9SBarry Smith 17983ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 17993ab0aad5SBarry Smith #undef __FUNCT__ 18001096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 18011096aae1SMatthew Knepley /*@C 18021096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 18031096aae1SMatthew Knepley it assumes a zero right hand side. 18041096aae1SMatthew Knepley 18053f9fe445SBarry Smith Logically Collective on SNES 18061096aae1SMatthew Knepley 18071096aae1SMatthew Knepley Input Parameter: 18081096aae1SMatthew Knepley . snes - the SNES context 18091096aae1SMatthew Knepley 18101096aae1SMatthew Knepley Output Parameter: 1811bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 18121096aae1SMatthew Knepley 18131096aae1SMatthew Knepley Level: intermediate 18141096aae1SMatthew Knepley 18151096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 18161096aae1SMatthew Knepley 181785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 18181096aae1SMatthew Knepley @*/ 18197087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 18201096aae1SMatthew Knepley { 18211096aae1SMatthew Knepley PetscFunctionBegin; 18220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18231096aae1SMatthew Knepley PetscValidPointer(rhs,2); 182485385478SLisandro Dalcin *rhs = snes->vec_rhs; 18251096aae1SMatthew Knepley PetscFunctionReturn(0); 18261096aae1SMatthew Knepley } 18271096aae1SMatthew Knepley 18281096aae1SMatthew Knepley #undef __FUNCT__ 18294a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 18309b94acceSBarry Smith /*@ 183136851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 18329b94acceSBarry Smith SNESSetFunction(). 18339b94acceSBarry Smith 1834c7afd0dbSLois Curfman McInnes Collective on SNES 1835c7afd0dbSLois Curfman McInnes 18369b94acceSBarry Smith Input Parameters: 1837c7afd0dbSLois Curfman McInnes + snes - the SNES context 1838c7afd0dbSLois Curfman McInnes - x - input vector 18399b94acceSBarry Smith 18409b94acceSBarry Smith Output Parameter: 18413638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 18429b94acceSBarry Smith 18431bffabb2SLois Curfman McInnes Notes: 184436851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 184536851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 184636851e7fSLois Curfman McInnes themselves. 184736851e7fSLois Curfman McInnes 184836851e7fSLois Curfman McInnes Level: developer 184936851e7fSLois Curfman McInnes 18509b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 18519b94acceSBarry Smith 1852a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 18539b94acceSBarry Smith @*/ 18547087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 18559b94acceSBarry Smith { 1856dfbe8321SBarry Smith PetscErrorCode ierr; 18576cab3a1bSJed Brown DM dm; 18586cab3a1bSJed Brown SNESDM sdm; 18599b94acceSBarry Smith 18603a40ed3dSBarry Smith PetscFunctionBegin; 18610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18620700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 18630700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1864c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1865c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 18664ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1867184914b5SBarry Smith 18686cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18696cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1870d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18716cab3a1bSJed Brown if (sdm->computefunction) { 1872d64ed03dSBarry Smith PetscStackPush("SNES user function"); 18736cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1874d64ed03dSBarry Smith PetscStackPop; 187573250ac0SBarry Smith } else if (snes->dm) { 1876644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1877c90fad12SPeter Brune } else if (snes->vec_rhs) { 1878c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1879644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 188085385478SLisandro Dalcin if (snes->vec_rhs) { 188185385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 18823ab0aad5SBarry Smith } 1883ae3c334cSLois Curfman McInnes snes->nfuncs++; 1884d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18854ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 18863a40ed3dSBarry Smith PetscFunctionReturn(0); 18879b94acceSBarry Smith } 18889b94acceSBarry Smith 18894a2ae208SSatish Balay #undef __FUNCT__ 1890646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1891c79ef259SPeter Brune /*@ 1892c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1893c79ef259SPeter Brune SNESSetGS(). 1894c79ef259SPeter Brune 1895c79ef259SPeter Brune Collective on SNES 1896c79ef259SPeter Brune 1897c79ef259SPeter Brune Input Parameters: 1898c79ef259SPeter Brune + snes - the SNES context 1899c79ef259SPeter Brune . x - input vector 1900c79ef259SPeter Brune - b - rhs vector 1901c79ef259SPeter Brune 1902c79ef259SPeter Brune Output Parameter: 1903c79ef259SPeter Brune . x - new solution vector 1904c79ef259SPeter Brune 1905c79ef259SPeter Brune Notes: 1906c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1907c79ef259SPeter Brune implementations, so most users would not generally call this routine 1908c79ef259SPeter Brune themselves. 1909c79ef259SPeter Brune 1910c79ef259SPeter Brune Level: developer 1911c79ef259SPeter Brune 1912c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1913c79ef259SPeter Brune 1914c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1915c79ef259SPeter Brune @*/ 1916646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1917646217ecSPeter Brune { 1918646217ecSPeter Brune PetscErrorCode ierr; 191989b92e6fSPeter Brune PetscInt i; 19206cab3a1bSJed Brown DM dm; 19216cab3a1bSJed Brown SNESDM sdm; 1922646217ecSPeter Brune 1923646217ecSPeter Brune PetscFunctionBegin; 1924646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1925646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1926646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1927646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1928646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 19294ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1930701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 19316cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19326cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19336cab3a1bSJed Brown if (sdm->computegs) { 193489b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1935646217ecSPeter Brune PetscStackPush("SNES user GS"); 19366cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1937646217ecSPeter Brune PetscStackPop; 193889b92e6fSPeter Brune } 1939646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1940701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 19414ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1942646217ecSPeter Brune PetscFunctionReturn(0); 1943646217ecSPeter Brune } 1944646217ecSPeter Brune 1945646217ecSPeter Brune 1946646217ecSPeter Brune #undef __FUNCT__ 19474a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 194862fef451SLois Curfman McInnes /*@ 194962fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 195062fef451SLois Curfman McInnes set with SNESSetJacobian(). 195162fef451SLois Curfman McInnes 1952c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1953c7afd0dbSLois Curfman McInnes 195462fef451SLois Curfman McInnes Input Parameters: 1955c7afd0dbSLois Curfman McInnes + snes - the SNES context 1956c7afd0dbSLois Curfman McInnes - x - input vector 195762fef451SLois Curfman McInnes 195862fef451SLois Curfman McInnes Output Parameters: 1959c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 196062fef451SLois Curfman McInnes . B - optional preconditioning matrix 19612b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1962fee21e36SBarry Smith 1963e35cf81dSBarry Smith Options Database Keys: 1964e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1965693365a8SJed Brown . -snes_lag_jacobian <lag> 1966693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1967693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1968693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 19694c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1970c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1971c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 1972c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 1973c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 1974c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 19754c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 1976c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 1977c01495d3SJed Brown 1978e35cf81dSBarry Smith 197962fef451SLois Curfman McInnes Notes: 198062fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 198162fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 198262fef451SLois Curfman McInnes 198394b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 1984dc5a77f8SLois Curfman McInnes flag parameter. 198562fef451SLois Curfman McInnes 198636851e7fSLois Curfman McInnes Level: developer 198736851e7fSLois Curfman McInnes 198862fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 198962fef451SLois Curfman McInnes 1990e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 199162fef451SLois Curfman McInnes @*/ 19927087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 19939b94acceSBarry Smith { 1994dfbe8321SBarry Smith PetscErrorCode ierr; 1995ace3abfcSBarry Smith PetscBool flag; 19966cab3a1bSJed Brown DM dm; 19976cab3a1bSJed Brown SNESDM sdm; 19983a40ed3dSBarry Smith 19993a40ed3dSBarry Smith PetscFunctionBegin; 20000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20010700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 20024482741eSBarry Smith PetscValidPointer(flg,5); 2003c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 20044ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 20056cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 20066cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 20076cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2008ebd3b9afSBarry Smith 2009ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2010ebd3b9afSBarry Smith 2011fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2012fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2013fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2014fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 2015e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 2016e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 2017251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 2018ebd3b9afSBarry Smith if (flag) { 2019ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2020ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2021ebd3b9afSBarry Smith } 2022e35cf81dSBarry Smith PetscFunctionReturn(0); 2023e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 2024e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 2025e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 2026251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 2027ebd3b9afSBarry Smith if (flag) { 2028ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2029ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2030ebd3b9afSBarry Smith } 2031e35cf81dSBarry Smith PetscFunctionReturn(0); 2032e35cf81dSBarry Smith } 2033e35cf81dSBarry Smith 2034c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 2035e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 2036d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 20376cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 2038d64ed03dSBarry Smith PetscStackPop; 2039d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 2040a8054027SBarry Smith 20413b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 20423b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 20433b4f5425SBarry Smith snes->lagpreconditioner = -1; 20443b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2045a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2046a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2047a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 2048a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2049a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2050a8054027SBarry Smith } 2051a8054027SBarry Smith 20526d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 20530700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 20540700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 2055693365a8SJed Brown { 2056693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2057693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 2058693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 2059693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 2060693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 2061693365a8SJed Brown if (flag || flag_draw || flag_contour) { 2062693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 2063693365a8SJed Brown MatStructure mstruct; 2064693365a8SJed Brown PetscViewer vdraw,vstdout; 20656b3a5b13SJed Brown PetscBool flg; 2066693365a8SJed Brown if (flag_operator) { 2067693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 2068693365a8SJed Brown Bexp = Bexp_mine; 2069693365a8SJed Brown } else { 2070693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2071251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2072693365a8SJed Brown if (flg) Bexp = *B; 2073693365a8SJed Brown else { 2074693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2075693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 2076693365a8SJed Brown Bexp = Bexp_mine; 2077693365a8SJed Brown } 2078693365a8SJed Brown } 2079693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2080693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 2081693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 2082693365a8SJed Brown if (flag_draw || flag_contour) { 2083693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2084693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2085693365a8SJed Brown } else vdraw = PETSC_NULL; 2086693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 2087693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2088693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2089693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2090693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2091693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2092693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2093693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2094693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2095693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2096693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2097693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2098693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2099693365a8SJed Brown } 2100693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2101693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2102693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2103693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2104693365a8SJed Brown } 2105693365a8SJed Brown } 21064c30e9fbSJed Brown { 21076719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 21086719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 21094c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 21106719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 21114c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 21124c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 21136719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 21146719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 21156719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 21166719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 21174c30e9fbSJed Brown Mat Bfd; 21184c30e9fbSJed Brown MatStructure mstruct; 21194c30e9fbSJed Brown PetscViewer vdraw,vstdout; 21204c30e9fbSJed Brown ISColoring iscoloring; 21214c30e9fbSJed Brown MatFDColoring matfdcoloring; 21224c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 21234c30e9fbSJed Brown void *funcctx; 21246719d8e4SJed Brown PetscReal norm1,norm2,normmax; 21254c30e9fbSJed Brown 21264c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 21274c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 21284c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 21294c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 21304c30e9fbSJed Brown 21314c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 21324c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 21334c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 21344c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 21354c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 21364c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 21374c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 21384c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 21394c30e9fbSJed Brown 21404c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 21414c30e9fbSJed Brown if (flag_draw || flag_contour) { 21424c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 21434c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 21444c30e9fbSJed Brown } else vdraw = PETSC_NULL; 21454c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 21466719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 21474c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 21484c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 21496719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21504c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 21514c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 21524c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 21536719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 21544c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 21556719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 21566719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21574c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 21584c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 21594c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 21604c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 21614c30e9fbSJed Brown } 21624c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 21636719d8e4SJed Brown 21646719d8e4SJed Brown if (flag_threshold) { 21656719d8e4SJed Brown PetscInt bs,rstart,rend,i; 21666719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 21676719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 21686719d8e4SJed Brown for (i=rstart; i<rend; i++) { 21696719d8e4SJed Brown const PetscScalar *ba,*ca; 21706719d8e4SJed Brown const PetscInt *bj,*cj; 21716719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 21726719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 21736719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 21746719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 21756719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 21766719d8e4SJed Brown for (j=0; j<bn; j++) { 21776719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21786719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 21796719d8e4SJed Brown maxentrycol = bj[j]; 21806719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 21816719d8e4SJed Brown } 21826719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 21836719d8e4SJed Brown maxdiffcol = bj[j]; 21846719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 21856719d8e4SJed Brown } 21866719d8e4SJed Brown if (rdiff > maxrdiff) { 21876719d8e4SJed Brown maxrdiffcol = bj[j]; 21886719d8e4SJed Brown maxrdiff = rdiff; 21896719d8e4SJed Brown } 21906719d8e4SJed Brown } 21916719d8e4SJed Brown if (maxrdiff > 1) { 21926719d8e4SJed 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); 21936719d8e4SJed Brown for (j=0; j<bn; j++) { 21946719d8e4SJed Brown PetscReal rdiff; 21956719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 21966719d8e4SJed Brown if (rdiff > 1) { 21976719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 21986719d8e4SJed Brown } 21996719d8e4SJed Brown } 22006719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 22016719d8e4SJed Brown } 22026719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 22036719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 22046719d8e4SJed Brown } 22056719d8e4SJed Brown } 22064c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 22074c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 22084c30e9fbSJed Brown } 22094c30e9fbSJed Brown } 22103a40ed3dSBarry Smith PetscFunctionReturn(0); 22119b94acceSBarry Smith } 22129b94acceSBarry Smith 22134a2ae208SSatish Balay #undef __FUNCT__ 22144a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 22159b94acceSBarry Smith /*@C 22169b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2217044dda88SLois Curfman McInnes location to store the matrix. 22189b94acceSBarry Smith 22193f9fe445SBarry Smith Logically Collective on SNES and Mat 2220c7afd0dbSLois Curfman McInnes 22219b94acceSBarry Smith Input Parameters: 2222c7afd0dbSLois Curfman McInnes + snes - the SNES context 22239b94acceSBarry Smith . A - Jacobian matrix 22249b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2225efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2226c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2227efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 22289b94acceSBarry Smith 22299b94acceSBarry Smith Calling sequence of func: 22308d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 22319b94acceSBarry Smith 2232c7afd0dbSLois Curfman McInnes + x - input vector 22339b94acceSBarry Smith . A - Jacobian matrix 22349b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2235ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 22362b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2237c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 22389b94acceSBarry Smith 22399b94acceSBarry Smith Notes: 224094b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 22412cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2242ac21db08SLois Curfman McInnes 2243ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 22449b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 22459b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 22469b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 22479b94acceSBarry Smith throughout the global iterations. 22489b94acceSBarry Smith 224916913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 225016913363SBarry Smith each matrix. 225116913363SBarry Smith 2252a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2253a8a26c1eSJed Brown must be a MatFDColoring. 2254a8a26c1eSJed Brown 2255c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2256c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2257c3cc8fd1SJed Brown 225836851e7fSLois Curfman McInnes Level: beginner 225936851e7fSLois Curfman McInnes 22609b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 22619b94acceSBarry Smith 22623ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 22639b94acceSBarry Smith @*/ 22647087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 22659b94acceSBarry Smith { 2266dfbe8321SBarry Smith PetscErrorCode ierr; 22676cab3a1bSJed Brown DM dm; 22683a7fca6bSBarry Smith 22693a40ed3dSBarry Smith PetscFunctionBegin; 22700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22710700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 22720700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2273c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 227406975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 22756cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 22766cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 22773a7fca6bSBarry Smith if (A) { 22787dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22796bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 22809b94acceSBarry Smith snes->jacobian = A; 22813a7fca6bSBarry Smith } 22823a7fca6bSBarry Smith if (B) { 22837dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 22846bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 22859b94acceSBarry Smith snes->jacobian_pre = B; 22863a7fca6bSBarry Smith } 22873a40ed3dSBarry Smith PetscFunctionReturn(0); 22889b94acceSBarry Smith } 228962fef451SLois Curfman McInnes 22904a2ae208SSatish Balay #undef __FUNCT__ 22914a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2292c2aafc4cSSatish Balay /*@C 2293b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2294b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2295b4fd4287SBarry Smith 2296c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2297c7afd0dbSLois Curfman McInnes 2298b4fd4287SBarry Smith Input Parameter: 2299b4fd4287SBarry Smith . snes - the nonlinear solver context 2300b4fd4287SBarry Smith 2301b4fd4287SBarry Smith Output Parameters: 2302c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2303b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 230470e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 230570e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2306fee21e36SBarry Smith 230736851e7fSLois Curfman McInnes Level: advanced 230836851e7fSLois Curfman McInnes 2309b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2310b4fd4287SBarry Smith @*/ 23117087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2312b4fd4287SBarry Smith { 23136cab3a1bSJed Brown PetscErrorCode ierr; 23146cab3a1bSJed Brown DM dm; 23156cab3a1bSJed Brown SNESDM sdm; 23166cab3a1bSJed Brown 23173a40ed3dSBarry Smith PetscFunctionBegin; 23180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2319b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2320b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 23216cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23226cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23236cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 23246cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 23253a40ed3dSBarry Smith PetscFunctionReturn(0); 2326b4fd4287SBarry Smith } 2327b4fd4287SBarry Smith 23289b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 23299b94acceSBarry Smith 23304a2ae208SSatish Balay #undef __FUNCT__ 23314a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 23329b94acceSBarry Smith /*@ 23339b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2334272ac6f2SLois Curfman McInnes of a nonlinear solver. 23359b94acceSBarry Smith 2336fee21e36SBarry Smith Collective on SNES 2337fee21e36SBarry Smith 2338c7afd0dbSLois Curfman McInnes Input Parameters: 233970e92668SMatthew Knepley . snes - the SNES context 2340c7afd0dbSLois Curfman McInnes 2341272ac6f2SLois Curfman McInnes Notes: 2342272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2343272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2344272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2345272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2346272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2347272ac6f2SLois Curfman McInnes 234836851e7fSLois Curfman McInnes Level: advanced 234936851e7fSLois Curfman McInnes 23509b94acceSBarry Smith .keywords: SNES, nonlinear, setup 23519b94acceSBarry Smith 23529b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 23539b94acceSBarry Smith @*/ 23547087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 23559b94acceSBarry Smith { 2356dfbe8321SBarry Smith PetscErrorCode ierr; 23576cab3a1bSJed Brown DM dm; 23586cab3a1bSJed Brown SNESDM sdm; 23596e2a1849SPeter Brune SNESLineSearch linesearch; 23606e2a1849SPeter Brune SNESLineSearch pclinesearch; 23616e2a1849SPeter Brune void *lsprectx,*lspostctx; 23626e2a1849SPeter Brune SNESLineSearchPreCheckFunc lsprefunc; 23636e2a1849SPeter Brune SNESLineSearchPostCheckFunc lspostfunc; 23646e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 23656e2a1849SPeter Brune Vec f,fpc; 23666e2a1849SPeter Brune void *funcctx; 23676e2a1849SPeter Brune PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 23686e2a1849SPeter Brune void *jacctx; 23696e2a1849SPeter Brune Mat A,B; 23703a40ed3dSBarry Smith 23713a40ed3dSBarry Smith PetscFunctionBegin; 23720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23734dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 23749b94acceSBarry Smith 23757adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 237685385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 237785385478SLisandro Dalcin } 237885385478SLisandro Dalcin 2379a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 238017186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 238158c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 238258c9b817SLisandro Dalcin 238358c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 238458c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 238558c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 238658c9b817SLisandro Dalcin } 238758c9b817SLisandro Dalcin 23886cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23896cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 23906cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23916cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 23926cab3a1bSJed Brown if (!snes->vec_func) { 23936cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2394214df951SJed Brown } 2395efd51863SBarry Smith 2396b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2397b710008aSBarry Smith 2398f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 23999e764e56SPeter Brune 2400d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2401d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2402d25893d9SBarry Smith } 2403d25893d9SBarry Smith 24046e2a1849SPeter Brune if (snes->pc) { 24056e2a1849SPeter Brune /* copy the DM over */ 24066e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 24076e2a1849SPeter Brune ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr); 24086e2a1849SPeter Brune 24096e2a1849SPeter Brune /* copy the legacy SNES context not related to the DM over*/ 24106e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 24116e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 24126e2a1849SPeter Brune ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr); 24136e2a1849SPeter Brune ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr); 24146e2a1849SPeter Brune ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr); 24156e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 24166e2a1849SPeter Brune 24176e2a1849SPeter Brune /* copy the function pointers over */ 24186e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr); 24196e2a1849SPeter Brune 24206e2a1849SPeter Brune /* default to 1 iteration */ 2421*140836e4SPeter Brune ierr = SNESSetTolerances(snes->pc, 0.0, 0.0, 0.0, 1, snes->pc->max_funcs);CHKERRQ(ierr); 24226e2a1849SPeter Brune ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 24236e2a1849SPeter Brune ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 24246e2a1849SPeter Brune 24256e2a1849SPeter Brune /* copy the line search context over */ 24266e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr); 24276e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr); 24286e2a1849SPeter Brune ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr); 24296e2a1849SPeter Brune ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr); 24306e2a1849SPeter Brune ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr); 24316e2a1849SPeter Brune ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr); 24326e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 24336e2a1849SPeter Brune } 24346e2a1849SPeter Brune 2435410397dcSLisandro Dalcin if (snes->ops->setup) { 2436410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2437410397dcSLisandro Dalcin } 243858c9b817SLisandro Dalcin 24397aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 24403a40ed3dSBarry Smith PetscFunctionReturn(0); 24419b94acceSBarry Smith } 24429b94acceSBarry Smith 24434a2ae208SSatish Balay #undef __FUNCT__ 244437596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 244537596af1SLisandro Dalcin /*@ 244637596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 244737596af1SLisandro Dalcin 244837596af1SLisandro Dalcin Collective on SNES 244937596af1SLisandro Dalcin 245037596af1SLisandro Dalcin Input Parameter: 245137596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 245237596af1SLisandro Dalcin 2453d25893d9SBarry Smith Level: intermediate 2454d25893d9SBarry Smith 2455d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 245637596af1SLisandro Dalcin 245737596af1SLisandro Dalcin .keywords: SNES, destroy 245837596af1SLisandro Dalcin 245937596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 246037596af1SLisandro Dalcin @*/ 246137596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 246237596af1SLisandro Dalcin { 246337596af1SLisandro Dalcin PetscErrorCode ierr; 246437596af1SLisandro Dalcin 246537596af1SLisandro Dalcin PetscFunctionBegin; 246637596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2467d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2468d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2469d25893d9SBarry Smith snes->user = PETSC_NULL; 2470d25893d9SBarry Smith } 24718a23116dSBarry Smith if (snes->pc) { 24728a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 24738a23116dSBarry Smith } 24748a23116dSBarry Smith 247537596af1SLisandro Dalcin if (snes->ops->reset) { 247637596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 247737596af1SLisandro Dalcin } 24789e764e56SPeter Brune if (snes->ksp) { 24799e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 24809e764e56SPeter Brune } 24819e764e56SPeter Brune 24829e764e56SPeter Brune if (snes->linesearch) { 2483f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 24849e764e56SPeter Brune } 24859e764e56SPeter Brune 24866bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 24876bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 24886bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 24896bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 24906bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 24916bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2492c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2493c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 249437596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 249537596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 249637596af1SLisandro Dalcin PetscFunctionReturn(0); 249737596af1SLisandro Dalcin } 249837596af1SLisandro Dalcin 249937596af1SLisandro Dalcin #undef __FUNCT__ 25004a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 250152baeb72SSatish Balay /*@ 25029b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 25039b94acceSBarry Smith with SNESCreate(). 25049b94acceSBarry Smith 2505c7afd0dbSLois Curfman McInnes Collective on SNES 2506c7afd0dbSLois Curfman McInnes 25079b94acceSBarry Smith Input Parameter: 25089b94acceSBarry Smith . snes - the SNES context 25099b94acceSBarry Smith 251036851e7fSLois Curfman McInnes Level: beginner 251136851e7fSLois Curfman McInnes 25129b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 25139b94acceSBarry Smith 251463a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 25159b94acceSBarry Smith @*/ 25166bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 25179b94acceSBarry Smith { 25186849ba73SBarry Smith PetscErrorCode ierr; 25193a40ed3dSBarry Smith 25203a40ed3dSBarry Smith PetscFunctionBegin; 25216bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 25226bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 25236bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2524d4bb536fSBarry Smith 25256bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 25268a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 25276b8b9a38SLisandro Dalcin 2528be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 25296bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 25306bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 25316d4c513bSLisandro Dalcin 25326bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 25336bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2534f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 25356b8b9a38SLisandro Dalcin 25366bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 25376bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 25386bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 25396b8b9a38SLisandro Dalcin } 25406bf464f9SBarry Smith if ((*snes)->conv_malloc) { 25416bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 25426bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 254358c9b817SLisandro Dalcin } 25446bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2545a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 25463a40ed3dSBarry Smith PetscFunctionReturn(0); 25479b94acceSBarry Smith } 25489b94acceSBarry Smith 25499b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 25509b94acceSBarry Smith 25514a2ae208SSatish Balay #undef __FUNCT__ 2552a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2553a8054027SBarry Smith /*@ 2554a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2555a8054027SBarry Smith 25563f9fe445SBarry Smith Logically Collective on SNES 2557a8054027SBarry Smith 2558a8054027SBarry Smith Input Parameters: 2559a8054027SBarry Smith + snes - the SNES context 2560a8054027SBarry 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 25613b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2562a8054027SBarry Smith 2563a8054027SBarry Smith Options Database Keys: 2564a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2565a8054027SBarry Smith 2566a8054027SBarry Smith Notes: 2567a8054027SBarry Smith The default is 1 2568a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2569a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2570a8054027SBarry Smith 2571a8054027SBarry Smith Level: intermediate 2572a8054027SBarry Smith 2573a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2574a8054027SBarry Smith 2575e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2576a8054027SBarry Smith 2577a8054027SBarry Smith @*/ 25787087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2579a8054027SBarry Smith { 2580a8054027SBarry Smith PetscFunctionBegin; 25810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2582e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2583e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2584c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2585a8054027SBarry Smith snes->lagpreconditioner = lag; 2586a8054027SBarry Smith PetscFunctionReturn(0); 2587a8054027SBarry Smith } 2588a8054027SBarry Smith 2589a8054027SBarry Smith #undef __FUNCT__ 2590efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2591efd51863SBarry Smith /*@ 2592efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2593efd51863SBarry Smith 2594efd51863SBarry Smith Logically Collective on SNES 2595efd51863SBarry Smith 2596efd51863SBarry Smith Input Parameters: 2597efd51863SBarry Smith + snes - the SNES context 2598efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2599efd51863SBarry Smith 2600efd51863SBarry Smith Options Database Keys: 2601efd51863SBarry Smith . -snes_grid_sequence <steps> 2602efd51863SBarry Smith 2603efd51863SBarry Smith Level: intermediate 2604efd51863SBarry Smith 2605c0df2a02SJed Brown Notes: 2606c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2607c0df2a02SJed Brown 2608efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2609efd51863SBarry Smith 2610efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2611efd51863SBarry Smith 2612efd51863SBarry Smith @*/ 2613efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2614efd51863SBarry Smith { 2615efd51863SBarry Smith PetscFunctionBegin; 2616efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2617efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2618efd51863SBarry Smith snes->gridsequence = steps; 2619efd51863SBarry Smith PetscFunctionReturn(0); 2620efd51863SBarry Smith } 2621efd51863SBarry Smith 2622efd51863SBarry Smith #undef __FUNCT__ 2623a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2624a8054027SBarry Smith /*@ 2625a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2626a8054027SBarry Smith 26273f9fe445SBarry Smith Not Collective 2628a8054027SBarry Smith 2629a8054027SBarry Smith Input Parameter: 2630a8054027SBarry Smith . snes - the SNES context 2631a8054027SBarry Smith 2632a8054027SBarry Smith Output Parameter: 2633a8054027SBarry 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 26343b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2635a8054027SBarry Smith 2636a8054027SBarry Smith Options Database Keys: 2637a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2638a8054027SBarry Smith 2639a8054027SBarry Smith Notes: 2640a8054027SBarry Smith The default is 1 2641a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2642a8054027SBarry Smith 2643a8054027SBarry Smith Level: intermediate 2644a8054027SBarry Smith 2645a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2646a8054027SBarry Smith 2647a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2648a8054027SBarry Smith 2649a8054027SBarry Smith @*/ 26507087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2651a8054027SBarry Smith { 2652a8054027SBarry Smith PetscFunctionBegin; 26530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2654a8054027SBarry Smith *lag = snes->lagpreconditioner; 2655a8054027SBarry Smith PetscFunctionReturn(0); 2656a8054027SBarry Smith } 2657a8054027SBarry Smith 2658a8054027SBarry Smith #undef __FUNCT__ 2659e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2660e35cf81dSBarry Smith /*@ 2661e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2662e35cf81dSBarry Smith often the preconditioner is rebuilt. 2663e35cf81dSBarry Smith 26643f9fe445SBarry Smith Logically Collective on SNES 2665e35cf81dSBarry Smith 2666e35cf81dSBarry Smith Input Parameters: 2667e35cf81dSBarry Smith + snes - the SNES context 2668e35cf81dSBarry 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 2669fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2670e35cf81dSBarry Smith 2671e35cf81dSBarry Smith Options Database Keys: 2672e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2673e35cf81dSBarry Smith 2674e35cf81dSBarry Smith Notes: 2675e35cf81dSBarry Smith The default is 1 2676e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2677fe3ffe1eSBarry 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 2678fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2679e35cf81dSBarry Smith 2680e35cf81dSBarry Smith Level: intermediate 2681e35cf81dSBarry Smith 2682e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2683e35cf81dSBarry Smith 2684e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2685e35cf81dSBarry Smith 2686e35cf81dSBarry Smith @*/ 26877087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2688e35cf81dSBarry Smith { 2689e35cf81dSBarry Smith PetscFunctionBegin; 26900700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2691e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2692e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2693c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2694e35cf81dSBarry Smith snes->lagjacobian = lag; 2695e35cf81dSBarry Smith PetscFunctionReturn(0); 2696e35cf81dSBarry Smith } 2697e35cf81dSBarry Smith 2698e35cf81dSBarry Smith #undef __FUNCT__ 2699e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2700e35cf81dSBarry Smith /*@ 2701e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2702e35cf81dSBarry Smith 27033f9fe445SBarry Smith Not Collective 2704e35cf81dSBarry Smith 2705e35cf81dSBarry Smith Input Parameter: 2706e35cf81dSBarry Smith . snes - the SNES context 2707e35cf81dSBarry Smith 2708e35cf81dSBarry Smith Output Parameter: 2709e35cf81dSBarry 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 2710e35cf81dSBarry Smith the Jacobian is built etc. 2711e35cf81dSBarry Smith 2712e35cf81dSBarry Smith Options Database Keys: 2713e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2714e35cf81dSBarry Smith 2715e35cf81dSBarry Smith Notes: 2716e35cf81dSBarry Smith The default is 1 2717e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2718e35cf81dSBarry Smith 2719e35cf81dSBarry Smith Level: intermediate 2720e35cf81dSBarry Smith 2721e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2722e35cf81dSBarry Smith 2723e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2724e35cf81dSBarry Smith 2725e35cf81dSBarry Smith @*/ 27267087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2727e35cf81dSBarry Smith { 2728e35cf81dSBarry Smith PetscFunctionBegin; 27290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2730e35cf81dSBarry Smith *lag = snes->lagjacobian; 2731e35cf81dSBarry Smith PetscFunctionReturn(0); 2732e35cf81dSBarry Smith } 2733e35cf81dSBarry Smith 2734e35cf81dSBarry Smith #undef __FUNCT__ 27354a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 27369b94acceSBarry Smith /*@ 2737d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 27389b94acceSBarry Smith 27393f9fe445SBarry Smith Logically Collective on SNES 2740c7afd0dbSLois Curfman McInnes 27419b94acceSBarry Smith Input Parameters: 2742c7afd0dbSLois Curfman McInnes + snes - the SNES context 274370441072SBarry Smith . abstol - absolute convergence tolerance 274433174efeSLois Curfman McInnes . rtol - relative convergence tolerance 274533174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 274633174efeSLois Curfman McInnes of the change in the solution between steps 274733174efeSLois Curfman McInnes . maxit - maximum number of iterations 2748c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2749fee21e36SBarry Smith 275033174efeSLois Curfman McInnes Options Database Keys: 275170441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2752c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2753c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2754c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2755c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 27569b94acceSBarry Smith 2757d7a720efSLois Curfman McInnes Notes: 27589b94acceSBarry Smith The default maximum number of iterations is 50. 27599b94acceSBarry Smith The default maximum number of function evaluations is 1000. 27609b94acceSBarry Smith 276136851e7fSLois Curfman McInnes Level: intermediate 276236851e7fSLois Curfman McInnes 276333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 27649b94acceSBarry Smith 27652492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 27669b94acceSBarry Smith @*/ 27677087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 27689b94acceSBarry Smith { 27693a40ed3dSBarry Smith PetscFunctionBegin; 27700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2771c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2772c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2773c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2774c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2775c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2776c5eb9154SBarry Smith 2777ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2778ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2779ab54825eSJed Brown snes->abstol = abstol; 2780ab54825eSJed Brown } 2781ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2782ab54825eSJed 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); 2783ab54825eSJed Brown snes->rtol = rtol; 2784ab54825eSJed Brown } 2785ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2786ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2787c60f73f4SPeter Brune snes->stol = stol; 2788ab54825eSJed Brown } 2789ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2790ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2791ab54825eSJed Brown snes->max_its = maxit; 2792ab54825eSJed Brown } 2793ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2794ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2795ab54825eSJed Brown snes->max_funcs = maxf; 2796ab54825eSJed Brown } 279788976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 27983a40ed3dSBarry Smith PetscFunctionReturn(0); 27999b94acceSBarry Smith } 28009b94acceSBarry Smith 28014a2ae208SSatish Balay #undef __FUNCT__ 28024a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 28039b94acceSBarry Smith /*@ 280433174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 280533174efeSLois Curfman McInnes 2806c7afd0dbSLois Curfman McInnes Not Collective 2807c7afd0dbSLois Curfman McInnes 280833174efeSLois Curfman McInnes Input Parameters: 2809c7afd0dbSLois Curfman McInnes + snes - the SNES context 281085385478SLisandro Dalcin . atol - absolute convergence tolerance 281133174efeSLois Curfman McInnes . rtol - relative convergence tolerance 281233174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 281333174efeSLois Curfman McInnes of the change in the solution between steps 281433174efeSLois Curfman McInnes . maxit - maximum number of iterations 2815c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2816fee21e36SBarry Smith 281733174efeSLois Curfman McInnes Notes: 281833174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 281933174efeSLois Curfman McInnes 282036851e7fSLois Curfman McInnes Level: intermediate 282136851e7fSLois Curfman McInnes 282233174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 282333174efeSLois Curfman McInnes 282433174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 282533174efeSLois Curfman McInnes @*/ 28267087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 282733174efeSLois Curfman McInnes { 28283a40ed3dSBarry Smith PetscFunctionBegin; 28290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 283085385478SLisandro Dalcin if (atol) *atol = snes->abstol; 283133174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2832c60f73f4SPeter Brune if (stol) *stol = snes->stol; 283333174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 283433174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 28353a40ed3dSBarry Smith PetscFunctionReturn(0); 283633174efeSLois Curfman McInnes } 283733174efeSLois Curfman McInnes 28384a2ae208SSatish Balay #undef __FUNCT__ 28394a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 284033174efeSLois Curfman McInnes /*@ 28419b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 28429b94acceSBarry Smith 28433f9fe445SBarry Smith Logically Collective on SNES 2844fee21e36SBarry Smith 2845c7afd0dbSLois Curfman McInnes Input Parameters: 2846c7afd0dbSLois Curfman McInnes + snes - the SNES context 2847c7afd0dbSLois Curfman McInnes - tol - tolerance 2848c7afd0dbSLois Curfman McInnes 28499b94acceSBarry Smith Options Database Key: 2850c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 28519b94acceSBarry Smith 285236851e7fSLois Curfman McInnes Level: intermediate 285336851e7fSLois Curfman McInnes 28549b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 28559b94acceSBarry Smith 28562492ecdbSBarry Smith .seealso: SNESSetTolerances() 28579b94acceSBarry Smith @*/ 28587087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 28599b94acceSBarry Smith { 28603a40ed3dSBarry Smith PetscFunctionBegin; 28610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2862c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 28639b94acceSBarry Smith snes->deltatol = tol; 28643a40ed3dSBarry Smith PetscFunctionReturn(0); 28659b94acceSBarry Smith } 28669b94acceSBarry Smith 2867df9fa365SBarry Smith /* 2868df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2869df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2870df9fa365SBarry Smith macros instead of functions 2871df9fa365SBarry Smith */ 28724a2ae208SSatish Balay #undef __FUNCT__ 2873a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 28747087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2875ce1608b8SBarry Smith { 2876dfbe8321SBarry Smith PetscErrorCode ierr; 2877ce1608b8SBarry Smith 2878ce1608b8SBarry Smith PetscFunctionBegin; 28790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2880a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2881ce1608b8SBarry Smith PetscFunctionReturn(0); 2882ce1608b8SBarry Smith } 2883ce1608b8SBarry Smith 28844a2ae208SSatish Balay #undef __FUNCT__ 2885a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 28867087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2887df9fa365SBarry Smith { 2888dfbe8321SBarry Smith PetscErrorCode ierr; 2889df9fa365SBarry Smith 2890df9fa365SBarry Smith PetscFunctionBegin; 2891a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2892df9fa365SBarry Smith PetscFunctionReturn(0); 2893df9fa365SBarry Smith } 2894df9fa365SBarry Smith 28954a2ae208SSatish Balay #undef __FUNCT__ 2896a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 28976bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2898df9fa365SBarry Smith { 2899dfbe8321SBarry Smith PetscErrorCode ierr; 2900df9fa365SBarry Smith 2901df9fa365SBarry Smith PetscFunctionBegin; 2902a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2903df9fa365SBarry Smith PetscFunctionReturn(0); 2904df9fa365SBarry Smith } 2905df9fa365SBarry Smith 29067087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2907b271bb04SBarry Smith #undef __FUNCT__ 2908b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 29097087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2910b271bb04SBarry Smith { 2911b271bb04SBarry Smith PetscDrawLG lg; 2912b271bb04SBarry Smith PetscErrorCode ierr; 2913b271bb04SBarry Smith PetscReal x,y,per; 2914b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2915b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2916b271bb04SBarry Smith PetscDraw draw; 2917b271bb04SBarry Smith PetscFunctionBegin; 2918b271bb04SBarry Smith if (!monctx) { 2919b271bb04SBarry Smith MPI_Comm comm; 2920b271bb04SBarry Smith 2921b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2922b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2923b271bb04SBarry Smith } 2924b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2925b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2926b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2927b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2928b271bb04SBarry Smith x = (PetscReal) n; 2929b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2930b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2931b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2932b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2933b271bb04SBarry Smith } 2934b271bb04SBarry Smith 2935b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2936b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2937b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2938b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2939b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2940b271bb04SBarry Smith x = (PetscReal) n; 2941b271bb04SBarry Smith y = 100.0*per; 2942b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2943b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2944b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2945b271bb04SBarry Smith } 2946b271bb04SBarry Smith 2947b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2948b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2949b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2950b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2951b271bb04SBarry Smith x = (PetscReal) n; 2952b271bb04SBarry Smith y = (prev - rnorm)/prev; 2953b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2954b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2955b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2956b271bb04SBarry Smith } 2957b271bb04SBarry Smith 2958b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2959b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2960b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2961b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2962b271bb04SBarry Smith x = (PetscReal) n; 2963b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2964b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2965b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2966b271bb04SBarry Smith } 2967b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2968b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2969b271bb04SBarry Smith } 2970b271bb04SBarry Smith prev = rnorm; 2971b271bb04SBarry Smith PetscFunctionReturn(0); 2972b271bb04SBarry Smith } 2973b271bb04SBarry Smith 2974b271bb04SBarry Smith #undef __FUNCT__ 2975b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 29767087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2977b271bb04SBarry Smith { 2978b271bb04SBarry Smith PetscErrorCode ierr; 2979b271bb04SBarry Smith 2980b271bb04SBarry Smith PetscFunctionBegin; 2981b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2982b271bb04SBarry Smith PetscFunctionReturn(0); 2983b271bb04SBarry Smith } 2984b271bb04SBarry Smith 2985b271bb04SBarry Smith #undef __FUNCT__ 2986b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 29876bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 2988b271bb04SBarry Smith { 2989b271bb04SBarry Smith PetscErrorCode ierr; 2990b271bb04SBarry Smith 2991b271bb04SBarry Smith PetscFunctionBegin; 2992b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2993b271bb04SBarry Smith PetscFunctionReturn(0); 2994b271bb04SBarry Smith } 2995b271bb04SBarry Smith 29967a03ce2fSLisandro Dalcin #undef __FUNCT__ 29977a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 2998228d79bcSJed Brown /*@ 2999228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3000228d79bcSJed Brown 3001228d79bcSJed Brown Collective on SNES 3002228d79bcSJed Brown 3003228d79bcSJed Brown Input Parameters: 3004228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 3005228d79bcSJed Brown . iter - iteration number 3006228d79bcSJed Brown - rnorm - relative norm of the residual 3007228d79bcSJed Brown 3008228d79bcSJed Brown Notes: 3009228d79bcSJed Brown This routine is called by the SNES implementations. 3010228d79bcSJed Brown It does not typically need to be called by the user. 3011228d79bcSJed Brown 3012228d79bcSJed Brown Level: developer 3013228d79bcSJed Brown 3014228d79bcSJed Brown .seealso: SNESMonitorSet() 3015228d79bcSJed Brown @*/ 30167a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 30177a03ce2fSLisandro Dalcin { 30187a03ce2fSLisandro Dalcin PetscErrorCode ierr; 30197a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 30207a03ce2fSLisandro Dalcin 30217a03ce2fSLisandro Dalcin PetscFunctionBegin; 30227a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 30237a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 30247a03ce2fSLisandro Dalcin } 30257a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 30267a03ce2fSLisandro Dalcin } 30277a03ce2fSLisandro Dalcin 30289b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 30299b94acceSBarry Smith 30304a2ae208SSatish Balay #undef __FUNCT__ 3031a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 30329b94acceSBarry Smith /*@C 3033a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 30349b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 30359b94acceSBarry Smith progress. 30369b94acceSBarry Smith 30373f9fe445SBarry Smith Logically Collective on SNES 3038fee21e36SBarry Smith 3039c7afd0dbSLois Curfman McInnes Input Parameters: 3040c7afd0dbSLois Curfman McInnes + snes - the SNES context 3041c7afd0dbSLois Curfman McInnes . func - monitoring routine 3042b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 3043e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 3044b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 3045b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 30469b94acceSBarry Smith 3047c7afd0dbSLois Curfman McInnes Calling sequence of func: 3048a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3049c7afd0dbSLois Curfman McInnes 3050c7afd0dbSLois Curfman McInnes + snes - the SNES context 3051c7afd0dbSLois Curfman McInnes . its - iteration number 3052c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 305340a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 30549b94acceSBarry Smith 30559665c990SLois Curfman McInnes Options Database Keys: 3056a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 3057a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 3058a6570f20SBarry Smith uses SNESMonitorLGCreate() 3059cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3060c7afd0dbSLois Curfman McInnes been hardwired into a code by 3061a6570f20SBarry Smith calls to SNESMonitorSet(), but 3062c7afd0dbSLois Curfman McInnes does not cancel those set via 3063c7afd0dbSLois Curfman McInnes the options database. 30649665c990SLois Curfman McInnes 3065639f9d9dSBarry Smith Notes: 30666bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3067a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 30686bc08f3fSLois Curfman McInnes order in which they were set. 3069639f9d9dSBarry Smith 3070025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3071025f1a04SBarry Smith 307236851e7fSLois Curfman McInnes Level: intermediate 307336851e7fSLois Curfman McInnes 30749b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 30759b94acceSBarry Smith 3076a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 30779b94acceSBarry Smith @*/ 3078c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 30799b94acceSBarry Smith { 3080b90d0a6eSBarry Smith PetscInt i; 3081649052a6SBarry Smith PetscErrorCode ierr; 3082b90d0a6eSBarry Smith 30833a40ed3dSBarry Smith PetscFunctionBegin; 30840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 308517186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3086b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 3087649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 3088649052a6SBarry Smith if (monitordestroy) { 3089c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3090649052a6SBarry Smith } 3091b90d0a6eSBarry Smith PetscFunctionReturn(0); 3092b90d0a6eSBarry Smith } 3093b90d0a6eSBarry Smith } 3094b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 3095b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3096639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 30973a40ed3dSBarry Smith PetscFunctionReturn(0); 30989b94acceSBarry Smith } 30999b94acceSBarry Smith 31004a2ae208SSatish Balay #undef __FUNCT__ 3101a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 31025cd90555SBarry Smith /*@C 3103a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 31045cd90555SBarry Smith 31053f9fe445SBarry Smith Logically Collective on SNES 3106c7afd0dbSLois Curfman McInnes 31075cd90555SBarry Smith Input Parameters: 31085cd90555SBarry Smith . snes - the SNES context 31095cd90555SBarry Smith 31101a480d89SAdministrator Options Database Key: 3111a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3112a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3113c7afd0dbSLois Curfman McInnes set via the options database 31145cd90555SBarry Smith 31155cd90555SBarry Smith Notes: 31165cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 31175cd90555SBarry Smith 311836851e7fSLois Curfman McInnes Level: intermediate 311936851e7fSLois Curfman McInnes 31205cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 31215cd90555SBarry Smith 3122a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 31235cd90555SBarry Smith @*/ 31247087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 31255cd90555SBarry Smith { 3126d952e501SBarry Smith PetscErrorCode ierr; 3127d952e501SBarry Smith PetscInt i; 3128d952e501SBarry Smith 31295cd90555SBarry Smith PetscFunctionBegin; 31300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3131d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3132d952e501SBarry Smith if (snes->monitordestroy[i]) { 31333c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3134d952e501SBarry Smith } 3135d952e501SBarry Smith } 31365cd90555SBarry Smith snes->numbermonitors = 0; 31375cd90555SBarry Smith PetscFunctionReturn(0); 31385cd90555SBarry Smith } 31395cd90555SBarry Smith 31404a2ae208SSatish Balay #undef __FUNCT__ 31414a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 31429b94acceSBarry Smith /*@C 31439b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 31449b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 31459b94acceSBarry Smith 31463f9fe445SBarry Smith Logically Collective on SNES 3147fee21e36SBarry Smith 3148c7afd0dbSLois Curfman McInnes Input Parameters: 3149c7afd0dbSLois Curfman McInnes + snes - the SNES context 3150c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 31517f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 31527f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 31539b94acceSBarry Smith 3154c7afd0dbSLois Curfman McInnes Calling sequence of func: 315506ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3156c7afd0dbSLois Curfman McInnes 3157c7afd0dbSLois Curfman McInnes + snes - the SNES context 315806ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3159c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3160184914b5SBarry Smith . reason - reason for convergence/divergence 3161c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 31624b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 31634b27c08aSLois Curfman McInnes - f - 2-norm of function 31649b94acceSBarry Smith 316536851e7fSLois Curfman McInnes Level: advanced 316636851e7fSLois Curfman McInnes 31679b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 31689b94acceSBarry Smith 316985385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 31709b94acceSBarry Smith @*/ 31717087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 31729b94acceSBarry Smith { 31737f7931b9SBarry Smith PetscErrorCode ierr; 31747f7931b9SBarry Smith 31753a40ed3dSBarry Smith PetscFunctionBegin; 31760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 317785385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 31787f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 31797f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 31807f7931b9SBarry Smith } 318185385478SLisandro Dalcin snes->ops->converged = func; 31827f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 318385385478SLisandro Dalcin snes->cnvP = cctx; 31843a40ed3dSBarry Smith PetscFunctionReturn(0); 31859b94acceSBarry Smith } 31869b94acceSBarry Smith 31874a2ae208SSatish Balay #undef __FUNCT__ 31884a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 318952baeb72SSatish Balay /*@ 3190184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3191184914b5SBarry Smith 3192184914b5SBarry Smith Not Collective 3193184914b5SBarry Smith 3194184914b5SBarry Smith Input Parameter: 3195184914b5SBarry Smith . snes - the SNES context 3196184914b5SBarry Smith 3197184914b5SBarry Smith Output Parameter: 31984d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3199184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3200184914b5SBarry Smith 3201184914b5SBarry Smith Level: intermediate 3202184914b5SBarry Smith 3203184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3204184914b5SBarry Smith 3205184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3206184914b5SBarry Smith 320785385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3208184914b5SBarry Smith @*/ 32097087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3210184914b5SBarry Smith { 3211184914b5SBarry Smith PetscFunctionBegin; 32120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32134482741eSBarry Smith PetscValidPointer(reason,2); 3214184914b5SBarry Smith *reason = snes->reason; 3215184914b5SBarry Smith PetscFunctionReturn(0); 3216184914b5SBarry Smith } 3217184914b5SBarry Smith 32184a2ae208SSatish Balay #undef __FUNCT__ 32194a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3220c9005455SLois Curfman McInnes /*@ 3221c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3222c9005455SLois Curfman McInnes 32233f9fe445SBarry Smith Logically Collective on SNES 3224fee21e36SBarry Smith 3225c7afd0dbSLois Curfman McInnes Input Parameters: 3226c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 32278c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3228cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3229758f92a0SBarry Smith . na - size of a and its 323064731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3231758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3232c7afd0dbSLois Curfman McInnes 3233308dcc3eSBarry Smith Notes: 3234308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3235308dcc3eSBarry Smith default array of length 10000 is allocated. 3236308dcc3eSBarry Smith 3237c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3238c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3239c9005455SLois Curfman McInnes during the section of code that is being timed. 3240c9005455SLois Curfman McInnes 324136851e7fSLois Curfman McInnes Level: intermediate 324236851e7fSLois Curfman McInnes 3243c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3244758f92a0SBarry Smith 324508405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3246758f92a0SBarry Smith 3247c9005455SLois Curfman McInnes @*/ 32487087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3249c9005455SLois Curfman McInnes { 3250308dcc3eSBarry Smith PetscErrorCode ierr; 3251308dcc3eSBarry Smith 32523a40ed3dSBarry Smith PetscFunctionBegin; 32530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32544482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3255a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3256308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3257308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3258308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3259308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3260308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3261308dcc3eSBarry Smith } 3262c9005455SLois Curfman McInnes snes->conv_hist = a; 3263758f92a0SBarry Smith snes->conv_hist_its = its; 3264758f92a0SBarry Smith snes->conv_hist_max = na; 3265a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3266758f92a0SBarry Smith snes->conv_hist_reset = reset; 3267758f92a0SBarry Smith PetscFunctionReturn(0); 3268758f92a0SBarry Smith } 3269758f92a0SBarry Smith 3270308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3271c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3272c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3273308dcc3eSBarry Smith EXTERN_C_BEGIN 3274308dcc3eSBarry Smith #undef __FUNCT__ 3275308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3276308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3277308dcc3eSBarry Smith { 3278308dcc3eSBarry Smith mxArray *mat; 3279308dcc3eSBarry Smith PetscInt i; 3280308dcc3eSBarry Smith PetscReal *ar; 3281308dcc3eSBarry Smith 3282308dcc3eSBarry Smith PetscFunctionBegin; 3283308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3284308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3285308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3286308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3287308dcc3eSBarry Smith } 3288308dcc3eSBarry Smith PetscFunctionReturn(mat); 3289308dcc3eSBarry Smith } 3290308dcc3eSBarry Smith EXTERN_C_END 3291308dcc3eSBarry Smith #endif 3292308dcc3eSBarry Smith 3293308dcc3eSBarry Smith 32944a2ae208SSatish Balay #undef __FUNCT__ 32954a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 32960c4c9dddSBarry Smith /*@C 3297758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3298758f92a0SBarry Smith 32993f9fe445SBarry Smith Not Collective 3300758f92a0SBarry Smith 3301758f92a0SBarry Smith Input Parameter: 3302758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3303758f92a0SBarry Smith 3304758f92a0SBarry Smith Output Parameters: 3305758f92a0SBarry Smith . a - array to hold history 3306758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3307758f92a0SBarry Smith negative if not converged) for each solve. 3308758f92a0SBarry Smith - na - size of a and its 3309758f92a0SBarry Smith 3310758f92a0SBarry Smith Notes: 3311758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3312758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3313758f92a0SBarry Smith 3314758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3315758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3316758f92a0SBarry Smith during the section of code that is being timed. 3317758f92a0SBarry Smith 3318758f92a0SBarry Smith Level: intermediate 3319758f92a0SBarry Smith 3320758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3321758f92a0SBarry Smith 3322758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3323758f92a0SBarry Smith 3324758f92a0SBarry Smith @*/ 33257087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3326758f92a0SBarry Smith { 3327758f92a0SBarry Smith PetscFunctionBegin; 33280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3329758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3330758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3331758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 33323a40ed3dSBarry Smith PetscFunctionReturn(0); 3333c9005455SLois Curfman McInnes } 3334c9005455SLois Curfman McInnes 3335e74ef692SMatthew Knepley #undef __FUNCT__ 3336e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3337ac226902SBarry Smith /*@C 333876b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3339eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 33407e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 334176b2cf59SMatthew Knepley 33423f9fe445SBarry Smith Logically Collective on SNES 334376b2cf59SMatthew Knepley 334476b2cf59SMatthew Knepley Input Parameters: 334576b2cf59SMatthew Knepley . snes - The nonlinear solver context 334676b2cf59SMatthew Knepley . func - The function 334776b2cf59SMatthew Knepley 334876b2cf59SMatthew Knepley Calling sequence of func: 3349b5d30489SBarry Smith . func (SNES snes, PetscInt step); 335076b2cf59SMatthew Knepley 335176b2cf59SMatthew Knepley . step - The current step of the iteration 335276b2cf59SMatthew Knepley 3353fe97e370SBarry Smith Level: advanced 3354fe97e370SBarry Smith 3355fe97e370SBarry 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() 3356fe97e370SBarry Smith This is not used by most users. 335776b2cf59SMatthew Knepley 335876b2cf59SMatthew Knepley .keywords: SNES, update 3359b5d30489SBarry Smith 336085385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 336176b2cf59SMatthew Knepley @*/ 33627087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 336376b2cf59SMatthew Knepley { 336476b2cf59SMatthew Knepley PetscFunctionBegin; 33650700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3366e7788613SBarry Smith snes->ops->update = func; 336776b2cf59SMatthew Knepley PetscFunctionReturn(0); 336876b2cf59SMatthew Knepley } 336976b2cf59SMatthew Knepley 3370e74ef692SMatthew Knepley #undef __FUNCT__ 3371e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 337276b2cf59SMatthew Knepley /*@ 337376b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 337476b2cf59SMatthew Knepley 337576b2cf59SMatthew Knepley Not collective 337676b2cf59SMatthew Knepley 337776b2cf59SMatthew Knepley Input Parameters: 337876b2cf59SMatthew Knepley . snes - The nonlinear solver context 337976b2cf59SMatthew Knepley . step - The current step of the iteration 338076b2cf59SMatthew Knepley 3381205452f4SMatthew Knepley Level: intermediate 3382205452f4SMatthew Knepley 338376b2cf59SMatthew Knepley .keywords: SNES, update 3384a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 338576b2cf59SMatthew Knepley @*/ 33867087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 338776b2cf59SMatthew Knepley { 338876b2cf59SMatthew Knepley PetscFunctionBegin; 338976b2cf59SMatthew Knepley PetscFunctionReturn(0); 339076b2cf59SMatthew Knepley } 339176b2cf59SMatthew Knepley 33924a2ae208SSatish Balay #undef __FUNCT__ 33934a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 33949b94acceSBarry Smith /* 33959b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 33969b94acceSBarry Smith positive parameter delta. 33979b94acceSBarry Smith 33989b94acceSBarry Smith Input Parameters: 3399c7afd0dbSLois Curfman McInnes + snes - the SNES context 34009b94acceSBarry Smith . y - approximate solution of linear system 34019b94acceSBarry Smith . fnorm - 2-norm of current function 3402c7afd0dbSLois Curfman McInnes - delta - trust region size 34039b94acceSBarry Smith 34049b94acceSBarry Smith Output Parameters: 3405c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 34069b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 34079b94acceSBarry Smith region, and exceeds zero otherwise. 3408c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 34099b94acceSBarry Smith 34109b94acceSBarry Smith Note: 34114b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 34129b94acceSBarry Smith is set to be the maximum allowable step size. 34139b94acceSBarry Smith 34149b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 34159b94acceSBarry Smith */ 3416dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 34179b94acceSBarry Smith { 3418064f8208SBarry Smith PetscReal nrm; 3419ea709b57SSatish Balay PetscScalar cnorm; 3420dfbe8321SBarry Smith PetscErrorCode ierr; 34213a40ed3dSBarry Smith 34223a40ed3dSBarry Smith PetscFunctionBegin; 34230700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34240700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3425c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3426184914b5SBarry Smith 3427064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3428064f8208SBarry Smith if (nrm > *delta) { 3429064f8208SBarry Smith nrm = *delta/nrm; 3430064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3431064f8208SBarry Smith cnorm = nrm; 34322dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 34339b94acceSBarry Smith *ynorm = *delta; 34349b94acceSBarry Smith } else { 34359b94acceSBarry Smith *gpnorm = 0.0; 3436064f8208SBarry Smith *ynorm = nrm; 34379b94acceSBarry Smith } 34383a40ed3dSBarry Smith PetscFunctionReturn(0); 34399b94acceSBarry Smith } 34409b94acceSBarry Smith 34414a2ae208SSatish Balay #undef __FUNCT__ 34424a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 34436ce558aeSBarry Smith /*@C 3444f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3445f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 34469b94acceSBarry Smith 3447c7afd0dbSLois Curfman McInnes Collective on SNES 3448c7afd0dbSLois Curfman McInnes 3449b2002411SLois Curfman McInnes Input Parameters: 3450c7afd0dbSLois Curfman McInnes + snes - the SNES context 34513cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 345285385478SLisandro Dalcin - x - the solution vector. 34539b94acceSBarry Smith 3454b2002411SLois Curfman McInnes Notes: 34558ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 34568ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 34578ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 34588ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 34598ddd3da0SLois Curfman McInnes 346036851e7fSLois Curfman McInnes Level: beginner 346136851e7fSLois Curfman McInnes 34629b94acceSBarry Smith .keywords: SNES, nonlinear, solve 34639b94acceSBarry Smith 3464c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 34659b94acceSBarry Smith @*/ 34667087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 34679b94acceSBarry Smith { 3468dfbe8321SBarry Smith PetscErrorCode ierr; 3469ace3abfcSBarry Smith PetscBool flg; 3470eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3471eabae89aSBarry Smith PetscViewer viewer; 3472efd51863SBarry Smith PetscInt grid; 3473a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3474caa4e7f2SJed Brown DM dm; 3475052efed2SBarry Smith 34763a40ed3dSBarry Smith PetscFunctionBegin; 34770700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3478a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3479a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 34800700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 348185385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 348285385478SLisandro Dalcin 3483caa4e7f2SJed Brown if (!x) { 3484caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3485caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3486a69afd8bSBarry Smith x = xcreated; 3487a69afd8bSBarry Smith } 3488a69afd8bSBarry Smith 3489a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3490efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3491efd51863SBarry Smith 349285385478SLisandro Dalcin /* set solution vector */ 3493efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 34946bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 349585385478SLisandro Dalcin snes->vec_sol = x; 3496caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3497caa4e7f2SJed Brown 3498caa4e7f2SJed Brown /* set affine vector if provided */ 349985385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 35006bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 350185385478SLisandro Dalcin snes->vec_rhs = b; 350285385478SLisandro Dalcin 350370e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 35043f149594SLisandro Dalcin 35057eee914bSBarry Smith if (!grid) { 35067eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3507d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3508dd568438SSatish Balay } else if (snes->dm) { 3509dd568438SSatish Balay PetscBool ig; 3510dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3511dd568438SSatish Balay if (ig) { 35127eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 35137eee914bSBarry Smith } 3514d25893d9SBarry Smith } 3515dd568438SSatish Balay } 3516d25893d9SBarry Smith 3517abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 351850ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3519d5e45103SBarry Smith 35203f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 35214936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 352285385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 35234936397dSBarry Smith if (snes->domainerror){ 35244936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 35254936397dSBarry Smith snes->domainerror = PETSC_FALSE; 35264936397dSBarry Smith } 352717186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 35283f149594SLisandro Dalcin 352990d69ab7SBarry Smith flg = PETSC_FALSE; 3530acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3531da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 35325968eb51SBarry Smith if (snes->printreason) { 3533a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 35345968eb51SBarry Smith if (snes->reason > 0) { 3535c7e7b494SJed 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); 35365968eb51SBarry Smith } else { 3537c7e7b494SJed 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); 35385968eb51SBarry Smith } 3539a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 35405968eb51SBarry Smith } 35415968eb51SBarry Smith 3542e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3543efd51863SBarry Smith if (grid < snes->gridsequence) { 3544efd51863SBarry Smith DM fine; 3545efd51863SBarry Smith Vec xnew; 3546efd51863SBarry Smith Mat interp; 3547efd51863SBarry Smith 3548efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3549c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3550e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3551efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3552efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3553c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 3554efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3555efd51863SBarry Smith x = xnew; 3556efd51863SBarry Smith 3557efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3558efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3559efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3560a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3561efd51863SBarry Smith } 3562efd51863SBarry Smith } 35633f7e2da0SPeter Brune /* monitoring and viewing */ 35643f7e2da0SPeter Brune flg = PETSC_FALSE; 35653f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 35663f7e2da0SPeter Brune if (flg && !PetscPreLoadingOn) { 35673f7e2da0SPeter Brune ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 35683f7e2da0SPeter Brune ierr = SNESView(snes,viewer);CHKERRQ(ierr); 35693f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 35703f7e2da0SPeter Brune } 35713f7e2da0SPeter Brune 35723f7e2da0SPeter Brune flg = PETSC_FALSE; 35733f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 35743f7e2da0SPeter Brune if (flg) { 35753f7e2da0SPeter Brune PetscViewer viewer; 35763f7e2da0SPeter Brune ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 35773f7e2da0SPeter Brune ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 35783f7e2da0SPeter Brune ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 35793f7e2da0SPeter Brune ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 35803f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 35813f7e2da0SPeter Brune } 35823f7e2da0SPeter Brune 3583a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 35843a40ed3dSBarry Smith PetscFunctionReturn(0); 35859b94acceSBarry Smith } 35869b94acceSBarry Smith 35879b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 35889b94acceSBarry Smith 35894a2ae208SSatish Balay #undef __FUNCT__ 35904a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 359182bf6240SBarry Smith /*@C 35924b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 35939b94acceSBarry Smith 3594fee21e36SBarry Smith Collective on SNES 3595fee21e36SBarry Smith 3596c7afd0dbSLois Curfman McInnes Input Parameters: 3597c7afd0dbSLois Curfman McInnes + snes - the SNES context 3598454a90a3SBarry Smith - type - a known method 3599c7afd0dbSLois Curfman McInnes 3600c7afd0dbSLois Curfman McInnes Options Database Key: 3601454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3602c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3603ae12b187SLois Curfman McInnes 36049b94acceSBarry Smith Notes: 3605e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 36064b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3607c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 36084b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3609c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 36109b94acceSBarry Smith 3611ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3612ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3613ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3614ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3615ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3616ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3617ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3618ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3619ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3620b0a32e0cSBarry Smith appropriate method. 362136851e7fSLois Curfman McInnes 362236851e7fSLois Curfman McInnes Level: intermediate 3623a703fe33SLois Curfman McInnes 3624454a90a3SBarry Smith .keywords: SNES, set, type 3625435da068SBarry Smith 3626435da068SBarry Smith .seealso: SNESType, SNESCreate() 3627435da068SBarry Smith 36289b94acceSBarry Smith @*/ 36297087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 36309b94acceSBarry Smith { 3631dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3632ace3abfcSBarry Smith PetscBool match; 36333a40ed3dSBarry Smith 36343a40ed3dSBarry Smith PetscFunctionBegin; 36350700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36364482741eSBarry Smith PetscValidCharPointer(type,2); 363782bf6240SBarry Smith 3638251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 36390f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 364092ff6ae8SBarry Smith 36414b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3642e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 364375396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3644b5c23020SJed Brown if (snes->ops->destroy) { 3645b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3646b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3647b5c23020SJed Brown } 364875396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 364975396ef9SLisandro Dalcin snes->ops->setup = 0; 365075396ef9SLisandro Dalcin snes->ops->solve = 0; 365175396ef9SLisandro Dalcin snes->ops->view = 0; 365275396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 365375396ef9SLisandro Dalcin snes->ops->destroy = 0; 365475396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 365575396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3656454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 365703bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 36589fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 36599fb22e1aSBarry Smith if (PetscAMSPublishAll) { 36609fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 36619fb22e1aSBarry Smith } 36629fb22e1aSBarry Smith #endif 36633a40ed3dSBarry Smith PetscFunctionReturn(0); 36649b94acceSBarry Smith } 36659b94acceSBarry Smith 3666a847f771SSatish Balay 36679b94acceSBarry Smith /* --------------------------------------------------------------------- */ 36684a2ae208SSatish Balay #undef __FUNCT__ 36694a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 367052baeb72SSatish Balay /*@ 36719b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3672f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 36739b94acceSBarry Smith 3674fee21e36SBarry Smith Not Collective 3675fee21e36SBarry Smith 367636851e7fSLois Curfman McInnes Level: advanced 367736851e7fSLois Curfman McInnes 36789b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 36799b94acceSBarry Smith 36809b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 36819b94acceSBarry Smith @*/ 36827087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 36839b94acceSBarry Smith { 3684dfbe8321SBarry Smith PetscErrorCode ierr; 368582bf6240SBarry Smith 36863a40ed3dSBarry Smith PetscFunctionBegin; 36871441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 36884c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 36893a40ed3dSBarry Smith PetscFunctionReturn(0); 36909b94acceSBarry Smith } 36919b94acceSBarry Smith 36924a2ae208SSatish Balay #undef __FUNCT__ 36934a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 36949b94acceSBarry Smith /*@C 36959a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 36969b94acceSBarry Smith 3697c7afd0dbSLois Curfman McInnes Not Collective 3698c7afd0dbSLois Curfman McInnes 36999b94acceSBarry Smith Input Parameter: 37004b0e389bSBarry Smith . snes - nonlinear solver context 37019b94acceSBarry Smith 37029b94acceSBarry Smith Output Parameter: 37033a7fca6bSBarry Smith . type - SNES method (a character string) 37049b94acceSBarry Smith 370536851e7fSLois Curfman McInnes Level: intermediate 370636851e7fSLois Curfman McInnes 3707454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 37089b94acceSBarry Smith @*/ 37097087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 37109b94acceSBarry Smith { 37113a40ed3dSBarry Smith PetscFunctionBegin; 37120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37134482741eSBarry Smith PetscValidPointer(type,2); 37147adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 37153a40ed3dSBarry Smith PetscFunctionReturn(0); 37169b94acceSBarry Smith } 37179b94acceSBarry Smith 37184a2ae208SSatish Balay #undef __FUNCT__ 37194a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 372052baeb72SSatish Balay /*@ 37219b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3722c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 37239b94acceSBarry Smith 3724c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3725c7afd0dbSLois Curfman McInnes 37269b94acceSBarry Smith Input Parameter: 37279b94acceSBarry Smith . snes - the SNES context 37289b94acceSBarry Smith 37299b94acceSBarry Smith Output Parameter: 37309b94acceSBarry Smith . x - the solution 37319b94acceSBarry Smith 373270e92668SMatthew Knepley Level: intermediate 373336851e7fSLois Curfman McInnes 37349b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 37359b94acceSBarry Smith 373685385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 37379b94acceSBarry Smith @*/ 37387087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 37399b94acceSBarry Smith { 37403a40ed3dSBarry Smith PetscFunctionBegin; 37410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37424482741eSBarry Smith PetscValidPointer(x,2); 374385385478SLisandro Dalcin *x = snes->vec_sol; 374470e92668SMatthew Knepley PetscFunctionReturn(0); 374570e92668SMatthew Knepley } 374670e92668SMatthew Knepley 374770e92668SMatthew Knepley #undef __FUNCT__ 37484a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 374952baeb72SSatish Balay /*@ 37509b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 37519b94acceSBarry Smith stored. 37529b94acceSBarry Smith 3753c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3754c7afd0dbSLois Curfman McInnes 37559b94acceSBarry Smith Input Parameter: 37569b94acceSBarry Smith . snes - the SNES context 37579b94acceSBarry Smith 37589b94acceSBarry Smith Output Parameter: 37599b94acceSBarry Smith . x - the solution update 37609b94acceSBarry Smith 376136851e7fSLois Curfman McInnes Level: advanced 376236851e7fSLois Curfman McInnes 37639b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 37649b94acceSBarry Smith 376585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 37669b94acceSBarry Smith @*/ 37677087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 37689b94acceSBarry Smith { 37693a40ed3dSBarry Smith PetscFunctionBegin; 37700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37714482741eSBarry Smith PetscValidPointer(x,2); 377285385478SLisandro Dalcin *x = snes->vec_sol_update; 37733a40ed3dSBarry Smith PetscFunctionReturn(0); 37749b94acceSBarry Smith } 37759b94acceSBarry Smith 37764a2ae208SSatish Balay #undef __FUNCT__ 37774a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 37789b94acceSBarry Smith /*@C 37793638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 37809b94acceSBarry Smith 3781a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3782c7afd0dbSLois Curfman McInnes 37839b94acceSBarry Smith Input Parameter: 37849b94acceSBarry Smith . snes - the SNES context 37859b94acceSBarry Smith 37869b94acceSBarry Smith Output Parameter: 37877bf4e008SBarry Smith + r - the function (or PETSC_NULL) 378870e92668SMatthew Knepley . func - the function (or PETSC_NULL) 378970e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 37909b94acceSBarry Smith 379136851e7fSLois Curfman McInnes Level: advanced 379236851e7fSLois Curfman McInnes 3793a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 37949b94acceSBarry Smith 37954b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 37969b94acceSBarry Smith @*/ 37977087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 37989b94acceSBarry Smith { 3799a63bb30eSJed Brown PetscErrorCode ierr; 38006cab3a1bSJed Brown DM dm; 3801a63bb30eSJed Brown 38023a40ed3dSBarry Smith PetscFunctionBegin; 38030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3804a63bb30eSJed Brown if (r) { 3805a63bb30eSJed Brown if (!snes->vec_func) { 3806a63bb30eSJed Brown if (snes->vec_rhs) { 3807a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3808a63bb30eSJed Brown } else if (snes->vec_sol) { 3809a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3810a63bb30eSJed Brown } else if (snes->dm) { 3811a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3812a63bb30eSJed Brown } 3813a63bb30eSJed Brown } 3814a63bb30eSJed Brown *r = snes->vec_func; 3815a63bb30eSJed Brown } 38166cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 38176cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 38183a40ed3dSBarry Smith PetscFunctionReturn(0); 38199b94acceSBarry Smith } 38209b94acceSBarry Smith 3821c79ef259SPeter Brune /*@C 3822c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3823c79ef259SPeter Brune 3824c79ef259SPeter Brune Input Parameter: 3825c79ef259SPeter Brune . snes - the SNES context 3826c79ef259SPeter Brune 3827c79ef259SPeter Brune Output Parameter: 3828c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3829c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3830c79ef259SPeter Brune 3831c79ef259SPeter Brune Level: advanced 3832c79ef259SPeter Brune 3833c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3834c79ef259SPeter Brune 3835c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3836c79ef259SPeter Brune @*/ 3837c79ef259SPeter Brune 38384a2ae208SSatish Balay #undef __FUNCT__ 3839646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3840646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3841646217ecSPeter Brune { 38426cab3a1bSJed Brown PetscErrorCode ierr; 38436cab3a1bSJed Brown DM dm; 38446cab3a1bSJed Brown 3845646217ecSPeter Brune PetscFunctionBegin; 3846646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 38476cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 38486cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3849646217ecSPeter Brune PetscFunctionReturn(0); 3850646217ecSPeter Brune } 3851646217ecSPeter Brune 38524a2ae208SSatish Balay #undef __FUNCT__ 38534a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 38543c7409f5SSatish Balay /*@C 38553c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3856d850072dSLois Curfman McInnes SNES options in the database. 38573c7409f5SSatish Balay 38583f9fe445SBarry Smith Logically Collective on SNES 3859fee21e36SBarry Smith 3860c7afd0dbSLois Curfman McInnes Input Parameter: 3861c7afd0dbSLois Curfman McInnes + snes - the SNES context 3862c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3863c7afd0dbSLois Curfman McInnes 3864d850072dSLois Curfman McInnes Notes: 3865a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3866c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3867d850072dSLois Curfman McInnes 386836851e7fSLois Curfman McInnes Level: advanced 386936851e7fSLois Curfman McInnes 38703c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3871a86d99e1SLois Curfman McInnes 3872a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 38733c7409f5SSatish Balay @*/ 38747087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 38753c7409f5SSatish Balay { 3876dfbe8321SBarry Smith PetscErrorCode ierr; 38773c7409f5SSatish Balay 38783a40ed3dSBarry Smith PetscFunctionBegin; 38790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3880639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 38811cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 388294b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 38833a40ed3dSBarry Smith PetscFunctionReturn(0); 38843c7409f5SSatish Balay } 38853c7409f5SSatish Balay 38864a2ae208SSatish Balay #undef __FUNCT__ 38874a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 38883c7409f5SSatish Balay /*@C 3889f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3890d850072dSLois Curfman McInnes SNES options in the database. 38913c7409f5SSatish Balay 38923f9fe445SBarry Smith Logically Collective on SNES 3893fee21e36SBarry Smith 3894c7afd0dbSLois Curfman McInnes Input Parameters: 3895c7afd0dbSLois Curfman McInnes + snes - the SNES context 3896c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3897c7afd0dbSLois Curfman McInnes 3898d850072dSLois Curfman McInnes Notes: 3899a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3900c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3901d850072dSLois Curfman McInnes 390236851e7fSLois Curfman McInnes Level: advanced 390336851e7fSLois Curfman McInnes 39043c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3905a86d99e1SLois Curfman McInnes 3906a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 39073c7409f5SSatish Balay @*/ 39087087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 39093c7409f5SSatish Balay { 3910dfbe8321SBarry Smith PetscErrorCode ierr; 39113c7409f5SSatish Balay 39123a40ed3dSBarry Smith PetscFunctionBegin; 39130700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3914639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 39151cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 391694b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 39173a40ed3dSBarry Smith PetscFunctionReturn(0); 39183c7409f5SSatish Balay } 39193c7409f5SSatish Balay 39204a2ae208SSatish Balay #undef __FUNCT__ 39214a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 39229ab63eb5SSatish Balay /*@C 39233c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 39243c7409f5SSatish Balay SNES options in the database. 39253c7409f5SSatish Balay 3926c7afd0dbSLois Curfman McInnes Not Collective 3927c7afd0dbSLois Curfman McInnes 39283c7409f5SSatish Balay Input Parameter: 39293c7409f5SSatish Balay . snes - the SNES context 39303c7409f5SSatish Balay 39313c7409f5SSatish Balay Output Parameter: 39323c7409f5SSatish Balay . prefix - pointer to the prefix string used 39333c7409f5SSatish Balay 39344ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 39359ab63eb5SSatish Balay sufficient length to hold the prefix. 39369ab63eb5SSatish Balay 393736851e7fSLois Curfman McInnes Level: advanced 393836851e7fSLois Curfman McInnes 39393c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3940a86d99e1SLois Curfman McInnes 3941a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 39423c7409f5SSatish Balay @*/ 39437087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 39443c7409f5SSatish Balay { 3945dfbe8321SBarry Smith PetscErrorCode ierr; 39463c7409f5SSatish Balay 39473a40ed3dSBarry Smith PetscFunctionBegin; 39480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3949639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 39503a40ed3dSBarry Smith PetscFunctionReturn(0); 39513c7409f5SSatish Balay } 39523c7409f5SSatish Balay 3953b2002411SLois Curfman McInnes 39544a2ae208SSatish Balay #undef __FUNCT__ 39554a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 39563cea93caSBarry Smith /*@C 39573cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 39583cea93caSBarry Smith 39597f6c08e0SMatthew Knepley Level: advanced 39603cea93caSBarry Smith @*/ 39617087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3962b2002411SLois Curfman McInnes { 3963e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3964dfbe8321SBarry Smith PetscErrorCode ierr; 3965b2002411SLois Curfman McInnes 3966b2002411SLois Curfman McInnes PetscFunctionBegin; 3967b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3968c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3969b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3970b2002411SLois Curfman McInnes } 3971da9b6338SBarry Smith 3972da9b6338SBarry Smith #undef __FUNCT__ 3973da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 39747087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 3975da9b6338SBarry Smith { 3976dfbe8321SBarry Smith PetscErrorCode ierr; 397777431f27SBarry Smith PetscInt N,i,j; 3978da9b6338SBarry Smith Vec u,uh,fh; 3979da9b6338SBarry Smith PetscScalar value; 3980da9b6338SBarry Smith PetscReal norm; 3981da9b6338SBarry Smith 3982da9b6338SBarry Smith PetscFunctionBegin; 3983da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 3984da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 3985da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 3986da9b6338SBarry Smith 3987da9b6338SBarry Smith /* currently only works for sequential */ 3988da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 3989da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 3990da9b6338SBarry Smith for (i=0; i<N; i++) { 3991da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 399277431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 3993da9b6338SBarry Smith for (j=-10; j<11; j++) { 3994ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 3995da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 39963ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 3997da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 399877431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 3999da9b6338SBarry Smith value = -value; 4000da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4001da9b6338SBarry Smith } 4002da9b6338SBarry Smith } 40036bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 40046bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 4005da9b6338SBarry Smith PetscFunctionReturn(0); 4006da9b6338SBarry Smith } 400771f87433Sdalcinl 400871f87433Sdalcinl #undef __FUNCT__ 4009fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 401071f87433Sdalcinl /*@ 4011fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 401271f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 401371f87433Sdalcinl Newton method. 401471f87433Sdalcinl 40153f9fe445SBarry Smith Logically Collective on SNES 401671f87433Sdalcinl 401771f87433Sdalcinl Input Parameters: 401871f87433Sdalcinl + snes - SNES context 401971f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 402071f87433Sdalcinl 402164ba62caSBarry Smith Options Database: 402264ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 402364ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 402464ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 402564ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 402664ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 402764ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 402864ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 402964ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 403064ba62caSBarry Smith 403171f87433Sdalcinl Notes: 403271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 403371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 403471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 403571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 403671f87433Sdalcinl solver. 403771f87433Sdalcinl 403871f87433Sdalcinl Level: advanced 403971f87433Sdalcinl 404071f87433Sdalcinl Reference: 404171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 404271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 404371f87433Sdalcinl 404471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 404571f87433Sdalcinl 4046fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 404771f87433Sdalcinl @*/ 40487087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 404971f87433Sdalcinl { 405071f87433Sdalcinl PetscFunctionBegin; 40510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4052acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 405371f87433Sdalcinl snes->ksp_ewconv = flag; 405471f87433Sdalcinl PetscFunctionReturn(0); 405571f87433Sdalcinl } 405671f87433Sdalcinl 405771f87433Sdalcinl #undef __FUNCT__ 4058fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 405971f87433Sdalcinl /*@ 4060fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 406171f87433Sdalcinl for computing relative tolerance for linear solvers within an 406271f87433Sdalcinl inexact Newton method. 406371f87433Sdalcinl 406471f87433Sdalcinl Not Collective 406571f87433Sdalcinl 406671f87433Sdalcinl Input Parameter: 406771f87433Sdalcinl . snes - SNES context 406871f87433Sdalcinl 406971f87433Sdalcinl Output Parameter: 407071f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 407171f87433Sdalcinl 407271f87433Sdalcinl Notes: 407371f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 407471f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 407571f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 407671f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 407771f87433Sdalcinl solver. 407871f87433Sdalcinl 407971f87433Sdalcinl Level: advanced 408071f87433Sdalcinl 408171f87433Sdalcinl Reference: 408271f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 408371f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 408471f87433Sdalcinl 408571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 408671f87433Sdalcinl 4087fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 408871f87433Sdalcinl @*/ 40897087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 409071f87433Sdalcinl { 409171f87433Sdalcinl PetscFunctionBegin; 40920700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 409371f87433Sdalcinl PetscValidPointer(flag,2); 409471f87433Sdalcinl *flag = snes->ksp_ewconv; 409571f87433Sdalcinl PetscFunctionReturn(0); 409671f87433Sdalcinl } 409771f87433Sdalcinl 409871f87433Sdalcinl #undef __FUNCT__ 4099fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 410071f87433Sdalcinl /*@ 4101fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 410271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 410371f87433Sdalcinl Newton method. 410471f87433Sdalcinl 41053f9fe445SBarry Smith Logically Collective on SNES 410671f87433Sdalcinl 410771f87433Sdalcinl Input Parameters: 410871f87433Sdalcinl + snes - SNES context 410971f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 411071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 411171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 411271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 411371f87433Sdalcinl (0 <= gamma2 <= 1) 411471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 411571f87433Sdalcinl . alpha2 - power for safeguard 411671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 411771f87433Sdalcinl 411871f87433Sdalcinl Note: 411971f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 412071f87433Sdalcinl 412171f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 412271f87433Sdalcinl 412371f87433Sdalcinl Level: advanced 412471f87433Sdalcinl 412571f87433Sdalcinl Reference: 412671f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 412771f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 412871f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 412971f87433Sdalcinl 413071f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 413171f87433Sdalcinl 4132fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 413371f87433Sdalcinl @*/ 41347087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 413571f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 413671f87433Sdalcinl { 4137fa9f3622SBarry Smith SNESKSPEW *kctx; 413871f87433Sdalcinl PetscFunctionBegin; 41390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4140fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4141e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4142c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4143c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4144c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4145c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4146c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4147c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4148c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 414971f87433Sdalcinl 415071f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 415171f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 415271f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 415371f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 415471f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 415571f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 415671f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 415771f87433Sdalcinl 415871f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4159e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 416071f87433Sdalcinl } 416171f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4162e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 416371f87433Sdalcinl } 416471f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4165e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 416671f87433Sdalcinl } 416771f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4168e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 416971f87433Sdalcinl } 417071f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4171e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 417271f87433Sdalcinl } 417371f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4174e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 417571f87433Sdalcinl } 417671f87433Sdalcinl PetscFunctionReturn(0); 417771f87433Sdalcinl } 417871f87433Sdalcinl 417971f87433Sdalcinl #undef __FUNCT__ 4180fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 418171f87433Sdalcinl /*@ 4182fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 418371f87433Sdalcinl convergence criteria for the linear solvers within an inexact 418471f87433Sdalcinl Newton method. 418571f87433Sdalcinl 418671f87433Sdalcinl Not Collective 418771f87433Sdalcinl 418871f87433Sdalcinl Input Parameters: 418971f87433Sdalcinl snes - SNES context 419071f87433Sdalcinl 419171f87433Sdalcinl Output Parameters: 419271f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 419371f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 419471f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 419571f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 419671f87433Sdalcinl (0 <= gamma2 <= 1) 419771f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 419871f87433Sdalcinl . alpha2 - power for safeguard 419971f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 420071f87433Sdalcinl 420171f87433Sdalcinl Level: advanced 420271f87433Sdalcinl 420371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 420471f87433Sdalcinl 4205fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 420671f87433Sdalcinl @*/ 42077087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 420871f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 420971f87433Sdalcinl { 4210fa9f3622SBarry Smith SNESKSPEW *kctx; 421171f87433Sdalcinl PetscFunctionBegin; 42120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4213fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4214e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 421571f87433Sdalcinl if(version) *version = kctx->version; 421671f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 421771f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 421871f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 421971f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 422071f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 422171f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 422271f87433Sdalcinl PetscFunctionReturn(0); 422371f87433Sdalcinl } 422471f87433Sdalcinl 422571f87433Sdalcinl #undef __FUNCT__ 4226fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4227fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 422871f87433Sdalcinl { 422971f87433Sdalcinl PetscErrorCode ierr; 4230fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 423171f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 423271f87433Sdalcinl 423371f87433Sdalcinl PetscFunctionBegin; 4234e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 423571f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 423671f87433Sdalcinl rtol = kctx->rtol_0; 423771f87433Sdalcinl } else { 423871f87433Sdalcinl if (kctx->version == 1) { 423971f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 424071f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 424171f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 424271f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 424371f87433Sdalcinl } else if (kctx->version == 2) { 424471f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 424571f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 424671f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 424771f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 424871f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 424971f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 425071f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 425171f87433Sdalcinl stol = PetscMax(rtol,stol); 425271f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 425371f87433Sdalcinl /* safeguard: avoid oversolving */ 425471f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 425571f87433Sdalcinl stol = PetscMax(rtol,stol); 425671f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4257e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 425871f87433Sdalcinl } 425971f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 426071f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 426171f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 426271f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 426371f87433Sdalcinl PetscFunctionReturn(0); 426471f87433Sdalcinl } 426571f87433Sdalcinl 426671f87433Sdalcinl #undef __FUNCT__ 4267fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4268fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 426971f87433Sdalcinl { 427071f87433Sdalcinl PetscErrorCode ierr; 4271fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 427271f87433Sdalcinl PCSide pcside; 427371f87433Sdalcinl Vec lres; 427471f87433Sdalcinl 427571f87433Sdalcinl PetscFunctionBegin; 4276e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 427771f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 427871f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 427971f87433Sdalcinl if (kctx->version == 1) { 4280b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 428171f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 428271f87433Sdalcinl /* KSP residual is true linear residual */ 428371f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 428471f87433Sdalcinl } else { 428571f87433Sdalcinl /* KSP residual is preconditioned residual */ 428671f87433Sdalcinl /* compute true linear residual norm */ 428771f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 428871f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 428971f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 429071f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 42916bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 429271f87433Sdalcinl } 429371f87433Sdalcinl } 429471f87433Sdalcinl PetscFunctionReturn(0); 429571f87433Sdalcinl } 429671f87433Sdalcinl 429771f87433Sdalcinl #undef __FUNCT__ 429871f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 429971f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 430071f87433Sdalcinl { 430171f87433Sdalcinl PetscErrorCode ierr; 430271f87433Sdalcinl 430371f87433Sdalcinl PetscFunctionBegin; 4304fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 430571f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4306fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 430771f87433Sdalcinl PetscFunctionReturn(0); 430871f87433Sdalcinl } 43096c699258SBarry Smith 43106c699258SBarry Smith #undef __FUNCT__ 43116c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 43126c699258SBarry Smith /*@ 43136c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 43146c699258SBarry Smith 43153f9fe445SBarry Smith Logically Collective on SNES 43166c699258SBarry Smith 43176c699258SBarry Smith Input Parameters: 43186c699258SBarry Smith + snes - the preconditioner context 43196c699258SBarry Smith - dm - the dm 43206c699258SBarry Smith 43216c699258SBarry Smith Level: intermediate 43226c699258SBarry Smith 43236c699258SBarry Smith 43246c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 43256c699258SBarry Smith @*/ 43267087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 43276c699258SBarry Smith { 43286c699258SBarry Smith PetscErrorCode ierr; 4329345fed2cSBarry Smith KSP ksp; 43306cab3a1bSJed Brown SNESDM sdm; 43316c699258SBarry Smith 43326c699258SBarry Smith PetscFunctionBegin; 43330700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4334d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 43356cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 43366cab3a1bSJed Brown PetscContainer oldcontainer,container; 43376cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 43386cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 43396cab3a1bSJed Brown if (oldcontainer && !container) { 43406cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 43416cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 43426cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 43436cab3a1bSJed Brown sdm->originaldm = dm; 43446cab3a1bSJed Brown } 43456cab3a1bSJed Brown } 43466bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 43476cab3a1bSJed Brown } 43486c699258SBarry Smith snes->dm = dm; 4349345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4350345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4351f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 43522c155ee1SBarry Smith if (snes->pc) { 43532c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 43542c155ee1SBarry Smith } 43556c699258SBarry Smith PetscFunctionReturn(0); 43566c699258SBarry Smith } 43576c699258SBarry Smith 43586c699258SBarry Smith #undef __FUNCT__ 43596c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 43606c699258SBarry Smith /*@ 43616c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 43626c699258SBarry Smith 43633f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 43646c699258SBarry Smith 43656c699258SBarry Smith Input Parameter: 43666c699258SBarry Smith . snes - the preconditioner context 43676c699258SBarry Smith 43686c699258SBarry Smith Output Parameter: 43696c699258SBarry Smith . dm - the dm 43706c699258SBarry Smith 43716c699258SBarry Smith Level: intermediate 43726c699258SBarry Smith 43736c699258SBarry Smith 43746c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 43756c699258SBarry Smith @*/ 43767087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 43776c699258SBarry Smith { 43786cab3a1bSJed Brown PetscErrorCode ierr; 43796cab3a1bSJed Brown 43806c699258SBarry Smith PetscFunctionBegin; 43810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 43826cab3a1bSJed Brown if (!snes->dm) { 43836cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 43846cab3a1bSJed Brown } 43856c699258SBarry Smith *dm = snes->dm; 43866c699258SBarry Smith PetscFunctionReturn(0); 43876c699258SBarry Smith } 43880807856dSBarry Smith 438931823bd8SMatthew G Knepley #undef __FUNCT__ 439031823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 439131823bd8SMatthew G Knepley /*@ 4392fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 439331823bd8SMatthew G Knepley 439431823bd8SMatthew G Knepley Collective on SNES 439531823bd8SMatthew G Knepley 439631823bd8SMatthew G Knepley Input Parameters: 439731823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 439831823bd8SMatthew G Knepley - pc - the preconditioner object 439931823bd8SMatthew G Knepley 440031823bd8SMatthew G Knepley Notes: 440131823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 440231823bd8SMatthew G Knepley to configure it using the API). 440331823bd8SMatthew G Knepley 440431823bd8SMatthew G Knepley Level: developer 440531823bd8SMatthew G Knepley 440631823bd8SMatthew G Knepley .keywords: SNES, set, precondition 440731823bd8SMatthew G Knepley .seealso: SNESGetPC() 440831823bd8SMatthew G Knepley @*/ 440931823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 441031823bd8SMatthew G Knepley { 441131823bd8SMatthew G Knepley PetscErrorCode ierr; 441231823bd8SMatthew G Knepley 441331823bd8SMatthew G Knepley PetscFunctionBegin; 441431823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 441531823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 441631823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 441731823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4418bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 441931823bd8SMatthew G Knepley snes->pc = pc; 442031823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 442131823bd8SMatthew G Knepley PetscFunctionReturn(0); 442231823bd8SMatthew G Knepley } 442331823bd8SMatthew G Knepley 442431823bd8SMatthew G Knepley #undef __FUNCT__ 442531823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 442631823bd8SMatthew G Knepley /*@ 4427fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 442831823bd8SMatthew G Knepley 442931823bd8SMatthew G Knepley Not Collective 443031823bd8SMatthew G Knepley 443131823bd8SMatthew G Knepley Input Parameter: 443231823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 443331823bd8SMatthew G Knepley 443431823bd8SMatthew G Knepley Output Parameter: 443531823bd8SMatthew G Knepley . pc - preconditioner context 443631823bd8SMatthew G Knepley 443731823bd8SMatthew G Knepley Level: developer 443831823bd8SMatthew G Knepley 443931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 444031823bd8SMatthew G Knepley .seealso: SNESSetPC() 444131823bd8SMatthew G Knepley @*/ 444231823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 444331823bd8SMatthew G Knepley { 444431823bd8SMatthew G Knepley PetscErrorCode ierr; 4445a64e098fSPeter Brune const char *optionsprefix; 444631823bd8SMatthew G Knepley 444731823bd8SMatthew G Knepley PetscFunctionBegin; 444831823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 444931823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 445031823bd8SMatthew G Knepley if (!snes->pc) { 445131823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr); 44524a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr); 445331823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr); 4454a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 4455a64e098fSPeter Brune ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr); 4456a64e098fSPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr); 445731823bd8SMatthew G Knepley } 445831823bd8SMatthew G Knepley *pc = snes->pc; 445931823bd8SMatthew G Knepley PetscFunctionReturn(0); 446031823bd8SMatthew G Knepley } 446131823bd8SMatthew G Knepley 44629e764e56SPeter Brune #undef __FUNCT__ 4463f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 44649e764e56SPeter Brune /*@ 44658141a3b9SPeter Brune SNESSetSNESLineSearch - Sets the linesearch on the SNES instance. 44669e764e56SPeter Brune 44679e764e56SPeter Brune Collective on SNES 44689e764e56SPeter Brune 44699e764e56SPeter Brune Input Parameters: 44709e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 44719e764e56SPeter Brune - linesearch - the linesearch object 44729e764e56SPeter Brune 44739e764e56SPeter Brune Notes: 4474f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 44759e764e56SPeter Brune to configure it using the API). 44769e764e56SPeter Brune 44779e764e56SPeter Brune Level: developer 44789e764e56SPeter Brune 44799e764e56SPeter Brune .keywords: SNES, set, linesearch 4480f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 44819e764e56SPeter Brune @*/ 4482f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 44839e764e56SPeter Brune { 44849e764e56SPeter Brune PetscErrorCode ierr; 44859e764e56SPeter Brune 44869e764e56SPeter Brune PetscFunctionBegin; 44879e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4488f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 44899e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 44909e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4491f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 44929e764e56SPeter Brune snes->linesearch = linesearch; 44939e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 44949e764e56SPeter Brune PetscFunctionReturn(0); 44959e764e56SPeter Brune } 44969e764e56SPeter Brune 44979e764e56SPeter Brune #undef __FUNCT__ 4498f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4499ea5d4fccSPeter Brune /*@C 45008141a3b9SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 45018141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 45029e764e56SPeter Brune 45039e764e56SPeter Brune Not Collective 45049e764e56SPeter Brune 45059e764e56SPeter Brune Input Parameter: 45069e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 45079e764e56SPeter Brune 45089e764e56SPeter Brune Output Parameter: 45099e764e56SPeter Brune . linesearch - linesearch context 45109e764e56SPeter Brune 45119e764e56SPeter Brune Level: developer 45129e764e56SPeter Brune 45139e764e56SPeter Brune .keywords: SNES, get, linesearch 4514f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 45159e764e56SPeter Brune @*/ 4516f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 45179e764e56SPeter Brune { 45189e764e56SPeter Brune PetscErrorCode ierr; 45199e764e56SPeter Brune const char *optionsprefix; 45209e764e56SPeter Brune 45219e764e56SPeter Brune PetscFunctionBegin; 45229e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 45239e764e56SPeter Brune PetscValidPointer(linesearch, 2); 45249e764e56SPeter Brune if (!snes->linesearch) { 45259e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4526f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4527f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4528b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 45299e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 45309e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 45319e764e56SPeter Brune } 45329e764e56SPeter Brune *linesearch = snes->linesearch; 45339e764e56SPeter Brune PetscFunctionReturn(0); 45349e764e56SPeter Brune } 45359e764e56SPeter Brune 453669b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4537c6db04a5SJed Brown #include <mex.h> 453869b4f73cSBarry Smith 45398f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 45408f6e6473SBarry Smith 45410807856dSBarry Smith #undef __FUNCT__ 45420807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 45430807856dSBarry Smith /* 45440807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 45450807856dSBarry Smith SNESSetFunctionMatlab(). 45460807856dSBarry Smith 45470807856dSBarry Smith Collective on SNES 45480807856dSBarry Smith 45490807856dSBarry Smith Input Parameters: 45500807856dSBarry Smith + snes - the SNES context 45510807856dSBarry Smith - x - input vector 45520807856dSBarry Smith 45530807856dSBarry Smith Output Parameter: 45540807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 45550807856dSBarry Smith 45560807856dSBarry Smith Notes: 45570807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 45580807856dSBarry Smith implementations, so most users would not generally call this routine 45590807856dSBarry Smith themselves. 45600807856dSBarry Smith 45610807856dSBarry Smith Level: developer 45620807856dSBarry Smith 45630807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 45640807856dSBarry Smith 45650807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 456661b2408cSBarry Smith */ 45677087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 45680807856dSBarry Smith { 4569e650e774SBarry Smith PetscErrorCode ierr; 45708f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 45718f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 45728f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 457391621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4574e650e774SBarry Smith 45750807856dSBarry Smith PetscFunctionBegin; 45760807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 45770807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 45780807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 45790807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 45800807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 45810807856dSBarry Smith 45820807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4583e650e774SBarry Smith 458491621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4585e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4586e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 458791621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 458891621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 458991621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 45908f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 45918f6e6473SBarry Smith prhs[4] = sctx->ctx; 4592b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4593e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4594e650e774SBarry Smith mxDestroyArray(prhs[0]); 4595e650e774SBarry Smith mxDestroyArray(prhs[1]); 4596e650e774SBarry Smith mxDestroyArray(prhs[2]); 45978f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4598e650e774SBarry Smith mxDestroyArray(plhs[0]); 45990807856dSBarry Smith PetscFunctionReturn(0); 46000807856dSBarry Smith } 46010807856dSBarry Smith 46020807856dSBarry Smith 46030807856dSBarry Smith #undef __FUNCT__ 46040807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 460561b2408cSBarry Smith /* 46060807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 46070807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4608e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 46090807856dSBarry Smith 46100807856dSBarry Smith Logically Collective on SNES 46110807856dSBarry Smith 46120807856dSBarry Smith Input Parameters: 46130807856dSBarry Smith + snes - the SNES context 46140807856dSBarry Smith . r - vector to store function value 46150807856dSBarry Smith - func - function evaluation routine 46160807856dSBarry Smith 46170807856dSBarry Smith Calling sequence of func: 461861b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 46190807856dSBarry Smith 46200807856dSBarry Smith 46210807856dSBarry Smith Notes: 46220807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 46230807856dSBarry Smith $ f'(x) x = -f(x), 46240807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 46250807856dSBarry Smith 46260807856dSBarry Smith Level: beginner 46270807856dSBarry Smith 46280807856dSBarry Smith .keywords: SNES, nonlinear, set, function 46290807856dSBarry Smith 46300807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 463161b2408cSBarry Smith */ 46327087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 46330807856dSBarry Smith { 46340807856dSBarry Smith PetscErrorCode ierr; 46358f6e6473SBarry Smith SNESMatlabContext *sctx; 46360807856dSBarry Smith 46370807856dSBarry Smith PetscFunctionBegin; 46388f6e6473SBarry Smith /* currently sctx is memory bleed */ 46398f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 46408f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 46418f6e6473SBarry Smith /* 46428f6e6473SBarry Smith This should work, but it doesn't 46438f6e6473SBarry Smith sctx->ctx = ctx; 46448f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 46458f6e6473SBarry Smith */ 46468f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 46478f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 46480807856dSBarry Smith PetscFunctionReturn(0); 46490807856dSBarry Smith } 465069b4f73cSBarry Smith 465161b2408cSBarry Smith #undef __FUNCT__ 465261b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 465361b2408cSBarry Smith /* 465461b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 465561b2408cSBarry Smith SNESSetJacobianMatlab(). 465661b2408cSBarry Smith 465761b2408cSBarry Smith Collective on SNES 465861b2408cSBarry Smith 465961b2408cSBarry Smith Input Parameters: 466061b2408cSBarry Smith + snes - the SNES context 466161b2408cSBarry Smith . x - input vector 466261b2408cSBarry Smith . A, B - the matrices 466361b2408cSBarry Smith - ctx - user context 466461b2408cSBarry Smith 466561b2408cSBarry Smith Output Parameter: 466661b2408cSBarry Smith . flag - structure of the matrix 466761b2408cSBarry Smith 466861b2408cSBarry Smith Level: developer 466961b2408cSBarry Smith 467061b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 467161b2408cSBarry Smith 467261b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 467361b2408cSBarry Smith @*/ 46747087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 467561b2408cSBarry Smith { 467661b2408cSBarry Smith PetscErrorCode ierr; 467761b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 467861b2408cSBarry Smith int nlhs = 2,nrhs = 6; 467961b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 468061b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 468161b2408cSBarry Smith 468261b2408cSBarry Smith PetscFunctionBegin; 468361b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 468461b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 468561b2408cSBarry Smith 468661b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 468761b2408cSBarry Smith 468861b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 468961b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 469061b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 469161b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 469261b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 469361b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 469461b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 469561b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 469661b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 469761b2408cSBarry Smith prhs[5] = sctx->ctx; 4698b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 469961b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 470061b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 470161b2408cSBarry Smith mxDestroyArray(prhs[0]); 470261b2408cSBarry Smith mxDestroyArray(prhs[1]); 470361b2408cSBarry Smith mxDestroyArray(prhs[2]); 470461b2408cSBarry Smith mxDestroyArray(prhs[3]); 470561b2408cSBarry Smith mxDestroyArray(prhs[4]); 470661b2408cSBarry Smith mxDestroyArray(plhs[0]); 470761b2408cSBarry Smith mxDestroyArray(plhs[1]); 470861b2408cSBarry Smith PetscFunctionReturn(0); 470961b2408cSBarry Smith } 471061b2408cSBarry Smith 471161b2408cSBarry Smith 471261b2408cSBarry Smith #undef __FUNCT__ 471361b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 471461b2408cSBarry Smith /* 471561b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 471661b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4717e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 471861b2408cSBarry Smith 471961b2408cSBarry Smith Logically Collective on SNES 472061b2408cSBarry Smith 472161b2408cSBarry Smith Input Parameters: 472261b2408cSBarry Smith + snes - the SNES context 472361b2408cSBarry Smith . A,B - Jacobian matrices 472461b2408cSBarry Smith . func - function evaluation routine 472561b2408cSBarry Smith - ctx - user context 472661b2408cSBarry Smith 472761b2408cSBarry Smith Calling sequence of func: 472861b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 472961b2408cSBarry Smith 473061b2408cSBarry Smith 473161b2408cSBarry Smith Level: developer 473261b2408cSBarry Smith 473361b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 473461b2408cSBarry Smith 473561b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 473661b2408cSBarry Smith */ 47377087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 473861b2408cSBarry Smith { 473961b2408cSBarry Smith PetscErrorCode ierr; 474061b2408cSBarry Smith SNESMatlabContext *sctx; 474161b2408cSBarry Smith 474261b2408cSBarry Smith PetscFunctionBegin; 474361b2408cSBarry Smith /* currently sctx is memory bleed */ 474461b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 474561b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 474661b2408cSBarry Smith /* 474761b2408cSBarry Smith This should work, but it doesn't 474861b2408cSBarry Smith sctx->ctx = ctx; 474961b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 475061b2408cSBarry Smith */ 475161b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 475261b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 475361b2408cSBarry Smith PetscFunctionReturn(0); 475461b2408cSBarry Smith } 475569b4f73cSBarry Smith 4756f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4757f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4758f9eb7ae2SShri Abhyankar /* 4759f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4760f9eb7ae2SShri Abhyankar 4761f9eb7ae2SShri Abhyankar Collective on SNES 4762f9eb7ae2SShri Abhyankar 4763f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4764f9eb7ae2SShri Abhyankar @*/ 47657087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4766f9eb7ae2SShri Abhyankar { 4767f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 476848f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4769f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4770f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4771f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4772f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4773f9eb7ae2SShri Abhyankar 4774f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4775f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4776f9eb7ae2SShri Abhyankar 4777f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4778f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4779f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4780f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4781f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4782f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4783f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4784f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4785f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4786f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4787f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4788f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4789f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4790f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4791f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4792f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4793f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4794f9eb7ae2SShri Abhyankar } 4795f9eb7ae2SShri Abhyankar 4796f9eb7ae2SShri Abhyankar 4797f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4798f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4799f9eb7ae2SShri Abhyankar /* 4800e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4801f9eb7ae2SShri Abhyankar 4802f9eb7ae2SShri Abhyankar Level: developer 4803f9eb7ae2SShri Abhyankar 4804f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4805f9eb7ae2SShri Abhyankar 4806f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4807f9eb7ae2SShri Abhyankar */ 48087087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4809f9eb7ae2SShri Abhyankar { 4810f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4811f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4812f9eb7ae2SShri Abhyankar 4813f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4814f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4815f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4816f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4817f9eb7ae2SShri Abhyankar /* 4818f9eb7ae2SShri Abhyankar This should work, but it doesn't 4819f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4820f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4821f9eb7ae2SShri Abhyankar */ 4822f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4823f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4824f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4825f9eb7ae2SShri Abhyankar } 4826f9eb7ae2SShri Abhyankar 482769b4f73cSBarry Smith #endif 4828