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; 33516ebb321SJed Brown if (PetscLogPrintInfo) { 33616ebb321SJed Brown PetscInt finelevel,coarselevel,fineclevel,coarseclevel; 33716ebb321SJed Brown ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr); 33816ebb321SJed Brown ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr); 33916ebb321SJed Brown ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr); 34016ebb321SJed Brown ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr); 34116ebb321SJed Brown ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr); 34216ebb321SJed Brown } 343dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 344dfe15315SJed Brown else { 345dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr); 346dfe15315SJed Brown Xfine = Xfine_named; 347dfe15315SJed Brown } 348dfe15315SJed Brown ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 349dfe15315SJed Brown ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr); 350dfe15315SJed Brown ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr); 351dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr); 352dfe15315SJed Brown if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);} 353dfe15315SJed Brown PetscFunctionReturn(0); 354dfe15315SJed Brown } 355dfe15315SJed Brown 356dfe15315SJed Brown #undef __FUNCT__ 35716ebb321SJed Brown #define __FUNCT__ "DMCoarsenHook_SNESVecSol" 35816ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx) 35916ebb321SJed Brown { 36016ebb321SJed Brown PetscErrorCode ierr; 36116ebb321SJed Brown 36216ebb321SJed Brown PetscFunctionBegin; 36316ebb321SJed Brown ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr); 36416ebb321SJed Brown PetscFunctionReturn(0); 36516ebb321SJed Brown } 36616ebb321SJed Brown 36716ebb321SJed Brown #undef __FUNCT__ 368caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES" 369a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 370a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 371caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx) 372caa4e7f2SJed Brown { 373caa4e7f2SJed Brown SNES snes = (SNES)ctx; 374caa4e7f2SJed Brown PetscErrorCode ierr; 375caa4e7f2SJed Brown Mat Asave = A,Bsave = B; 376dfe15315SJed Brown Vec X,Xnamed = PETSC_NULL; 377dfe15315SJed Brown DM dmsave; 378*4e269d77SPeter Brune void *ctxsave; 379*4e269d77SPeter Brune PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 380caa4e7f2SJed Brown 381caa4e7f2SJed Brown PetscFunctionBegin; 382dfe15315SJed Brown dmsave = snes->dm; 383dfe15315SJed Brown ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr); 384dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 385dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 386dfe15315SJed Brown ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 387dfe15315SJed Brown X = Xnamed; 388*4e269d77SPeter Brune ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,&jac,&ctxsave);CHKERRQ(ierr); 389*4e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 390*4e269d77SPeter Brune if (jac == SNESDefaultComputeJacobianColor) { 391*4e269d77SPeter Brune ierr = SNESSetJacobian(snes,PETSC_NULL,PETSC_NULL,SNESDefaultComputeJacobianColor,0);CHKERRQ(ierr); 392dfe15315SJed Brown } 393*4e269d77SPeter Brune } 394*4e269d77SPeter Brune /* put the previous context back */ 395*4e269d77SPeter Brune 396dfe15315SJed Brown ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr); 397*4e269d77SPeter Brune if (snes->dm != dmsave && jac == SNESDefaultComputeJacobianColor) { 398*4e269d77SPeter Brune ierr = SNESSetJacobian(snes,PETSC_NULL,PETSC_NULL,jac,ctxsave);CHKERRQ(ierr); 399*4e269d77SPeter Brune } 400*4e269d77SPeter Brune 401caa4e7f2SJed Brown if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time"); 402dfe15315SJed Brown if (Xnamed) { 403dfe15315SJed Brown ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr); 404dfe15315SJed Brown } 405dfe15315SJed Brown snes->dm = dmsave; 406caa4e7f2SJed Brown PetscFunctionReturn(0); 407caa4e7f2SJed Brown } 408caa4e7f2SJed Brown 409caa4e7f2SJed Brown #undef __FUNCT__ 4106cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices" 4116cab3a1bSJed Brown /*@ 4126cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 4136cab3a1bSJed Brown 4146cab3a1bSJed Brown Collective 4156cab3a1bSJed Brown 4166cab3a1bSJed Brown Input Arguments: 4176cab3a1bSJed Brown . snes - snes to configure 4186cab3a1bSJed Brown 4196cab3a1bSJed Brown Level: developer 4206cab3a1bSJed Brown 4216cab3a1bSJed Brown .seealso: SNESSetUp() 4226cab3a1bSJed Brown @*/ 4236cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 4246cab3a1bSJed Brown { 4256cab3a1bSJed Brown PetscErrorCode ierr; 4266cab3a1bSJed Brown DM dm; 4276cab3a1bSJed Brown SNESDM sdm; 4286cab3a1bSJed Brown 4296cab3a1bSJed Brown PetscFunctionBegin; 4306cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 4316cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 432caa4e7f2SJed Brown if (!sdm->computejacobian) { 43317842b4fSJed Brown SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_PLIB,"SNESDM not improperly configured"); 4346cab3a1bSJed Brown } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) { 4356cab3a1bSJed Brown Mat J; 4366cab3a1bSJed Brown void *functx; 4376cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4386cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4396cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4406cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 4416cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr); 4426cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 443caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 4446cab3a1bSJed Brown Mat J,B; 4456cab3a1bSJed Brown ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr); 4466cab3a1bSJed Brown ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr); 4476cab3a1bSJed Brown ierr = MatSetFromOptions(J);CHKERRQ(ierr); 4486cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 44906f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 45006f20277SJed Brown ierr = SNESSetJacobian(snes,J,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4516cab3a1bSJed Brown ierr = MatDestroy(&J);CHKERRQ(ierr); 4526cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 453caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 4546cab3a1bSJed Brown Mat J,B; 4556cab3a1bSJed Brown J = snes->jacobian; 4566cab3a1bSJed Brown ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr); 4576cab3a1bSJed Brown ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 4586cab3a1bSJed Brown ierr = MatDestroy(&B);CHKERRQ(ierr); 4596cab3a1bSJed Brown } 460caa4e7f2SJed Brown { 461caa4e7f2SJed Brown KSP ksp; 462caa4e7f2SJed Brown ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 463caa4e7f2SJed Brown ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr); 46416ebb321SJed Brown ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr); 465caa4e7f2SJed Brown } 4666cab3a1bSJed Brown PetscFunctionReturn(0); 4676cab3a1bSJed Brown } 4686cab3a1bSJed Brown 4696cab3a1bSJed Brown #undef __FUNCT__ 4704a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions" 4719b94acceSBarry Smith /*@ 47294b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 4739b94acceSBarry Smith 474c7afd0dbSLois Curfman McInnes Collective on SNES 475c7afd0dbSLois Curfman McInnes 4769b94acceSBarry Smith Input Parameter: 4779b94acceSBarry Smith . snes - the SNES context 4789b94acceSBarry Smith 47936851e7fSLois Curfman McInnes Options Database Keys: 480ea630c6eSPeter Brune + -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas 48182738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 48282738288SBarry Smith of the change in the solution between steps 48370441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 484b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 485b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 486b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 4874839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 488ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 489a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 490e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 491b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 4922492ecdbSBarry Smith . -snes_no_convergence_test - skip convergence test in nonlinear 49382738288SBarry Smith solver; hence iterations will continue until max_it 4941fbbfb26SLois Curfman McInnes or some other criterion is reached. Saves expense 49582738288SBarry Smith of convergence test 496e8105e01SRichard Katz . -snes_monitor <optional filename> - prints residual norm at each iteration. if no 497e8105e01SRichard Katz filename given prints to stdout 498a6570f20SBarry Smith . -snes_monitor_solution - plots solution at each iteration 499a6570f20SBarry Smith . -snes_monitor_residual - plots residual (not its norm) at each iteration 500a6570f20SBarry Smith . -snes_monitor_solution_update - plots update to solution at each iteration 501a6570f20SBarry Smith . -snes_monitor_draw - plots residual norm at each iteration 502e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 5035968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 504fee2055bSBarry Smith - -snes_converged_reason - print the reason for convergence/divergence after each solve 50582738288SBarry Smith 50682738288SBarry Smith Options Database for Eisenstat-Walker method: 507fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 5084b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 50936851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 51036851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 51136851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 51236851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 51336851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 51436851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 51582738288SBarry Smith 51611ca99fdSLois Curfman McInnes Notes: 51711ca99fdSLois Curfman McInnes To see all options, run your program with the -help option or consult 5180598bfebSBarry Smith the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>. 51983e2fdc7SBarry Smith 52036851e7fSLois Curfman McInnes Level: beginner 52136851e7fSLois Curfman McInnes 5229b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database 5239b94acceSBarry Smith 52469ed319cSSatish Balay .seealso: SNESSetOptionsPrefix() 5259b94acceSBarry Smith @*/ 5267087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 5279b94acceSBarry Smith { 528872b6db9SPeter Brune PetscBool flg,mf,mf_operator,pcset; 529efd51863SBarry Smith PetscInt i,indx,lag,mf_version,grids; 530aa3661deSLisandro Dalcin MatStructure matflag; 53185385478SLisandro Dalcin const char *deft = SNESLS; 53285385478SLisandro Dalcin const char *convtests[] = {"default","skip"}; 53385385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 534e8105e01SRichard Katz char type[256], monfilename[PETSC_MAX_PATH_LEN]; 535649052a6SBarry Smith PetscViewer monviewer; 53685385478SLisandro Dalcin PetscErrorCode ierr; 537a64e098fSPeter Brune const char *optionsprefix; 5389b94acceSBarry Smith 5393a40ed3dSBarry Smith PetscFunctionBegin; 5400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 541ca161407SBarry Smith 542186905e3SBarry Smith if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 5433194b578SJed Brown ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr); 5447adad957SLisandro Dalcin if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; } 545b0a32e0cSBarry Smith ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr); 546d64ed03dSBarry Smith if (flg) { 547186905e3SBarry Smith ierr = SNESSetType(snes,type);CHKERRQ(ierr); 5487adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 549186905e3SBarry Smith ierr = SNESSetType(snes,deft);CHKERRQ(ierr); 550d64ed03dSBarry Smith } 55190d69ab7SBarry Smith /* not used here, but called so will go into help messaage */ 552909c8a9fSBarry Smith ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr); 55393c39befSBarry Smith 554c60f73f4SPeter Brune ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr); 55557034d6fSHong Zhang ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr); 556186905e3SBarry Smith 55757034d6fSHong Zhang ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr); 558b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr); 559b0a32e0cSBarry Smith ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr); 56024254dc1SJed Brown ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr); 561ddf469c8SBarry Smith ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr); 562acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr); 56385385478SLisandro Dalcin 564a8054027SBarry Smith ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr); 565a8054027SBarry Smith if (flg) { 566a8054027SBarry Smith ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr); 567a8054027SBarry Smith } 568e35cf81dSBarry Smith ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr); 569e35cf81dSBarry Smith if (flg) { 570e35cf81dSBarry Smith ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr); 571e35cf81dSBarry Smith } 572efd51863SBarry Smith ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr); 573efd51863SBarry Smith if (flg) { 574efd51863SBarry Smith ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr); 575efd51863SBarry Smith } 576a8054027SBarry Smith 57785385478SLisandro Dalcin ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr); 57885385478SLisandro Dalcin if (flg) { 57985385478SLisandro Dalcin switch (indx) { 5807f7931b9SBarry Smith case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 5817f7931b9SBarry Smith case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break; 58285385478SLisandro Dalcin } 58385385478SLisandro Dalcin } 58485385478SLisandro Dalcin 585acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr); 586186905e3SBarry Smith 587fdacfa88SPeter Brune ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr); 588fdacfa88SPeter Brune if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); } 589fdacfa88SPeter Brune 59085385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 59185385478SLisandro Dalcin 592acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr); 593186905e3SBarry Smith 594fa9f3622SBarry Smith ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr); 595fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr); 596fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr); 597fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr); 598fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr); 599fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr); 600fa9f3622SBarry Smith ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr); 601186905e3SBarry Smith 60290d69ab7SBarry Smith flg = PETSC_FALSE; 603acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 604a6570f20SBarry Smith if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);} 605eabae89aSBarry Smith 606a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 607e8105e01SRichard Katz if (flg) { 608649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 609649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 610e8105e01SRichard Katz } 611eabae89aSBarry Smith 612b271bb04SBarry Smith ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 613b271bb04SBarry Smith if (flg) { 614b271bb04SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr); 615b271bb04SBarry Smith } 616b271bb04SBarry Smith 617a6570f20SBarry Smith ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 618eabae89aSBarry Smith if (flg) { 619649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 620f1bef1bcSMatthew Knepley ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr); 621e8105e01SRichard Katz } 622eabae89aSBarry Smith 623a6570f20SBarry Smith ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 624eabae89aSBarry Smith if (flg) { 625649052a6SBarry Smith ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr); 626649052a6SBarry Smith ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr); 627eabae89aSBarry Smith } 628eabae89aSBarry Smith 6295180491cSLisandro Dalcin ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 6305180491cSLisandro Dalcin if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);} 6315180491cSLisandro Dalcin 63290d69ab7SBarry Smith flg = PETSC_FALSE; 633acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 634a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);} 63590d69ab7SBarry Smith flg = PETSC_FALSE; 636acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 637a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);} 63890d69ab7SBarry Smith flg = PETSC_FALSE; 639acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 640a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);} 64190d69ab7SBarry Smith flg = PETSC_FALSE; 642acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 643a6570f20SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 64490d69ab7SBarry Smith flg = PETSC_FALSE; 645acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 646b271bb04SBarry Smith if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);} 647e24b481bSBarry Smith 64890d69ab7SBarry Smith flg = PETSC_FALSE; 649acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr); 6504b27c08aSLois Curfman McInnes if (flg) { 6516cab3a1bSJed Brown void *functx; 6526cab3a1bSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr); 6536cab3a1bSJed Brown ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr); 654ae15b995SBarry Smith ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr); 6559b94acceSBarry Smith } 656639f9d9dSBarry Smith 657aa3661deSLisandro Dalcin mf = mf_operator = PETSC_FALSE; 658aa3661deSLisandro Dalcin flg = PETSC_FALSE; 659acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr); 660a8248277SBarry Smith if (flg && mf_operator) { 661a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 662a8248277SBarry Smith mf = PETSC_TRUE; 663a8248277SBarry Smith } 664aa3661deSLisandro Dalcin flg = PETSC_FALSE; 665acfcf0e5SJed Brown ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr); 666aa3661deSLisandro Dalcin if (!flg && mf_operator) mf = PETSC_TRUE; 667aa3661deSLisandro Dalcin mf_version = 1; 668aa3661deSLisandro Dalcin ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr); 669aa3661deSLisandro Dalcin 670d28543b3SPeter Brune 67189b92e6fSPeter Brune /* GS Options */ 67289b92e6fSPeter Brune ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr); 67389b92e6fSPeter Brune 67476b2cf59SMatthew Knepley for(i = 0; i < numberofsetfromoptions; i++) { 67576b2cf59SMatthew Knepley ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr); 67676b2cf59SMatthew Knepley } 67776b2cf59SMatthew Knepley 678e7788613SBarry Smith if (snes->ops->setfromoptions) { 679e7788613SBarry Smith ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr); 680639f9d9dSBarry Smith } 6815d973c19SBarry Smith 6825d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 6835d973c19SBarry Smith ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr); 684b0a32e0cSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 6854bbc92c1SBarry Smith 686aa3661deSLisandro Dalcin if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); } 6871cee3971SBarry Smith 6881cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 689aa3661deSLisandro Dalcin ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag); 690aa3661deSLisandro Dalcin ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr); 69185385478SLisandro Dalcin ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr); 69293993e2dSLois Curfman McInnes 6939e764e56SPeter Brune if (!snes->linesearch) { 694f1c6b773SPeter Brune ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr); 6959e764e56SPeter Brune } 696f1c6b773SPeter Brune ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr); 6979e764e56SPeter Brune 69851e86f29SPeter Brune /* if someone has set the SNES PC type, create it. */ 69951e86f29SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 70051e86f29SPeter Brune ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr); 70151e86f29SPeter Brune if (pcset && (!snes->pc)) { 70251e86f29SPeter Brune ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr); 70351e86f29SPeter Brune } 7043a40ed3dSBarry Smith PetscFunctionReturn(0); 7059b94acceSBarry Smith } 7069b94acceSBarry Smith 707d25893d9SBarry Smith #undef __FUNCT__ 708d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext" 709d25893d9SBarry Smith /*@ 710d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 711d25893d9SBarry Smith the nonlinear solvers. 712d25893d9SBarry Smith 713d25893d9SBarry Smith Logically Collective on SNES 714d25893d9SBarry Smith 715d25893d9SBarry Smith Input Parameters: 716d25893d9SBarry Smith + snes - the SNES context 717d25893d9SBarry Smith . compute - function to compute the context 718d25893d9SBarry Smith - destroy - function to destroy the context 719d25893d9SBarry Smith 720d25893d9SBarry Smith Level: intermediate 721d25893d9SBarry Smith 722d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context 723d25893d9SBarry Smith 724d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext() 725d25893d9SBarry Smith @*/ 726d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 727d25893d9SBarry Smith { 728d25893d9SBarry Smith PetscFunctionBegin; 729d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 730d25893d9SBarry Smith snes->ops->usercompute = compute; 731d25893d9SBarry Smith snes->ops->userdestroy = destroy; 732d25893d9SBarry Smith PetscFunctionReturn(0); 733d25893d9SBarry Smith } 734a847f771SSatish Balay 7354a2ae208SSatish Balay #undef __FUNCT__ 7364a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext" 737b07ff414SBarry Smith /*@ 7389b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 7399b94acceSBarry Smith the nonlinear solvers. 7409b94acceSBarry Smith 7413f9fe445SBarry Smith Logically Collective on SNES 742fee21e36SBarry Smith 743c7afd0dbSLois Curfman McInnes Input Parameters: 744c7afd0dbSLois Curfman McInnes + snes - the SNES context 745c7afd0dbSLois Curfman McInnes - usrP - optional user context 746c7afd0dbSLois Curfman McInnes 74736851e7fSLois Curfman McInnes Level: intermediate 74836851e7fSLois Curfman McInnes 7499b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context 7509b94acceSBarry Smith 751ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext() 7529b94acceSBarry Smith @*/ 7537087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 7549b94acceSBarry Smith { 7551b2093e4SBarry Smith PetscErrorCode ierr; 756b07ff414SBarry Smith KSP ksp; 7571b2093e4SBarry Smith 7583a40ed3dSBarry Smith PetscFunctionBegin; 7590700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 760b07ff414SBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 761b07ff414SBarry Smith ierr = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr); 7629b94acceSBarry Smith snes->user = usrP; 7633a40ed3dSBarry Smith PetscFunctionReturn(0); 7649b94acceSBarry Smith } 76574679c65SBarry Smith 7664a2ae208SSatish Balay #undef __FUNCT__ 7674a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext" 768b07ff414SBarry Smith /*@ 7699b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 7709b94acceSBarry Smith nonlinear solvers. 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 . usrP - user context 7799b94acceSBarry Smith 78036851e7fSLois Curfman McInnes Level: intermediate 78136851e7fSLois Curfman McInnes 7829b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context 7839b94acceSBarry Smith 7849b94acceSBarry Smith .seealso: SNESSetApplicationContext() 7859b94acceSBarry Smith @*/ 786e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 7879b94acceSBarry Smith { 7883a40ed3dSBarry Smith PetscFunctionBegin; 7890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 790e71120c6SJed Brown *(void**)usrP = snes->user; 7913a40ed3dSBarry Smith PetscFunctionReturn(0); 7929b94acceSBarry Smith } 79374679c65SBarry Smith 7944a2ae208SSatish Balay #undef __FUNCT__ 7954a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber" 7969b94acceSBarry Smith /*@ 797c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 798c8228a4eSBarry Smith at this time. 7999b94acceSBarry Smith 800c7afd0dbSLois Curfman McInnes Not Collective 801c7afd0dbSLois Curfman McInnes 8029b94acceSBarry Smith Input Parameter: 8039b94acceSBarry Smith . snes - SNES context 8049b94acceSBarry Smith 8059b94acceSBarry Smith Output Parameter: 8069b94acceSBarry Smith . iter - iteration number 8079b94acceSBarry Smith 808c8228a4eSBarry Smith Notes: 809c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 810c8228a4eSBarry Smith 811c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 81208405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 81308405cd6SLois Curfman McInnes .vb 81408405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 81508405cd6SLois Curfman McInnes if (!(it % 2)) { 81608405cd6SLois Curfman McInnes [compute Jacobian here] 81708405cd6SLois Curfman McInnes } 81808405cd6SLois Curfman McInnes .ve 819c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 82008405cd6SLois Curfman McInnes recomputed every second SNES iteration. 821c8228a4eSBarry Smith 82236851e7fSLois Curfman McInnes Level: intermediate 82336851e7fSLois Curfman McInnes 8242b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number, 8252b668275SBarry Smith 826b850b91aSLisandro Dalcin .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 8279b94acceSBarry Smith @*/ 8287087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter) 8299b94acceSBarry Smith { 8303a40ed3dSBarry Smith PetscFunctionBegin; 8310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8324482741eSBarry Smith PetscValidIntPointer(iter,2); 8339b94acceSBarry Smith *iter = snes->iter; 8343a40ed3dSBarry Smith PetscFunctionReturn(0); 8359b94acceSBarry Smith } 83674679c65SBarry Smith 8374a2ae208SSatish Balay #undef __FUNCT__ 838360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber" 839360c497dSPeter Brune /*@ 840360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 841360c497dSPeter Brune 842360c497dSPeter Brune Not Collective 843360c497dSPeter Brune 844360c497dSPeter Brune Input Parameter: 845360c497dSPeter Brune . snes - SNES context 846360c497dSPeter Brune . iter - iteration number 847360c497dSPeter Brune 848360c497dSPeter Brune Level: developer 849360c497dSPeter Brune 850360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number, 851360c497dSPeter Brune 852360c497dSPeter Brune .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations() 853360c497dSPeter Brune @*/ 854360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 855360c497dSPeter Brune { 856360c497dSPeter Brune PetscErrorCode ierr; 857360c497dSPeter Brune 858360c497dSPeter Brune PetscFunctionBegin; 859360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 860360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 861360c497dSPeter Brune snes->iter = iter; 862360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 863360c497dSPeter Brune PetscFunctionReturn(0); 864360c497dSPeter Brune } 865360c497dSPeter Brune 866360c497dSPeter Brune #undef __FUNCT__ 8674a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm" 8689b94acceSBarry Smith /*@ 8699b94acceSBarry Smith SNESGetFunctionNorm - Gets the norm of the current function that was set 8709b94acceSBarry Smith with SNESSSetFunction(). 8719b94acceSBarry Smith 872c7afd0dbSLois Curfman McInnes Collective on SNES 873c7afd0dbSLois Curfman McInnes 8749b94acceSBarry Smith Input Parameter: 8759b94acceSBarry Smith . snes - SNES context 8769b94acceSBarry Smith 8779b94acceSBarry Smith Output Parameter: 8789b94acceSBarry Smith . fnorm - 2-norm of function 8799b94acceSBarry Smith 88036851e7fSLois Curfman McInnes Level: intermediate 88136851e7fSLois Curfman McInnes 8829b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm 883a86d99e1SLois Curfman McInnes 884b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations() 8859b94acceSBarry Smith @*/ 8867087cfbeSBarry Smith PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm) 8879b94acceSBarry Smith { 8883a40ed3dSBarry Smith PetscFunctionBegin; 8890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 8904482741eSBarry Smith PetscValidScalarPointer(fnorm,2); 8919b94acceSBarry Smith *fnorm = snes->norm; 8923a40ed3dSBarry Smith PetscFunctionReturn(0); 8939b94acceSBarry Smith } 89474679c65SBarry Smith 895360c497dSPeter Brune 896360c497dSPeter Brune #undef __FUNCT__ 897360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm" 898360c497dSPeter Brune /*@ 899360c497dSPeter Brune SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm(). 900360c497dSPeter Brune 901360c497dSPeter Brune Collective on SNES 902360c497dSPeter Brune 903360c497dSPeter Brune Input Parameter: 904360c497dSPeter Brune . snes - SNES context 905360c497dSPeter Brune . fnorm - 2-norm of function 906360c497dSPeter Brune 907360c497dSPeter Brune Level: developer 908360c497dSPeter Brune 909360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm 910360c497dSPeter Brune 911360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm(). 912360c497dSPeter Brune @*/ 913360c497dSPeter Brune PetscErrorCode SNESSetFunctionNorm(SNES snes,PetscReal fnorm) 914360c497dSPeter Brune { 915360c497dSPeter Brune 916360c497dSPeter Brune PetscErrorCode ierr; 917360c497dSPeter Brune 918360c497dSPeter Brune PetscFunctionBegin; 919360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 920360c497dSPeter Brune ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr); 921360c497dSPeter Brune snes->norm = fnorm; 922360c497dSPeter Brune ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr); 923360c497dSPeter Brune PetscFunctionReturn(0); 924360c497dSPeter Brune } 925360c497dSPeter Brune 9264a2ae208SSatish Balay #undef __FUNCT__ 927b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures" 9289b94acceSBarry Smith /*@ 929b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 9309b94acceSBarry Smith attempted by the nonlinear solver. 9319b94acceSBarry Smith 932c7afd0dbSLois Curfman McInnes Not Collective 933c7afd0dbSLois Curfman McInnes 9349b94acceSBarry Smith Input Parameter: 9359b94acceSBarry Smith . snes - SNES context 9369b94acceSBarry Smith 9379b94acceSBarry Smith Output Parameter: 9389b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 9399b94acceSBarry Smith 940c96a6f78SLois Curfman McInnes Notes: 941c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 942c96a6f78SLois Curfman McInnes 94336851e7fSLois Curfman McInnes Level: intermediate 94436851e7fSLois Curfman McInnes 9459b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 94658ebbce7SBarry Smith 947e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 94858ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures() 9499b94acceSBarry Smith @*/ 9507087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails) 9519b94acceSBarry Smith { 9523a40ed3dSBarry Smith PetscFunctionBegin; 9530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9544482741eSBarry Smith PetscValidIntPointer(nfails,2); 95550ffb88aSMatthew Knepley *nfails = snes->numFailures; 95650ffb88aSMatthew Knepley PetscFunctionReturn(0); 95750ffb88aSMatthew Knepley } 95850ffb88aSMatthew Knepley 95950ffb88aSMatthew Knepley #undef __FUNCT__ 960b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures" 96150ffb88aSMatthew Knepley /*@ 962b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 96350ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 96450ffb88aSMatthew Knepley 96550ffb88aSMatthew Knepley Not Collective 96650ffb88aSMatthew Knepley 96750ffb88aSMatthew Knepley Input Parameters: 96850ffb88aSMatthew Knepley + snes - SNES context 96950ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 97050ffb88aSMatthew Knepley 97150ffb88aSMatthew Knepley Level: intermediate 97250ffb88aSMatthew Knepley 97350ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 97458ebbce7SBarry Smith 975e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 97658ebbce7SBarry Smith SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 97750ffb88aSMatthew Knepley @*/ 9787087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 97950ffb88aSMatthew Knepley { 98050ffb88aSMatthew Knepley PetscFunctionBegin; 9810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 98250ffb88aSMatthew Knepley snes->maxFailures = maxFails; 98350ffb88aSMatthew Knepley PetscFunctionReturn(0); 98450ffb88aSMatthew Knepley } 98550ffb88aSMatthew Knepley 98650ffb88aSMatthew Knepley #undef __FUNCT__ 987b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures" 98850ffb88aSMatthew Knepley /*@ 989b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 99050ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 99150ffb88aSMatthew Knepley 99250ffb88aSMatthew Knepley Not Collective 99350ffb88aSMatthew Knepley 99450ffb88aSMatthew Knepley Input Parameter: 99550ffb88aSMatthew Knepley . snes - SNES context 99650ffb88aSMatthew Knepley 99750ffb88aSMatthew Knepley Output Parameter: 99850ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 99950ffb88aSMatthew Knepley 100050ffb88aSMatthew Knepley Level: intermediate 100150ffb88aSMatthew Knepley 100250ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 100358ebbce7SBarry Smith 1004e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), 100558ebbce7SBarry Smith SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures() 100658ebbce7SBarry Smith 100750ffb88aSMatthew Knepley @*/ 10087087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 100950ffb88aSMatthew Knepley { 101050ffb88aSMatthew Knepley PetscFunctionBegin; 10110700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10124482741eSBarry Smith PetscValidIntPointer(maxFails,2); 101350ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 10143a40ed3dSBarry Smith PetscFunctionReturn(0); 10159b94acceSBarry Smith } 1016a847f771SSatish Balay 10174a2ae208SSatish Balay #undef __FUNCT__ 10182541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals" 10192541af92SBarry Smith /*@ 10202541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 10212541af92SBarry Smith done by SNES. 10222541af92SBarry Smith 10232541af92SBarry Smith Not Collective 10242541af92SBarry Smith 10252541af92SBarry Smith Input Parameter: 10262541af92SBarry Smith . snes - SNES context 10272541af92SBarry Smith 10282541af92SBarry Smith Output Parameter: 10292541af92SBarry Smith . nfuncs - number of evaluations 10302541af92SBarry Smith 10312541af92SBarry Smith Level: intermediate 10322541af92SBarry Smith 10332541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 103458ebbce7SBarry Smith 1035e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures() 10362541af92SBarry Smith @*/ 10377087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 10382541af92SBarry Smith { 10392541af92SBarry Smith PetscFunctionBegin; 10400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10412541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 10422541af92SBarry Smith *nfuncs = snes->nfuncs; 10432541af92SBarry Smith PetscFunctionReturn(0); 10442541af92SBarry Smith } 10452541af92SBarry Smith 10462541af92SBarry Smith #undef __FUNCT__ 10473d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures" 10483d4c4710SBarry Smith /*@ 10493d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 10503d4c4710SBarry Smith linear solvers. 10513d4c4710SBarry Smith 10523d4c4710SBarry Smith Not Collective 10533d4c4710SBarry Smith 10543d4c4710SBarry Smith Input Parameter: 10553d4c4710SBarry Smith . snes - SNES context 10563d4c4710SBarry Smith 10573d4c4710SBarry Smith Output Parameter: 10583d4c4710SBarry Smith . nfails - number of failed solves 10593d4c4710SBarry Smith 10603d4c4710SBarry Smith Notes: 10613d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 10623d4c4710SBarry Smith 10633d4c4710SBarry Smith Level: intermediate 10643d4c4710SBarry Smith 10653d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps 106658ebbce7SBarry Smith 1067e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures() 10683d4c4710SBarry Smith @*/ 10697087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails) 10703d4c4710SBarry Smith { 10713d4c4710SBarry Smith PetscFunctionBegin; 10720700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 10733d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 10743d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 10753d4c4710SBarry Smith PetscFunctionReturn(0); 10763d4c4710SBarry Smith } 10773d4c4710SBarry Smith 10783d4c4710SBarry Smith #undef __FUNCT__ 10793d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures" 10803d4c4710SBarry Smith /*@ 10813d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 10823d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 10833d4c4710SBarry Smith 10843f9fe445SBarry Smith Logically Collective on SNES 10853d4c4710SBarry Smith 10863d4c4710SBarry Smith Input Parameters: 10873d4c4710SBarry Smith + snes - SNES context 10883d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 10893d4c4710SBarry Smith 10903d4c4710SBarry Smith Level: intermediate 10913d4c4710SBarry Smith 1092a6796414SBarry Smith Notes: By default this is 0; that is SNES returns on the first failed linear solve 10933d4c4710SBarry Smith 10943d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps 10953d4c4710SBarry Smith 109658ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations() 10973d4c4710SBarry Smith @*/ 10987087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 10993d4c4710SBarry Smith { 11003d4c4710SBarry Smith PetscFunctionBegin; 11010700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1102c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 11033d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 11043d4c4710SBarry Smith PetscFunctionReturn(0); 11053d4c4710SBarry Smith } 11063d4c4710SBarry Smith 11073d4c4710SBarry Smith #undef __FUNCT__ 11083d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures" 11093d4c4710SBarry Smith /*@ 11103d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 11113d4c4710SBarry Smith are allowed before SNES terminates 11123d4c4710SBarry Smith 11133d4c4710SBarry Smith Not Collective 11143d4c4710SBarry Smith 11153d4c4710SBarry Smith Input Parameter: 11163d4c4710SBarry Smith . snes - SNES context 11173d4c4710SBarry Smith 11183d4c4710SBarry Smith Output Parameter: 11193d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 11203d4c4710SBarry Smith 11213d4c4710SBarry Smith Level: intermediate 11223d4c4710SBarry Smith 11233d4c4710SBarry Smith Notes: By default this is 1; that is SNES returns on the first failed linear solve 11243d4c4710SBarry Smith 11253d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps 11263d4c4710SBarry Smith 1127e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), 11283d4c4710SBarry Smith @*/ 11297087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 11303d4c4710SBarry Smith { 11313d4c4710SBarry Smith PetscFunctionBegin; 11320700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11333d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 11343d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 11353d4c4710SBarry Smith PetscFunctionReturn(0); 11363d4c4710SBarry Smith } 11373d4c4710SBarry Smith 11383d4c4710SBarry Smith #undef __FUNCT__ 1139b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations" 1140c96a6f78SLois Curfman McInnes /*@ 1141b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1142c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1143c96a6f78SLois Curfman McInnes 1144c7afd0dbSLois Curfman McInnes Not Collective 1145c7afd0dbSLois Curfman McInnes 1146c96a6f78SLois Curfman McInnes Input Parameter: 1147c96a6f78SLois Curfman McInnes . snes - SNES context 1148c96a6f78SLois Curfman McInnes 1149c96a6f78SLois Curfman McInnes Output Parameter: 1150c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1151c96a6f78SLois Curfman McInnes 1152c96a6f78SLois Curfman McInnes Notes: 1153c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1154c96a6f78SLois Curfman McInnes 115536851e7fSLois Curfman McInnes Level: intermediate 115636851e7fSLois Curfman McInnes 1157c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations 11582b668275SBarry Smith 11598c7482ecSBarry Smith .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures() 1160c96a6f78SLois Curfman McInnes @*/ 11617087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits) 1162c96a6f78SLois Curfman McInnes { 11633a40ed3dSBarry Smith PetscFunctionBegin; 11640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 11654482741eSBarry Smith PetscValidIntPointer(lits,2); 1166c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 11673a40ed3dSBarry Smith PetscFunctionReturn(0); 1168c96a6f78SLois Curfman McInnes } 1169c96a6f78SLois Curfman McInnes 11704a2ae208SSatish Balay #undef __FUNCT__ 117194b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP" 117252baeb72SSatish Balay /*@ 117394b7f48cSBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 11749b94acceSBarry Smith 117594b7f48cSBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 1176c7afd0dbSLois Curfman McInnes 11779b94acceSBarry Smith Input Parameter: 11789b94acceSBarry Smith . snes - the SNES context 11799b94acceSBarry Smith 11809b94acceSBarry Smith Output Parameter: 118194b7f48cSBarry Smith . ksp - the KSP context 11829b94acceSBarry Smith 11839b94acceSBarry Smith Notes: 118494b7f48cSBarry Smith The user can then directly manipulate the KSP context to set various 11859b94acceSBarry Smith options, etc. Likewise, the user can then extract and manipulate the 11862999313aSBarry Smith PC contexts as well. 11879b94acceSBarry Smith 118836851e7fSLois Curfman McInnes Level: beginner 118936851e7fSLois Curfman McInnes 119094b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 11919b94acceSBarry Smith 11922999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 11939b94acceSBarry Smith @*/ 11947087cfbeSBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 11959b94acceSBarry Smith { 11961cee3971SBarry Smith PetscErrorCode ierr; 11971cee3971SBarry Smith 11983a40ed3dSBarry Smith PetscFunctionBegin; 11990700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12004482741eSBarry Smith PetscValidPointer(ksp,2); 12011cee3971SBarry Smith 12021cee3971SBarry Smith if (!snes->ksp) { 12031cee3971SBarry Smith ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr); 12041cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr); 12051cee3971SBarry Smith ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr); 12061cee3971SBarry Smith } 120794b7f48cSBarry Smith *ksp = snes->ksp; 12083a40ed3dSBarry Smith PetscFunctionReturn(0); 12099b94acceSBarry Smith } 121082bf6240SBarry Smith 12114a2ae208SSatish Balay #undef __FUNCT__ 12122999313aSBarry Smith #define __FUNCT__ "SNESSetKSP" 12132999313aSBarry Smith /*@ 12142999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 12152999313aSBarry Smith 12162999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 12172999313aSBarry Smith 12182999313aSBarry Smith Input Parameters: 12192999313aSBarry Smith + snes - the SNES context 12202999313aSBarry Smith - ksp - the KSP context 12212999313aSBarry Smith 12222999313aSBarry Smith Notes: 12232999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 12242999313aSBarry Smith so this routine is rarely needed. 12252999313aSBarry Smith 12262999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 12272999313aSBarry Smith decreased by one. 12282999313aSBarry Smith 12292999313aSBarry Smith Level: developer 12302999313aSBarry Smith 12312999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context 12322999313aSBarry Smith 12332999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP() 12342999313aSBarry Smith @*/ 12357087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 12362999313aSBarry Smith { 12372999313aSBarry Smith PetscErrorCode ierr; 12382999313aSBarry Smith 12392999313aSBarry Smith PetscFunctionBegin; 12400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12410700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 12422999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 12437dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr); 1244906ed7ccSBarry Smith if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);} 12452999313aSBarry Smith snes->ksp = ksp; 12462999313aSBarry Smith PetscFunctionReturn(0); 12472999313aSBarry Smith } 12482999313aSBarry Smith 12497adad957SLisandro Dalcin #if 0 12502999313aSBarry Smith #undef __FUNCT__ 12514a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc" 12526849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj) 1253e24b481bSBarry Smith { 1254e24b481bSBarry Smith PetscFunctionBegin; 1255e24b481bSBarry Smith PetscFunctionReturn(0); 1256e24b481bSBarry Smith } 12577adad957SLisandro Dalcin #endif 1258e24b481bSBarry Smith 12599b94acceSBarry Smith /* -----------------------------------------------------------*/ 12604a2ae208SSatish Balay #undef __FUNCT__ 12614a2ae208SSatish Balay #define __FUNCT__ "SNESCreate" 126252baeb72SSatish Balay /*@ 12639b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 12649b94acceSBarry Smith 1265c7afd0dbSLois Curfman McInnes Collective on MPI_Comm 1266c7afd0dbSLois Curfman McInnes 1267c7afd0dbSLois Curfman McInnes Input Parameters: 1268906ed7ccSBarry Smith . comm - MPI communicator 12699b94acceSBarry Smith 12709b94acceSBarry Smith Output Parameter: 12719b94acceSBarry Smith . outsnes - the new SNES context 12729b94acceSBarry Smith 1273c7afd0dbSLois Curfman McInnes Options Database Keys: 1274c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1275c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1276c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1277c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1278c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1279c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1280c1f60f51SBarry Smith 128136851e7fSLois Curfman McInnes Level: beginner 128236851e7fSLois Curfman McInnes 12839b94acceSBarry Smith .keywords: SNES, nonlinear, create, context 12849b94acceSBarry Smith 1285a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner() 1286a8054027SBarry Smith 12879b94acceSBarry Smith @*/ 12887087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 12899b94acceSBarry Smith { 1290dfbe8321SBarry Smith PetscErrorCode ierr; 12919b94acceSBarry Smith SNES snes; 1292fa9f3622SBarry Smith SNESKSPEW *kctx; 129337fcc0dbSBarry Smith 12943a40ed3dSBarry Smith PetscFunctionBegin; 1295ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 12968ba1e511SMatthew Knepley *outsnes = PETSC_NULL; 12978ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES 12988ba1e511SMatthew Knepley ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr); 12998ba1e511SMatthew Knepley #endif 13008ba1e511SMatthew Knepley 13013194b578SJed Brown ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr); 13027adad957SLisandro Dalcin 130385385478SLisandro Dalcin snes->ops->converged = SNESDefaultConverged; 13042c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 130588976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 13069b94acceSBarry Smith snes->max_its = 50; 13079750a799SBarry Smith snes->max_funcs = 10000; 13089b94acceSBarry Smith snes->norm = 0.0; 1309fdacfa88SPeter Brune snes->normtype = SNES_NORM_FUNCTION; 1310b4874afaSBarry Smith snes->rtol = 1.e-8; 1311b4874afaSBarry Smith snes->ttol = 0.0; 131270441072SBarry Smith snes->abstol = 1.e-50; 1313c60f73f4SPeter Brune snes->stol = 1.e-8; 13144b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 13159b94acceSBarry Smith snes->nfuncs = 0; 131650ffb88aSMatthew Knepley snes->numFailures = 0; 131750ffb88aSMatthew Knepley snes->maxFailures = 1; 13187a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1319e35cf81dSBarry Smith snes->lagjacobian = 1; 1320a8054027SBarry Smith snes->lagpreconditioner = 1; 1321639f9d9dSBarry Smith snes->numbermonitors = 0; 13229b94acceSBarry Smith snes->data = 0; 13234dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1324186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 13256f24a144SLois Curfman McInnes snes->nwork = 0; 132658c9b817SLisandro Dalcin snes->work = 0; 132758c9b817SLisandro Dalcin snes->nvwork = 0; 132858c9b817SLisandro Dalcin snes->vwork = 0; 1329758f92a0SBarry Smith snes->conv_hist_len = 0; 1330758f92a0SBarry Smith snes->conv_hist_max = 0; 1331758f92a0SBarry Smith snes->conv_hist = PETSC_NULL; 1332758f92a0SBarry Smith snes->conv_hist_its = PETSC_NULL; 1333758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1334e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1335e4ed7901SPeter Brune snes->norm_init = 0.; 1336e4ed7901SPeter Brune snes->norm_init_set = PETSC_FALSE; 1337184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 133889b92e6fSPeter Brune snes->gssweeps = 1; 13399b94acceSBarry Smith 13403d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 13413d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 13423d4c4710SBarry Smith 13439b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 134438f2d2fdSLisandro Dalcin ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr); 13459b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 13469b94acceSBarry Smith kctx->version = 2; 13479b94acceSBarry Smith kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 13489b94acceSBarry Smith this was too large for some test cases */ 134975567043SBarry Smith kctx->rtol_last = 0.0; 13509b94acceSBarry Smith kctx->rtol_max = .9; 13519b94acceSBarry Smith kctx->gamma = 1.0; 135262d1f40fSBarry Smith kctx->alpha = .5*(1.0 + PetscSqrtReal(5.0)); 135371f87433Sdalcinl kctx->alpha2 = kctx->alpha; 13549b94acceSBarry Smith kctx->threshold = .1; 135575567043SBarry Smith kctx->lresid_last = 0.0; 135675567043SBarry Smith kctx->norm_last = 0.0; 13579b94acceSBarry Smith 13589b94acceSBarry Smith *outsnes = snes; 13593a40ed3dSBarry Smith PetscFunctionReturn(0); 13609b94acceSBarry Smith } 13619b94acceSBarry Smith 13624a2ae208SSatish Balay #undef __FUNCT__ 13634a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction" 13649b94acceSBarry Smith /*@C 13659b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 13669b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 13679b94acceSBarry Smith equations. 13689b94acceSBarry Smith 13693f9fe445SBarry Smith Logically Collective on SNES 1370fee21e36SBarry Smith 1371c7afd0dbSLois Curfman McInnes Input Parameters: 1372c7afd0dbSLois Curfman McInnes + snes - the SNES context 1373c7afd0dbSLois Curfman McInnes . r - vector to store function value 1374de044059SHong Zhang . func - function evaluation routine 1375c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1376c7afd0dbSLois Curfman McInnes function evaluation routine (may be PETSC_NULL) 13779b94acceSBarry Smith 1378c7afd0dbSLois Curfman McInnes Calling sequence of func: 13798d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Vec f,void *ctx); 1380c7afd0dbSLois Curfman McInnes 1381c586c404SJed Brown + snes - the SNES context 1382c586c404SJed Brown . x - state at which to evaluate residual 1383c586c404SJed Brown . f - vector to put residual 1384c7afd0dbSLois Curfman McInnes - ctx - optional user-defined function context 13859b94acceSBarry Smith 13869b94acceSBarry Smith Notes: 13879b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 13889b94acceSBarry Smith $ f'(x) x = -f(x), 1389c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 13909b94acceSBarry Smith 139136851e7fSLois Curfman McInnes Level: beginner 139236851e7fSLois Curfman McInnes 13939b94acceSBarry Smith .keywords: SNES, nonlinear, set, function 13949b94acceSBarry Smith 13958b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard() 13969b94acceSBarry Smith @*/ 13977087cfbeSBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx) 13989b94acceSBarry Smith { 139985385478SLisandro Dalcin PetscErrorCode ierr; 14006cab3a1bSJed Brown DM dm; 14016cab3a1bSJed Brown 14023a40ed3dSBarry Smith PetscFunctionBegin; 14030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1404d2a683ecSLisandro Dalcin if (r) { 1405d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1406d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 140785385478SLisandro Dalcin ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr); 14086bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 140985385478SLisandro Dalcin snes->vec_func = r; 1410d2a683ecSLisandro Dalcin } 14116cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 14126cab3a1bSJed Brown ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr); 14133a40ed3dSBarry Smith PetscFunctionReturn(0); 14149b94acceSBarry Smith } 14159b94acceSBarry Smith 1416646217ecSPeter Brune 1417646217ecSPeter Brune #undef __FUNCT__ 1418e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction" 1419e4ed7901SPeter Brune /*@C 1420e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1421e4ed7901SPeter Brune function norm at the initialization of the method. In some 1422e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1423e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1424e4ed7901SPeter Brune to SNESComputeFunction in that case. 1425e4ed7901SPeter Brune 1426e4ed7901SPeter Brune Logically Collective on SNES 1427e4ed7901SPeter Brune 1428e4ed7901SPeter Brune Input Parameters: 1429e4ed7901SPeter Brune + snes - the SNES context 1430e4ed7901SPeter Brune - f - vector to store function value 1431e4ed7901SPeter Brune 1432e4ed7901SPeter Brune Notes: 1433e4ed7901SPeter Brune This should not be modified during the solution procedure. 1434e4ed7901SPeter Brune 1435e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1436e4ed7901SPeter Brune 1437e4ed7901SPeter Brune Level: developer 1438e4ed7901SPeter Brune 1439e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function 1440e4ed7901SPeter Brune 1441e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm() 1442e4ed7901SPeter Brune @*/ 1443e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1444e4ed7901SPeter Brune { 1445e4ed7901SPeter Brune PetscErrorCode ierr; 1446e4ed7901SPeter Brune Vec vec_func; 1447e4ed7901SPeter Brune 1448e4ed7901SPeter Brune PetscFunctionBegin; 1449e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1450e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1451e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1452e4ed7901SPeter Brune ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 1453e4ed7901SPeter Brune ierr = VecCopy(f, vec_func);CHKERRQ(ierr); 1454217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1455e4ed7901SPeter Brune PetscFunctionReturn(0); 1456e4ed7901SPeter Brune } 1457e4ed7901SPeter Brune 1458e4ed7901SPeter Brune 1459e4ed7901SPeter Brune #undef __FUNCT__ 1460e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm" 1461e4ed7901SPeter Brune /*@C 1462e4ed7901SPeter Brune SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm 1463e4ed7901SPeter Brune at the initialization of the method. In some instances, the user has precomputed 1464e4ed7901SPeter Brune the function and its norm before calling SNESSolve. This function allows one to 1465e4ed7901SPeter Brune avoid a redundant call to SNESComputeFunction() and VecNorm() in that case. 1466e4ed7901SPeter Brune 1467e4ed7901SPeter Brune Logically Collective on SNES 1468e4ed7901SPeter Brune 1469e4ed7901SPeter Brune Input Parameters: 1470e4ed7901SPeter Brune + snes - the SNES context 1471e4ed7901SPeter Brune - fnorm - the norm of F as set by SNESSetInitialFunction() 1472e4ed7901SPeter Brune 1473e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1474e4ed7901SPeter Brune 1475e4ed7901SPeter Brune Level: developer 1476e4ed7901SPeter Brune 1477e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm 1478e4ed7901SPeter Brune 1479e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction() 1480e4ed7901SPeter Brune @*/ 1481e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm) 1482e4ed7901SPeter Brune { 1483e4ed7901SPeter Brune PetscFunctionBegin; 1484e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1485e4ed7901SPeter Brune snes->norm_init = fnorm; 1486e4ed7901SPeter Brune snes->norm_init_set = PETSC_TRUE; 1487e4ed7901SPeter Brune PetscFunctionReturn(0); 1488e4ed7901SPeter Brune } 1489e4ed7901SPeter Brune 1490e4ed7901SPeter Brune #undef __FUNCT__ 1491534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType" 1492534ebe21SPeter Brune /*@ 1493534ebe21SPeter Brune SNESSetNormType - Sets the SNESNormType used in covergence and monitoring 1494534ebe21SPeter Brune of the SNES method. 1495534ebe21SPeter Brune 1496534ebe21SPeter Brune Logically Collective on SNES 1497534ebe21SPeter Brune 1498534ebe21SPeter Brune Input Parameters: 1499534ebe21SPeter Brune + snes - the SNES context 1500534ebe21SPeter Brune - normtype - the type of the norm used 1501534ebe21SPeter Brune 1502534ebe21SPeter Brune Notes: 1503534ebe21SPeter Brune Only certain SNES methods support certain SNESNormTypes. Most require evaluation 1504534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1505534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1506534ebe21SPeter Brune (SNESGS) and the like do not require the norm of the function to be computed, and therfore 1507534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1508534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1509534ebe21SPeter Brune their solution. 1510534ebe21SPeter Brune 1511534ebe21SPeter Brune Level: developer 1512534ebe21SPeter Brune 1513534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1514534ebe21SPeter Brune 1515534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1516534ebe21SPeter Brune @*/ 1517534ebe21SPeter Brune PetscErrorCode SNESSetNormType(SNES snes, SNESNormType normtype) 1518534ebe21SPeter Brune { 1519534ebe21SPeter Brune PetscFunctionBegin; 1520534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1521534ebe21SPeter Brune snes->normtype = normtype; 1522534ebe21SPeter Brune PetscFunctionReturn(0); 1523534ebe21SPeter Brune } 1524534ebe21SPeter Brune 1525534ebe21SPeter Brune 1526534ebe21SPeter Brune #undef __FUNCT__ 1527534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType" 1528534ebe21SPeter Brune /*@ 1529534ebe21SPeter Brune SNESGetNormType - Gets the SNESNormType used in covergence and monitoring 1530534ebe21SPeter Brune of the SNES method. 1531534ebe21SPeter Brune 1532534ebe21SPeter Brune Logically Collective on SNES 1533534ebe21SPeter Brune 1534534ebe21SPeter Brune Input Parameters: 1535534ebe21SPeter Brune + snes - the SNES context 1536534ebe21SPeter Brune - normtype - the type of the norm used 1537534ebe21SPeter Brune 1538534ebe21SPeter Brune Level: advanced 1539534ebe21SPeter Brune 1540534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type 1541534ebe21SPeter Brune 1542534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType 1543534ebe21SPeter Brune @*/ 1544534ebe21SPeter Brune PetscErrorCode SNESGetNormType(SNES snes, SNESNormType *normtype) 1545534ebe21SPeter Brune { 1546534ebe21SPeter Brune PetscFunctionBegin; 1547534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1548534ebe21SPeter Brune *normtype = snes->normtype; 1549534ebe21SPeter Brune PetscFunctionReturn(0); 1550534ebe21SPeter Brune } 1551534ebe21SPeter Brune 1552534ebe21SPeter Brune #undef __FUNCT__ 1553646217ecSPeter Brune #define __FUNCT__ "SNESSetGS" 1554c79ef259SPeter Brune /*@C 1555c79ef259SPeter Brune SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for 1556c79ef259SPeter Brune use with composed nonlinear solvers. 1557c79ef259SPeter Brune 1558c79ef259SPeter Brune Input Parameters: 1559c79ef259SPeter Brune + snes - the SNES context 1560c79ef259SPeter Brune . gsfunc - function evaluation routine 1561c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 1562c79ef259SPeter Brune smoother evaluation routine (may be PETSC_NULL) 1563c79ef259SPeter Brune 1564c79ef259SPeter Brune Calling sequence of func: 1565c79ef259SPeter Brune $ func (SNES snes,Vec x,Vec b,void *ctx); 1566c79ef259SPeter Brune 1567c79ef259SPeter Brune + X - solution vector 1568c79ef259SPeter Brune . B - RHS vector 1569d28543b3SPeter Brune - ctx - optional user-defined Gauss-Seidel context 1570c79ef259SPeter Brune 1571c79ef259SPeter Brune Notes: 1572c79ef259SPeter Brune The GS routines are used by the composed nonlinear solver to generate 1573c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 1574c79ef259SPeter Brune 1575d28543b3SPeter Brune Level: intermediate 1576c79ef259SPeter Brune 1577d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel 1578c79ef259SPeter Brune 1579c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS() 1580c79ef259SPeter Brune @*/ 15816cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx) 15826cab3a1bSJed Brown { 15836cab3a1bSJed Brown PetscErrorCode ierr; 15846cab3a1bSJed Brown DM dm; 15856cab3a1bSJed Brown 1586646217ecSPeter Brune PetscFunctionBegin; 15876cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15886cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 15896cab3a1bSJed Brown ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr); 1590646217ecSPeter Brune PetscFunctionReturn(0); 1591646217ecSPeter Brune } 1592646217ecSPeter Brune 1593d25893d9SBarry Smith #undef __FUNCT__ 159489b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps" 159589b92e6fSPeter Brune /*@ 159689b92e6fSPeter Brune SNESSetGSSweeps - Sets the number of sweeps of GS to use. 159789b92e6fSPeter Brune 159889b92e6fSPeter Brune Input Parameters: 159989b92e6fSPeter Brune + snes - the SNES context 160089b92e6fSPeter Brune - sweeps - the number of sweeps of GS to perform. 160189b92e6fSPeter Brune 160289b92e6fSPeter Brune Level: intermediate 160389b92e6fSPeter Brune 160489b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 160589b92e6fSPeter Brune 160689b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps() 160789b92e6fSPeter Brune @*/ 160889b92e6fSPeter Brune 160989b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) { 161089b92e6fSPeter Brune PetscFunctionBegin; 161189b92e6fSPeter Brune snes->gssweeps = sweeps; 161289b92e6fSPeter Brune PetscFunctionReturn(0); 161389b92e6fSPeter Brune } 161489b92e6fSPeter Brune 161589b92e6fSPeter Brune 161689b92e6fSPeter Brune #undef __FUNCT__ 161789b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps" 161889b92e6fSPeter Brune /*@ 161989b92e6fSPeter Brune SNESGetGSSweeps - Gets the number of sweeps GS will use. 162089b92e6fSPeter Brune 162189b92e6fSPeter Brune Input Parameters: 162289b92e6fSPeter Brune . snes - the SNES context 162389b92e6fSPeter Brune 162489b92e6fSPeter Brune Output Parameters: 162589b92e6fSPeter Brune . sweeps - the number of sweeps of GS to perform. 162689b92e6fSPeter Brune 162789b92e6fSPeter Brune Level: intermediate 162889b92e6fSPeter Brune 162989b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel 163089b92e6fSPeter Brune 163189b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps() 163289b92e6fSPeter Brune @*/ 163389b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) { 163489b92e6fSPeter Brune PetscFunctionBegin; 163589b92e6fSPeter Brune *sweeps = snes->gssweeps; 163689b92e6fSPeter Brune PetscFunctionReturn(0); 163789b92e6fSPeter Brune } 163889b92e6fSPeter Brune 163989b92e6fSPeter Brune #undef __FUNCT__ 16408b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction" 16418b0a5094SBarry Smith PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 16428b0a5094SBarry Smith { 16438b0a5094SBarry Smith PetscErrorCode ierr; 1644e03ab78fSPeter Brune DM dm; 1645e03ab78fSPeter Brune SNESDM sdm; 16466cab3a1bSJed Brown 16478b0a5094SBarry Smith PetscFunctionBegin; 1648e03ab78fSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 1649e03ab78fSPeter Brune ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 16508b0a5094SBarry Smith /* A(x)*x - b(x) */ 1651e03ab78fSPeter Brune if (sdm->computepfunction) { 1652e03ab78fSPeter Brune ierr = (*sdm->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr); 1653e03ab78fSPeter Brune } else if (snes->dm) { 1654e03ab78fSPeter Brune ierr = DMComputeFunction(snes->dm,x,f);CHKERRQ(ierr); 1655e03ab78fSPeter Brune } else { 1656e03ab78fSPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard function."); 1657e03ab78fSPeter Brune } 1658e03ab78fSPeter Brune 1659e03ab78fSPeter Brune if (sdm->computepjacobian) { 1660e03ab78fSPeter Brune ierr = (*sdm->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,sdm->pctx);CHKERRQ(ierr); 1661e03ab78fSPeter Brune } else if (snes->dm) { 1662e03ab78fSPeter Brune ierr = DMComputeJacobian(snes->dm,x,snes->jacobian,snes->jacobian_pre,&snes->matstruct);CHKERRQ(ierr); 1663e03ab78fSPeter Brune } else { 1664e03ab78fSPeter Brune SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() or SNESSetDM() before SNESPicardComputeFunction to provide Picard matrix."); 1665e03ab78fSPeter Brune } 1666e03ab78fSPeter Brune 16678b0a5094SBarry Smith ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16688b0a5094SBarry Smith ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr); 16698b0a5094SBarry Smith ierr = VecScale(f,-1.0);CHKERRQ(ierr); 16708b0a5094SBarry Smith ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr); 16718b0a5094SBarry Smith PetscFunctionReturn(0); 16728b0a5094SBarry Smith } 16738b0a5094SBarry Smith 16748b0a5094SBarry Smith #undef __FUNCT__ 16758b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian" 16768b0a5094SBarry Smith PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx) 16778b0a5094SBarry Smith { 16788b0a5094SBarry Smith PetscFunctionBegin; 1679e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 16808b0a5094SBarry Smith *flag = snes->matstruct; 16818b0a5094SBarry Smith PetscFunctionReturn(0); 16828b0a5094SBarry Smith } 16838b0a5094SBarry Smith 16848b0a5094SBarry Smith #undef __FUNCT__ 16858b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard" 16868b0a5094SBarry Smith /*@C 16870d04baf8SBarry Smith SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization) 16888b0a5094SBarry Smith 16898b0a5094SBarry Smith Logically Collective on SNES 16908b0a5094SBarry Smith 16918b0a5094SBarry Smith Input Parameters: 16928b0a5094SBarry Smith + snes - the SNES context 16938b0a5094SBarry Smith . r - vector to store function value 16948b0a5094SBarry Smith . func - function evaluation routine 16958b0a5094SBarry 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) 16968b0a5094SBarry Smith . mat - matrix to store A 16978b0a5094SBarry Smith . mfunc - function to compute matrix value 16988b0a5094SBarry Smith - ctx - [optional] user-defined context for private data for the 16998b0a5094SBarry Smith function evaluation routine (may be PETSC_NULL) 17008b0a5094SBarry Smith 17018b0a5094SBarry Smith Calling sequence of func: 17028b0a5094SBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 17038b0a5094SBarry Smith 17048b0a5094SBarry Smith + f - function vector 17058b0a5094SBarry Smith - ctx - optional user-defined function context 17068b0a5094SBarry Smith 17078b0a5094SBarry Smith Calling sequence of mfunc: 17088b0a5094SBarry Smith $ mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx); 17098b0a5094SBarry Smith 17108b0a5094SBarry Smith + x - input vector 17118b0a5094SBarry 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(), 17128b0a5094SBarry Smith normally just pass mat in this location 17138b0a5094SBarry Smith . mat - form A(x) matrix 17148b0a5094SBarry Smith . flag - flag indicating information about the preconditioner matrix 17158b0a5094SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 17168b0a5094SBarry Smith - ctx - [optional] user-defined Jacobian context 17178b0a5094SBarry Smith 17188b0a5094SBarry Smith Notes: 17198b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 17208b0a5094SBarry Smith 17218b0a5094SBarry 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} 17228b0a5094SBarry 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. 17238b0a5094SBarry Smith 17248b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 17258b0a5094SBarry Smith 17260d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 17270d04baf8SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = b(x^n) 17288b0a5094SBarry Smith 17298b0a5094SBarry 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 17308b0a5094SBarry 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 17318b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 17328b0a5094SBarry Smith 17338b0a5094SBarry Smith Level: beginner 17348b0a5094SBarry Smith 17358b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function 17368b0a5094SBarry Smith 17370d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard() 17388b0a5094SBarry Smith @*/ 17398b0a5094SBarry 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) 17408b0a5094SBarry Smith { 17418b0a5094SBarry Smith PetscErrorCode ierr; 1742e03ab78fSPeter Brune DM dm; 1743e03ab78fSPeter Brune 17448b0a5094SBarry Smith PetscFunctionBegin; 17458b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1746e03ab78fSPeter Brune ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr); 1747e03ab78fSPeter Brune ierr = DMSNESSetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr); 17488b0a5094SBarry Smith ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr); 17498b0a5094SBarry Smith ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr); 17508b0a5094SBarry Smith PetscFunctionReturn(0); 17518b0a5094SBarry Smith } 17528b0a5094SBarry Smith 17537971a8bfSPeter Brune 17547971a8bfSPeter Brune #undef __FUNCT__ 17557971a8bfSPeter Brune #define __FUNCT__ "SNESGetPicard" 17567971a8bfSPeter Brune /*@C 17577971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 17587971a8bfSPeter Brune 17597971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 17607971a8bfSPeter Brune 17617971a8bfSPeter Brune Input Parameter: 17627971a8bfSPeter Brune . snes - the SNES context 17637971a8bfSPeter Brune 17647971a8bfSPeter Brune Output Parameter: 17657971a8bfSPeter Brune + r - the function (or PETSC_NULL) 17667971a8bfSPeter Brune . func - the function (or PETSC_NULL) 17677971a8bfSPeter Brune . jmat - the picard matrix (or PETSC_NULL) 17687971a8bfSPeter Brune . mat - the picard preconditioner matrix (or PETSC_NULL) 17697971a8bfSPeter Brune . mfunc - the function for matrix evaluation (or PETSC_NULL) 17707971a8bfSPeter Brune - ctx - the function context (or PETSC_NULL) 17717971a8bfSPeter Brune 17727971a8bfSPeter Brune Level: advanced 17737971a8bfSPeter Brune 17747971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function 17757971a8bfSPeter Brune 17767971a8bfSPeter Brune .seealso: SNESSetPicard, SNESGetFunction, SNESGetJacobian, SNESGetDM 17777971a8bfSPeter Brune @*/ 17787971a8bfSPeter 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) 17797971a8bfSPeter Brune { 17807971a8bfSPeter Brune PetscErrorCode ierr; 17817971a8bfSPeter Brune DM dm; 17827971a8bfSPeter Brune 17837971a8bfSPeter Brune PetscFunctionBegin; 17847971a8bfSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 17857971a8bfSPeter Brune ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 17867971a8bfSPeter Brune ierr = SNESGetJacobian(snes,jmat,mat,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 17877971a8bfSPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 17887971a8bfSPeter Brune ierr = DMSNESGetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr); 17897971a8bfSPeter Brune PetscFunctionReturn(0); 17907971a8bfSPeter Brune } 17917971a8bfSPeter Brune 17928b0a5094SBarry Smith #undef __FUNCT__ 1793d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess" 1794d25893d9SBarry Smith /*@C 1795d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 1796d25893d9SBarry Smith 1797d25893d9SBarry Smith Logically Collective on SNES 1798d25893d9SBarry Smith 1799d25893d9SBarry Smith Input Parameters: 1800d25893d9SBarry Smith + snes - the SNES context 1801d25893d9SBarry Smith . func - function evaluation routine 1802d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 1803d25893d9SBarry Smith function evaluation routine (may be PETSC_NULL) 1804d25893d9SBarry Smith 1805d25893d9SBarry Smith Calling sequence of func: 1806d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 1807d25893d9SBarry Smith 1808d25893d9SBarry Smith . f - function vector 1809d25893d9SBarry Smith - ctx - optional user-defined function context 1810d25893d9SBarry Smith 1811d25893d9SBarry Smith Level: intermediate 1812d25893d9SBarry Smith 1813d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function 1814d25893d9SBarry Smith 1815d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian() 1816d25893d9SBarry Smith @*/ 1817d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 1818d25893d9SBarry Smith { 1819d25893d9SBarry Smith PetscFunctionBegin; 1820d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1821d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 1822d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 1823d25893d9SBarry Smith PetscFunctionReturn(0); 1824d25893d9SBarry Smith } 1825d25893d9SBarry Smith 18263ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 18273ab0aad5SBarry Smith #undef __FUNCT__ 18281096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs" 18291096aae1SMatthew Knepley /*@C 18301096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 18311096aae1SMatthew Knepley it assumes a zero right hand side. 18321096aae1SMatthew Knepley 18333f9fe445SBarry Smith Logically Collective on SNES 18341096aae1SMatthew Knepley 18351096aae1SMatthew Knepley Input Parameter: 18361096aae1SMatthew Knepley . snes - the SNES context 18371096aae1SMatthew Knepley 18381096aae1SMatthew Knepley Output Parameter: 1839bc08b0f1SBarry Smith . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null 18401096aae1SMatthew Knepley 18411096aae1SMatthew Knepley Level: intermediate 18421096aae1SMatthew Knepley 18431096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side 18441096aae1SMatthew Knepley 184585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 18461096aae1SMatthew Knepley @*/ 18477087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 18481096aae1SMatthew Knepley { 18491096aae1SMatthew Knepley PetscFunctionBegin; 18500700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18511096aae1SMatthew Knepley PetscValidPointer(rhs,2); 185285385478SLisandro Dalcin *rhs = snes->vec_rhs; 18531096aae1SMatthew Knepley PetscFunctionReturn(0); 18541096aae1SMatthew Knepley } 18551096aae1SMatthew Knepley 18561096aae1SMatthew Knepley #undef __FUNCT__ 18574a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction" 18589b94acceSBarry Smith /*@ 185936851e7fSLois Curfman McInnes SNESComputeFunction - Calls the function that has been set with 18609b94acceSBarry Smith SNESSetFunction(). 18619b94acceSBarry Smith 1862c7afd0dbSLois Curfman McInnes Collective on SNES 1863c7afd0dbSLois Curfman McInnes 18649b94acceSBarry Smith Input Parameters: 1865c7afd0dbSLois Curfman McInnes + snes - the SNES context 1866c7afd0dbSLois Curfman McInnes - x - input vector 18679b94acceSBarry Smith 18689b94acceSBarry Smith Output Parameter: 18693638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 18709b94acceSBarry Smith 18711bffabb2SLois Curfman McInnes Notes: 187236851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 187336851e7fSLois Curfman McInnes implementations, so most users would not generally call this routine 187436851e7fSLois Curfman McInnes themselves. 187536851e7fSLois Curfman McInnes 187636851e7fSLois Curfman McInnes Level: developer 187736851e7fSLois Curfman McInnes 18789b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function 18799b94acceSBarry Smith 1880a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction() 18819b94acceSBarry Smith @*/ 18827087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 18839b94acceSBarry Smith { 1884dfbe8321SBarry Smith PetscErrorCode ierr; 18856cab3a1bSJed Brown DM dm; 18866cab3a1bSJed Brown SNESDM sdm; 18879b94acceSBarry Smith 18883a40ed3dSBarry Smith PetscFunctionBegin; 18890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 18900700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 18910700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 1892c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 1893c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 18944ec14c9cSBarry Smith VecValidValues(x,2,PETSC_TRUE); 1895184914b5SBarry Smith 18966cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 18976cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 1898d5ba7fb7SMatthew Knepley ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 18996cab3a1bSJed Brown if (sdm->computefunction) { 1900d64ed03dSBarry Smith PetscStackPush("SNES user function"); 19016cab3a1bSJed Brown ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr); 1902d64ed03dSBarry Smith PetscStackPop; 190373250ac0SBarry Smith } else if (snes->dm) { 1904644e2e5bSBarry Smith ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr); 1905c90fad12SPeter Brune } else if (snes->vec_rhs) { 1906c90fad12SPeter Brune ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr); 1907644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 190885385478SLisandro Dalcin if (snes->vec_rhs) { 190985385478SLisandro Dalcin ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr); 19103ab0aad5SBarry Smith } 1911ae3c334cSLois Curfman McInnes snes->nfuncs++; 1912d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr); 19134ec14c9cSBarry Smith VecValidValues(y,3,PETSC_FALSE); 19143a40ed3dSBarry Smith PetscFunctionReturn(0); 19159b94acceSBarry Smith } 19169b94acceSBarry Smith 19174a2ae208SSatish Balay #undef __FUNCT__ 1918646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS" 1919c79ef259SPeter Brune /*@ 1920c79ef259SPeter Brune SNESComputeGS - Calls the Gauss-Seidel function that has been set with 1921c79ef259SPeter Brune SNESSetGS(). 1922c79ef259SPeter Brune 1923c79ef259SPeter Brune Collective on SNES 1924c79ef259SPeter Brune 1925c79ef259SPeter Brune Input Parameters: 1926c79ef259SPeter Brune + snes - the SNES context 1927c79ef259SPeter Brune . x - input vector 1928c79ef259SPeter Brune - b - rhs vector 1929c79ef259SPeter Brune 1930c79ef259SPeter Brune Output Parameter: 1931c79ef259SPeter Brune . x - new solution vector 1932c79ef259SPeter Brune 1933c79ef259SPeter Brune Notes: 1934c79ef259SPeter Brune SNESComputeGS() is typically used within composed nonlinear solver 1935c79ef259SPeter Brune implementations, so most users would not generally call this routine 1936c79ef259SPeter Brune themselves. 1937c79ef259SPeter Brune 1938c79ef259SPeter Brune Level: developer 1939c79ef259SPeter Brune 1940c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function 1941c79ef259SPeter Brune 1942c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction() 1943c79ef259SPeter Brune @*/ 1944646217ecSPeter Brune PetscErrorCode SNESComputeGS(SNES snes,Vec b,Vec x) 1945646217ecSPeter Brune { 1946646217ecSPeter Brune PetscErrorCode ierr; 194789b92e6fSPeter Brune PetscInt i; 19486cab3a1bSJed Brown DM dm; 19496cab3a1bSJed Brown SNESDM sdm; 1950646217ecSPeter Brune 1951646217ecSPeter Brune PetscFunctionBegin; 1952646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1953646217ecSPeter Brune PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1954646217ecSPeter Brune if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3); 1955646217ecSPeter Brune PetscCheckSameComm(snes,1,x,2); 1956646217ecSPeter Brune if(b) PetscCheckSameComm(snes,1,b,3); 19574ec14c9cSBarry Smith if (b) VecValidValues(b,2,PETSC_TRUE); 1958701cf23dSPeter Brune ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 19596cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 19606cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 19616cab3a1bSJed Brown if (sdm->computegs) { 196289b92e6fSPeter Brune for (i = 0; i < snes->gssweeps; i++) { 1963646217ecSPeter Brune PetscStackPush("SNES user GS"); 19646cab3a1bSJed Brown ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr); 1965646217ecSPeter Brune PetscStackPop; 196689b92e6fSPeter Brune } 1967646217ecSPeter Brune } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve()."); 1968701cf23dSPeter Brune ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr); 19694ec14c9cSBarry Smith VecValidValues(x,3,PETSC_FALSE); 1970646217ecSPeter Brune PetscFunctionReturn(0); 1971646217ecSPeter Brune } 1972646217ecSPeter Brune 1973646217ecSPeter Brune 1974646217ecSPeter Brune #undef __FUNCT__ 19754a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian" 197662fef451SLois Curfman McInnes /*@ 197762fef451SLois Curfman McInnes SNESComputeJacobian - Computes the Jacobian matrix that has been 197862fef451SLois Curfman McInnes set with SNESSetJacobian(). 197962fef451SLois Curfman McInnes 1980c7afd0dbSLois Curfman McInnes Collective on SNES and Mat 1981c7afd0dbSLois Curfman McInnes 198262fef451SLois Curfman McInnes Input Parameters: 1983c7afd0dbSLois Curfman McInnes + snes - the SNES context 1984c7afd0dbSLois Curfman McInnes - x - input vector 198562fef451SLois Curfman McInnes 198662fef451SLois Curfman McInnes Output Parameters: 1987c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 198862fef451SLois Curfman McInnes . B - optional preconditioning matrix 19892b668275SBarry Smith - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER) 1990fee21e36SBarry Smith 1991e35cf81dSBarry Smith Options Database Keys: 1992e35cf81dSBarry Smith + -snes_lag_preconditioner <lag> 1993693365a8SJed Brown . -snes_lag_jacobian <lag> 1994693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 1995693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 1996693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 19974c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 1998c01495d3SJed Brown . -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference 1999c01495d3SJed Brown . -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences 2000c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2001c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2002c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 20034c30e9fbSJed Brown . -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences 2004c01495d3SJed Brown - -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences 2005c01495d3SJed Brown 2006e35cf81dSBarry Smith 200762fef451SLois Curfman McInnes Notes: 200862fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 200962fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 201062fef451SLois Curfman McInnes 201194b7f48cSBarry Smith See KSPSetOperators() for important information about setting the 2012dc5a77f8SLois Curfman McInnes flag parameter. 201362fef451SLois Curfman McInnes 201436851e7fSLois Curfman McInnes Level: developer 201536851e7fSLois Curfman McInnes 201662fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix 201762fef451SLois Curfman McInnes 2018e35cf81dSBarry Smith .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian() 201962fef451SLois Curfman McInnes @*/ 20207087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg) 20219b94acceSBarry Smith { 2022dfbe8321SBarry Smith PetscErrorCode ierr; 2023ace3abfcSBarry Smith PetscBool flag; 20246cab3a1bSJed Brown DM dm; 20256cab3a1bSJed Brown SNESDM sdm; 20263a40ed3dSBarry Smith 20273a40ed3dSBarry Smith PetscFunctionBegin; 20280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 20290700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 20304482741eSBarry Smith PetscValidPointer(flg,5); 2031c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 20324ec14c9cSBarry Smith VecValidValues(X,2,PETSC_TRUE); 20336cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 20346cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 20356cab3a1bSJed Brown if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2036ebd3b9afSBarry Smith 2037ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2038ebd3b9afSBarry Smith 2039fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2040fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2041fe3ffe1eSBarry Smith ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr); 2042fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 2043e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 2044e35cf81dSBarry Smith ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr); 2045251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 2046ebd3b9afSBarry Smith if (flag) { 2047ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2048ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2049ebd3b9afSBarry Smith } 2050e35cf81dSBarry Smith PetscFunctionReturn(0); 2051e35cf81dSBarry Smith } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) { 2052e35cf81dSBarry Smith *flg = SAME_PRECONDITIONER; 2053e35cf81dSBarry Smith ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr); 2054251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr); 2055ebd3b9afSBarry Smith if (flag) { 2056ebd3b9afSBarry Smith ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2057ebd3b9afSBarry Smith ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2058ebd3b9afSBarry Smith } 2059e35cf81dSBarry Smith PetscFunctionReturn(0); 2060e35cf81dSBarry Smith } 2061e35cf81dSBarry Smith 2062c4fc05e7SBarry Smith *flg = DIFFERENT_NONZERO_PATTERN; 2063e35cf81dSBarry Smith ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 2064d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 20656cab3a1bSJed Brown ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr); 2066d64ed03dSBarry Smith PetscStackPop; 2067d5ba7fb7SMatthew Knepley ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr); 2068a8054027SBarry Smith 20693b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 20703b4f5425SBarry Smith ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr); 20713b4f5425SBarry Smith snes->lagpreconditioner = -1; 20723b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 2073a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2074a8054027SBarry Smith ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr); 2075a8054027SBarry Smith } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) { 2076a8054027SBarry Smith *flg = SAME_PRECONDITIONER; 2077a8054027SBarry Smith ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr); 2078a8054027SBarry Smith } 2079a8054027SBarry Smith 20806d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 20810700a824SBarry Smith /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3); 20820700a824SBarry Smith PetscValidHeaderSpecific(*B,MAT_CLASSID,4); */ 2083693365a8SJed Brown { 2084693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 2085693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr); 2086693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 2087693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 2088693365a8SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr); 2089693365a8SJed Brown if (flag || flag_draw || flag_contour) { 2090693365a8SJed Brown Mat Bexp_mine = PETSC_NULL,Bexp,FDexp; 2091693365a8SJed Brown MatStructure mstruct; 2092693365a8SJed Brown PetscViewer vdraw,vstdout; 20936b3a5b13SJed Brown PetscBool flg; 2094693365a8SJed Brown if (flag_operator) { 2095693365a8SJed Brown ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr); 2096693365a8SJed Brown Bexp = Bexp_mine; 2097693365a8SJed Brown } else { 2098693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 2099251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr); 2100693365a8SJed Brown if (flg) Bexp = *B; 2101693365a8SJed Brown else { 2102693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 2103693365a8SJed Brown ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr); 2104693365a8SJed Brown Bexp = Bexp_mine; 2105693365a8SJed Brown } 2106693365a8SJed Brown } 2107693365a8SJed Brown ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr); 2108693365a8SJed Brown ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr); 2109693365a8SJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 2110693365a8SJed Brown if (flag_draw || flag_contour) { 2111693365a8SJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 2112693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 2113693365a8SJed Brown } else vdraw = PETSC_NULL; 2114693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr); 2115693365a8SJed Brown if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);} 2116693365a8SJed Brown if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);} 2117693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr); 2118693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2119693365a8SJed Brown if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);} 2120693365a8SJed Brown ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2121693365a8SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr); 2122693365a8SJed Brown if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);} 2123693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 2124693365a8SJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 2125693365a8SJed Brown ierr = MatView(FDexp,vdraw);CHKERRQ(ierr); 2126693365a8SJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 2127693365a8SJed Brown } 2128693365a8SJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 2129693365a8SJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 2130693365a8SJed Brown ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr); 2131693365a8SJed Brown ierr = MatDestroy(&FDexp);CHKERRQ(ierr); 2132693365a8SJed Brown } 2133693365a8SJed Brown } 21344c30e9fbSJed Brown { 21356719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 21366719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 21374c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr); 21386719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr); 21394c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr); 21404c30e9fbSJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr); 21416719d8e4SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr); 21426719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr); 21436719d8e4SJed Brown ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr); 21446719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 21454c30e9fbSJed Brown Mat Bfd; 21464c30e9fbSJed Brown MatStructure mstruct; 21474c30e9fbSJed Brown PetscViewer vdraw,vstdout; 21484c30e9fbSJed Brown ISColoring iscoloring; 21494c30e9fbSJed Brown MatFDColoring matfdcoloring; 21504c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 21514c30e9fbSJed Brown void *funcctx; 21526719d8e4SJed Brown PetscReal norm1,norm2,normmax; 21534c30e9fbSJed Brown 21544c30e9fbSJed Brown ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr); 21554c30e9fbSJed Brown ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr); 21564c30e9fbSJed Brown ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr); 21574c30e9fbSJed Brown ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr); 21584c30e9fbSJed Brown 21594c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 21604c30e9fbSJed Brown ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr); 21614c30e9fbSJed Brown ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr); 21624c30e9fbSJed Brown ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr); 21634c30e9fbSJed Brown ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr); 21644c30e9fbSJed Brown ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr); 21654c30e9fbSJed Brown ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr); 21664c30e9fbSJed Brown ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr); 21674c30e9fbSJed Brown 21684c30e9fbSJed Brown ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr); 21694c30e9fbSJed Brown if (flag_draw || flag_contour) { 21704c30e9fbSJed Brown ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr); 21714c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);} 21724c30e9fbSJed Brown } else vdraw = PETSC_NULL; 21734c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr); 21746719d8e4SJed Brown if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);} 21754c30e9fbSJed Brown if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);} 21764c30e9fbSJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr); 21776719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21784c30e9fbSJed Brown if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);} 21794c30e9fbSJed Brown ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 21804c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr); 21816719d8e4SJed Brown ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr); 21824c30e9fbSJed Brown ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr); 21836719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr); 21846719d8e4SJed Brown if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);} 21854c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 21864c30e9fbSJed Brown ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr); 21874c30e9fbSJed Brown ierr = MatView(Bfd,vdraw);CHKERRQ(ierr); 21884c30e9fbSJed Brown ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr); 21894c30e9fbSJed Brown } 21904c30e9fbSJed Brown if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);} 21916719d8e4SJed Brown 21926719d8e4SJed Brown if (flag_threshold) { 21936719d8e4SJed Brown PetscInt bs,rstart,rend,i; 21946719d8e4SJed Brown ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr); 21956719d8e4SJed Brown ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr); 21966719d8e4SJed Brown for (i=rstart; i<rend; i++) { 21976719d8e4SJed Brown const PetscScalar *ba,*ca; 21986719d8e4SJed Brown const PetscInt *bj,*cj; 21996719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 22006719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 22016719d8e4SJed Brown ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 22026719d8e4SJed Brown ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 22036719d8e4SJed Brown if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 22046719d8e4SJed Brown for (j=0; j<bn; j++) { 22056719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 22066719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 22076719d8e4SJed Brown maxentrycol = bj[j]; 22086719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 22096719d8e4SJed Brown } 22106719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 22116719d8e4SJed Brown maxdiffcol = bj[j]; 22126719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 22136719d8e4SJed Brown } 22146719d8e4SJed Brown if (rdiff > maxrdiff) { 22156719d8e4SJed Brown maxrdiffcol = bj[j]; 22166719d8e4SJed Brown maxrdiff = rdiff; 22176719d8e4SJed Brown } 22186719d8e4SJed Brown } 22196719d8e4SJed Brown if (maxrdiff > 1) { 22206719d8e4SJed 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); 22216719d8e4SJed Brown for (j=0; j<bn; j++) { 22226719d8e4SJed Brown PetscReal rdiff; 22236719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 22246719d8e4SJed Brown if (rdiff > 1) { 22256719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr); 22266719d8e4SJed Brown } 22276719d8e4SJed Brown } 22286719d8e4SJed Brown ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr); 22296719d8e4SJed Brown } 22306719d8e4SJed Brown ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr); 22316719d8e4SJed Brown ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr); 22326719d8e4SJed Brown } 22336719d8e4SJed Brown } 22344c30e9fbSJed Brown ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr); 22354c30e9fbSJed Brown ierr = MatDestroy(&Bfd);CHKERRQ(ierr); 22364c30e9fbSJed Brown } 22374c30e9fbSJed Brown } 22383a40ed3dSBarry Smith PetscFunctionReturn(0); 22399b94acceSBarry Smith } 22409b94acceSBarry Smith 22414a2ae208SSatish Balay #undef __FUNCT__ 22424a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian" 22439b94acceSBarry Smith /*@C 22449b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2245044dda88SLois Curfman McInnes location to store the matrix. 22469b94acceSBarry Smith 22473f9fe445SBarry Smith Logically Collective on SNES and Mat 2248c7afd0dbSLois Curfman McInnes 22499b94acceSBarry Smith Input Parameters: 2250c7afd0dbSLois Curfman McInnes + snes - the SNES context 22519b94acceSBarry Smith . A - Jacobian matrix 22529b94acceSBarry Smith . B - preconditioner matrix (usually same as the Jacobian) 2253efd51863SBarry Smith . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value) 2254c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 2255efd51863SBarry Smith Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value) 22569b94acceSBarry Smith 22579b94acceSBarry Smith Calling sequence of func: 22588d76a1e5SLois Curfman McInnes $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx); 22599b94acceSBarry Smith 2260c7afd0dbSLois Curfman McInnes + x - input vector 22619b94acceSBarry Smith . A - Jacobian matrix 22629b94acceSBarry Smith . B - preconditioner matrix, usually the same as A 2263ac21db08SLois Curfman McInnes . flag - flag indicating information about the preconditioner matrix 22642b668275SBarry Smith structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER 2265c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined Jacobian context 22669b94acceSBarry Smith 22679b94acceSBarry Smith Notes: 226894b7f48cSBarry Smith See KSPSetOperators() for important information about setting the flag 22692cd2dfdcSLois Curfman McInnes output parameter in the routine func(). Be sure to read this information! 2270ac21db08SLois Curfman McInnes 2271ac21db08SLois Curfman McInnes The routine func() takes Mat * as the matrix arguments rather than Mat. 22729b94acceSBarry Smith This allows the Jacobian evaluation routine to replace A and/or B with a 22739b94acceSBarry Smith completely new new matrix structure (not just different matrix elements) 22749b94acceSBarry Smith when appropriate, for instance, if the nonzero structure is changing 22759b94acceSBarry Smith throughout the global iterations. 22769b94acceSBarry Smith 227716913363SBarry Smith If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on 227816913363SBarry Smith each matrix. 227916913363SBarry Smith 2280a8a26c1eSJed Brown If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument 2281a8a26c1eSJed Brown must be a MatFDColoring. 2282a8a26c1eSJed Brown 2283c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2284c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2285c3cc8fd1SJed Brown 228636851e7fSLois Curfman McInnes Level: beginner 228736851e7fSLois Curfman McInnes 22889b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix 22899b94acceSBarry Smith 22903ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure 22919b94acceSBarry Smith @*/ 22927087cfbeSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx) 22939b94acceSBarry Smith { 2294dfbe8321SBarry Smith PetscErrorCode ierr; 22956cab3a1bSJed Brown DM dm; 22963a7fca6bSBarry Smith 22973a40ed3dSBarry Smith PetscFunctionBegin; 22980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22990700a824SBarry Smith if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2); 23000700a824SBarry Smith if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3); 2301c9780b6fSBarry Smith if (A) PetscCheckSameComm(snes,1,A,2); 230206975374SJed Brown if (B) PetscCheckSameComm(snes,1,B,3); 23036cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23046cab3a1bSJed Brown ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr); 23053a7fca6bSBarry Smith if (A) { 23067dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 23076bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 23089b94acceSBarry Smith snes->jacobian = A; 23093a7fca6bSBarry Smith } 23103a7fca6bSBarry Smith if (B) { 23117dcf0eaaSdalcinl ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr); 23126bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 23139b94acceSBarry Smith snes->jacobian_pre = B; 23143a7fca6bSBarry Smith } 23153a40ed3dSBarry Smith PetscFunctionReturn(0); 23169b94acceSBarry Smith } 231762fef451SLois Curfman McInnes 23184a2ae208SSatish Balay #undef __FUNCT__ 23194a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian" 2320c2aafc4cSSatish Balay /*@C 2321b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 2322b4fd4287SBarry Smith provided context for evaluating the Jacobian. 2323b4fd4287SBarry Smith 2324c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 2325c7afd0dbSLois Curfman McInnes 2326b4fd4287SBarry Smith Input Parameter: 2327b4fd4287SBarry Smith . snes - the nonlinear solver context 2328b4fd4287SBarry Smith 2329b4fd4287SBarry Smith Output Parameters: 2330c7afd0dbSLois Curfman McInnes + A - location to stash Jacobian matrix (or PETSC_NULL) 2331b4fd4287SBarry Smith . B - location to stash preconditioner matrix (or PETSC_NULL) 233270e92668SMatthew Knepley . func - location to put Jacobian function (or PETSC_NULL) 233370e92668SMatthew Knepley - ctx - location to stash Jacobian ctx (or PETSC_NULL) 2334fee21e36SBarry Smith 233536851e7fSLois Curfman McInnes Level: advanced 233636851e7fSLois Curfman McInnes 2337b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian() 2338b4fd4287SBarry Smith @*/ 23397087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx) 2340b4fd4287SBarry Smith { 23416cab3a1bSJed Brown PetscErrorCode ierr; 23426cab3a1bSJed Brown DM dm; 23436cab3a1bSJed Brown SNESDM sdm; 23446cab3a1bSJed Brown 23453a40ed3dSBarry Smith PetscFunctionBegin; 23460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2347b4fd4287SBarry Smith if (A) *A = snes->jacobian; 2348b4fd4287SBarry Smith if (B) *B = snes->jacobian_pre; 23496cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 23506cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 23516cab3a1bSJed Brown if (func) *func = sdm->computejacobian; 23526cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 23533a40ed3dSBarry Smith PetscFunctionReturn(0); 2354b4fd4287SBarry Smith } 2355b4fd4287SBarry Smith 23569b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */ 23579b94acceSBarry Smith 23584a2ae208SSatish Balay #undef __FUNCT__ 23594a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp" 23609b94acceSBarry Smith /*@ 23619b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 2362272ac6f2SLois Curfman McInnes of a nonlinear solver. 23639b94acceSBarry Smith 2364fee21e36SBarry Smith Collective on SNES 2365fee21e36SBarry Smith 2366c7afd0dbSLois Curfman McInnes Input Parameters: 236770e92668SMatthew Knepley . snes - the SNES context 2368c7afd0dbSLois Curfman McInnes 2369272ac6f2SLois Curfman McInnes Notes: 2370272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 2371272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 2372272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 2373272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 2374272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 2375272ac6f2SLois Curfman McInnes 237636851e7fSLois Curfman McInnes Level: advanced 237736851e7fSLois Curfman McInnes 23789b94acceSBarry Smith .keywords: SNES, nonlinear, setup 23799b94acceSBarry Smith 23809b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy() 23819b94acceSBarry Smith @*/ 23827087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 23839b94acceSBarry Smith { 2384dfbe8321SBarry Smith PetscErrorCode ierr; 23856cab3a1bSJed Brown DM dm; 23866cab3a1bSJed Brown SNESDM sdm; 23876e2a1849SPeter Brune SNESLineSearch linesearch; 23886e2a1849SPeter Brune SNESLineSearch pclinesearch; 23896e2a1849SPeter Brune void *lsprectx,*lspostctx; 23906e2a1849SPeter Brune SNESLineSearchPreCheckFunc lsprefunc; 23916e2a1849SPeter Brune SNESLineSearchPostCheckFunc lspostfunc; 23926e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 23936e2a1849SPeter Brune Vec f,fpc; 23946e2a1849SPeter Brune void *funcctx; 23956e2a1849SPeter Brune PetscErrorCode (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); 23966e2a1849SPeter Brune void *jacctx; 23976e2a1849SPeter Brune Mat A,B; 23983a40ed3dSBarry Smith 23993a40ed3dSBarry Smith PetscFunctionBegin; 24000700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 24014dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 24029b94acceSBarry Smith 24037adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 240485385478SLisandro Dalcin ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr); 240585385478SLisandro Dalcin } 240685385478SLisandro Dalcin 2407a63bb30eSJed Brown ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); 240817186662SBarry Smith if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 240958c9b817SLisandro Dalcin if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 241058c9b817SLisandro Dalcin 241158c9b817SLisandro Dalcin if (!snes->vec_sol_update /* && snes->vec_sol */) { 241258c9b817SLisandro Dalcin ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr); 241358c9b817SLisandro Dalcin ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr); 241458c9b817SLisandro Dalcin } 241558c9b817SLisandro Dalcin 24166cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 24176cab3a1bSJed Brown ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */ 24186cab3a1bSJed Brown ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr); 24196cab3a1bSJed Brown if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc"); 24206cab3a1bSJed Brown if (!snes->vec_func) { 24216cab3a1bSJed Brown ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr); 2422214df951SJed Brown } 2423efd51863SBarry Smith 2424b710008aSBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);} 2425b710008aSBarry Smith 2426f1c6b773SPeter Brune if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);} 24279e764e56SPeter Brune 2428d25893d9SBarry Smith if (snes->ops->usercompute && !snes->user) { 2429d25893d9SBarry Smith ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr); 2430d25893d9SBarry Smith } 2431d25893d9SBarry Smith 24326e2a1849SPeter Brune if (snes->pc) { 24336e2a1849SPeter Brune /* copy the DM over */ 24346e2a1849SPeter Brune ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 24356e2a1849SPeter Brune ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr); 24366e2a1849SPeter Brune 24376e2a1849SPeter Brune /* copy the legacy SNES context not related to the DM over*/ 24386e2a1849SPeter Brune ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr); 24396e2a1849SPeter Brune ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr); 24406e2a1849SPeter Brune ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr); 24416e2a1849SPeter Brune ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr); 24426e2a1849SPeter Brune ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr); 24436e2a1849SPeter Brune ierr = VecDestroy(&fpc);CHKERRQ(ierr); 24446e2a1849SPeter Brune 24456e2a1849SPeter Brune /* copy the function pointers over */ 24466e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr); 24476e2a1849SPeter Brune 24486e2a1849SPeter Brune /* default to 1 iteration */ 2449140836e4SPeter Brune ierr = SNESSetTolerances(snes->pc, 0.0, 0.0, 0.0, 1, snes->pc->max_funcs);CHKERRQ(ierr); 24506e2a1849SPeter Brune ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr); 24516e2a1849SPeter Brune ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr); 24526e2a1849SPeter Brune 24536e2a1849SPeter Brune /* copy the line search context over */ 24546e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr); 24556e2a1849SPeter Brune ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr); 24566e2a1849SPeter Brune ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr); 24576e2a1849SPeter Brune ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr); 24586e2a1849SPeter Brune ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr); 24596e2a1849SPeter Brune ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr); 24606e2a1849SPeter Brune ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr); 24616e2a1849SPeter Brune } 24626e2a1849SPeter Brune 2463410397dcSLisandro Dalcin if (snes->ops->setup) { 2464410397dcSLisandro Dalcin ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr); 2465410397dcSLisandro Dalcin } 246658c9b817SLisandro Dalcin 24677aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 24683a40ed3dSBarry Smith PetscFunctionReturn(0); 24699b94acceSBarry Smith } 24709b94acceSBarry Smith 24714a2ae208SSatish Balay #undef __FUNCT__ 247237596af1SLisandro Dalcin #define __FUNCT__ "SNESReset" 247337596af1SLisandro Dalcin /*@ 247437596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 247537596af1SLisandro Dalcin 247637596af1SLisandro Dalcin Collective on SNES 247737596af1SLisandro Dalcin 247837596af1SLisandro Dalcin Input Parameter: 247937596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 248037596af1SLisandro Dalcin 2481d25893d9SBarry Smith Level: intermediate 2482d25893d9SBarry Smith 2483d25893d9SBarry Smith Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 248437596af1SLisandro Dalcin 248537596af1SLisandro Dalcin .keywords: SNES, destroy 248637596af1SLisandro Dalcin 248737596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve() 248837596af1SLisandro Dalcin @*/ 248937596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 249037596af1SLisandro Dalcin { 249137596af1SLisandro Dalcin PetscErrorCode ierr; 249237596af1SLisandro Dalcin 249337596af1SLisandro Dalcin PetscFunctionBegin; 249437596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2495d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 2496d25893d9SBarry Smith ierr = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr); 2497d25893d9SBarry Smith snes->user = PETSC_NULL; 2498d25893d9SBarry Smith } 24998a23116dSBarry Smith if (snes->pc) { 25008a23116dSBarry Smith ierr = SNESReset(snes->pc);CHKERRQ(ierr); 25018a23116dSBarry Smith } 25028a23116dSBarry Smith 250337596af1SLisandro Dalcin if (snes->ops->reset) { 250437596af1SLisandro Dalcin ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr); 250537596af1SLisandro Dalcin } 25069e764e56SPeter Brune if (snes->ksp) { 25079e764e56SPeter Brune ierr = KSPReset(snes->ksp);CHKERRQ(ierr); 25089e764e56SPeter Brune } 25099e764e56SPeter Brune 25109e764e56SPeter Brune if (snes->linesearch) { 2511f1c6b773SPeter Brune ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr); 25129e764e56SPeter Brune } 25139e764e56SPeter Brune 25146bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 25156bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 25166bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr); 25176bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr); 25186bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr); 25196bf464f9SBarry Smith ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr); 2520c41d97abSJed Brown ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr); 2521c41d97abSJed Brown ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr); 252237596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 252337596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 252437596af1SLisandro Dalcin PetscFunctionReturn(0); 252537596af1SLisandro Dalcin } 252637596af1SLisandro Dalcin 252737596af1SLisandro Dalcin #undef __FUNCT__ 25284a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy" 252952baeb72SSatish Balay /*@ 25309b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 25319b94acceSBarry Smith with SNESCreate(). 25329b94acceSBarry Smith 2533c7afd0dbSLois Curfman McInnes Collective on SNES 2534c7afd0dbSLois Curfman McInnes 25359b94acceSBarry Smith Input Parameter: 25369b94acceSBarry Smith . snes - the SNES context 25379b94acceSBarry Smith 253836851e7fSLois Curfman McInnes Level: beginner 253936851e7fSLois Curfman McInnes 25409b94acceSBarry Smith .keywords: SNES, nonlinear, destroy 25419b94acceSBarry Smith 254263a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve() 25439b94acceSBarry Smith @*/ 25446bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 25459b94acceSBarry Smith { 25466849ba73SBarry Smith PetscErrorCode ierr; 25473a40ed3dSBarry Smith 25483a40ed3dSBarry Smith PetscFunctionBegin; 25496bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 25506bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 25516bf464f9SBarry Smith if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);} 2552d4bb536fSBarry Smith 25536bf464f9SBarry Smith ierr = SNESReset((*snes));CHKERRQ(ierr); 25548a23116dSBarry Smith ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr); 25556b8b9a38SLisandro Dalcin 2556be0abb6dSBarry Smith /* if memory was published with AMS then destroy it */ 25576bf464f9SBarry Smith ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr); 25586bf464f9SBarry Smith if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);} 25596d4c513bSLisandro Dalcin 25606bf464f9SBarry Smith ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr); 25616bf464f9SBarry Smith ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr); 2562f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr); 25636b8b9a38SLisandro Dalcin 25646bf464f9SBarry Smith ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr); 25656bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 25666bf464f9SBarry Smith ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr); 25676b8b9a38SLisandro Dalcin } 25686bf464f9SBarry Smith if ((*snes)->conv_malloc) { 25696bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr); 25706bf464f9SBarry Smith ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr); 257158c9b817SLisandro Dalcin } 25726bf464f9SBarry Smith ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr); 2573a79aaaedSSatish Balay ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr); 25743a40ed3dSBarry Smith PetscFunctionReturn(0); 25759b94acceSBarry Smith } 25769b94acceSBarry Smith 25779b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 25789b94acceSBarry Smith 25794a2ae208SSatish Balay #undef __FUNCT__ 2580a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner" 2581a8054027SBarry Smith /*@ 2582a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 2583a8054027SBarry Smith 25843f9fe445SBarry Smith Logically Collective on SNES 2585a8054027SBarry Smith 2586a8054027SBarry Smith Input Parameters: 2587a8054027SBarry Smith + snes - the SNES context 2588a8054027SBarry 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 25893b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2590a8054027SBarry Smith 2591a8054027SBarry Smith Options Database Keys: 2592a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2593a8054027SBarry Smith 2594a8054027SBarry Smith Notes: 2595a8054027SBarry Smith The default is 1 2596a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2597a8054027SBarry Smith If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use 2598a8054027SBarry Smith 2599a8054027SBarry Smith Level: intermediate 2600a8054027SBarry Smith 2601a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2602a8054027SBarry Smith 2603e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2604a8054027SBarry Smith 2605a8054027SBarry Smith @*/ 26067087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 2607a8054027SBarry Smith { 2608a8054027SBarry Smith PetscFunctionBegin; 26090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2610e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2611e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2612c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2613a8054027SBarry Smith snes->lagpreconditioner = lag; 2614a8054027SBarry Smith PetscFunctionReturn(0); 2615a8054027SBarry Smith } 2616a8054027SBarry Smith 2617a8054027SBarry Smith #undef __FUNCT__ 2618efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence" 2619efd51863SBarry Smith /*@ 2620efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 2621efd51863SBarry Smith 2622efd51863SBarry Smith Logically Collective on SNES 2623efd51863SBarry Smith 2624efd51863SBarry Smith Input Parameters: 2625efd51863SBarry Smith + snes - the SNES context 2626efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 2627efd51863SBarry Smith 2628efd51863SBarry Smith Options Database Keys: 2629efd51863SBarry Smith . -snes_grid_sequence <steps> 2630efd51863SBarry Smith 2631efd51863SBarry Smith Level: intermediate 2632efd51863SBarry Smith 2633c0df2a02SJed Brown Notes: 2634c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 2635c0df2a02SJed Brown 2636efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2637efd51863SBarry Smith 2638efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian() 2639efd51863SBarry Smith 2640efd51863SBarry Smith @*/ 2641efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 2642efd51863SBarry Smith { 2643efd51863SBarry Smith PetscFunctionBegin; 2644efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2645efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 2646efd51863SBarry Smith snes->gridsequence = steps; 2647efd51863SBarry Smith PetscFunctionReturn(0); 2648efd51863SBarry Smith } 2649efd51863SBarry Smith 2650efd51863SBarry Smith #undef __FUNCT__ 2651a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner" 2652a8054027SBarry Smith /*@ 2653a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 2654a8054027SBarry Smith 26553f9fe445SBarry Smith Not Collective 2656a8054027SBarry Smith 2657a8054027SBarry Smith Input Parameter: 2658a8054027SBarry Smith . snes - the SNES context 2659a8054027SBarry Smith 2660a8054027SBarry Smith Output Parameter: 2661a8054027SBarry 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 26623b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 2663a8054027SBarry Smith 2664a8054027SBarry Smith Options Database Keys: 2665a8054027SBarry Smith . -snes_lag_preconditioner <lag> 2666a8054027SBarry Smith 2667a8054027SBarry Smith Notes: 2668a8054027SBarry Smith The default is 1 2669a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2670a8054027SBarry Smith 2671a8054027SBarry Smith Level: intermediate 2672a8054027SBarry Smith 2673a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2674a8054027SBarry Smith 2675a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner() 2676a8054027SBarry Smith 2677a8054027SBarry Smith @*/ 26787087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 2679a8054027SBarry Smith { 2680a8054027SBarry Smith PetscFunctionBegin; 26810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2682a8054027SBarry Smith *lag = snes->lagpreconditioner; 2683a8054027SBarry Smith PetscFunctionReturn(0); 2684a8054027SBarry Smith } 2685a8054027SBarry Smith 2686a8054027SBarry Smith #undef __FUNCT__ 2687e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian" 2688e35cf81dSBarry Smith /*@ 2689e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 2690e35cf81dSBarry Smith often the preconditioner is rebuilt. 2691e35cf81dSBarry Smith 26923f9fe445SBarry Smith Logically Collective on SNES 2693e35cf81dSBarry Smith 2694e35cf81dSBarry Smith Input Parameters: 2695e35cf81dSBarry Smith + snes - the SNES context 2696e35cf81dSBarry 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 2697fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 2698e35cf81dSBarry Smith 2699e35cf81dSBarry Smith Options Database Keys: 2700e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2701e35cf81dSBarry Smith 2702e35cf81dSBarry Smith Notes: 2703e35cf81dSBarry Smith The default is 1 2704e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2705fe3ffe1eSBarry 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 2706fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 2707e35cf81dSBarry Smith 2708e35cf81dSBarry Smith Level: intermediate 2709e35cf81dSBarry Smith 2710e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2711e35cf81dSBarry Smith 2712e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian() 2713e35cf81dSBarry Smith 2714e35cf81dSBarry Smith @*/ 27157087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 2716e35cf81dSBarry Smith { 2717e35cf81dSBarry Smith PetscFunctionBegin; 27180700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2719e32f2f54SBarry Smith if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 2720e32f2f54SBarry Smith if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 2721c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 2722e35cf81dSBarry Smith snes->lagjacobian = lag; 2723e35cf81dSBarry Smith PetscFunctionReturn(0); 2724e35cf81dSBarry Smith } 2725e35cf81dSBarry Smith 2726e35cf81dSBarry Smith #undef __FUNCT__ 2727e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian" 2728e35cf81dSBarry Smith /*@ 2729e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 2730e35cf81dSBarry Smith 27313f9fe445SBarry Smith Not Collective 2732e35cf81dSBarry Smith 2733e35cf81dSBarry Smith Input Parameter: 2734e35cf81dSBarry Smith . snes - the SNES context 2735e35cf81dSBarry Smith 2736e35cf81dSBarry Smith Output Parameter: 2737e35cf81dSBarry 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 2738e35cf81dSBarry Smith the Jacobian is built etc. 2739e35cf81dSBarry Smith 2740e35cf81dSBarry Smith Options Database Keys: 2741e35cf81dSBarry Smith . -snes_lag_jacobian <lag> 2742e35cf81dSBarry Smith 2743e35cf81dSBarry Smith Notes: 2744e35cf81dSBarry Smith The default is 1 2745e35cf81dSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 2746e35cf81dSBarry Smith 2747e35cf81dSBarry Smith Level: intermediate 2748e35cf81dSBarry Smith 2749e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances 2750e35cf81dSBarry Smith 2751e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner() 2752e35cf81dSBarry Smith 2753e35cf81dSBarry Smith @*/ 27547087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 2755e35cf81dSBarry Smith { 2756e35cf81dSBarry Smith PetscFunctionBegin; 27570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2758e35cf81dSBarry Smith *lag = snes->lagjacobian; 2759e35cf81dSBarry Smith PetscFunctionReturn(0); 2760e35cf81dSBarry Smith } 2761e35cf81dSBarry Smith 2762e35cf81dSBarry Smith #undef __FUNCT__ 27634a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances" 27649b94acceSBarry Smith /*@ 2765d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 27669b94acceSBarry Smith 27673f9fe445SBarry Smith Logically Collective on SNES 2768c7afd0dbSLois Curfman McInnes 27699b94acceSBarry Smith Input Parameters: 2770c7afd0dbSLois Curfman McInnes + snes - the SNES context 277170441072SBarry Smith . abstol - absolute convergence tolerance 277233174efeSLois Curfman McInnes . rtol - relative convergence tolerance 277333174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 277433174efeSLois Curfman McInnes of the change in the solution between steps 277533174efeSLois Curfman McInnes . maxit - maximum number of iterations 2776c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2777fee21e36SBarry Smith 277833174efeSLois Curfman McInnes Options Database Keys: 277970441072SBarry Smith + -snes_atol <abstol> - Sets abstol 2780c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 2781c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 2782c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 2783c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 27849b94acceSBarry Smith 2785d7a720efSLois Curfman McInnes Notes: 27869b94acceSBarry Smith The default maximum number of iterations is 50. 27879b94acceSBarry Smith The default maximum number of function evaluations is 1000. 27889b94acceSBarry Smith 278936851e7fSLois Curfman McInnes Level: intermediate 279036851e7fSLois Curfman McInnes 279133174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances 27929b94acceSBarry Smith 27932492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance() 27949b94acceSBarry Smith @*/ 27957087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 27969b94acceSBarry Smith { 27973a40ed3dSBarry Smith PetscFunctionBegin; 27980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2799c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 2800c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 2801c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 2802c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 2803c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 2804c5eb9154SBarry Smith 2805ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 2806ab54825eSJed Brown if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol); 2807ab54825eSJed Brown snes->abstol = abstol; 2808ab54825eSJed Brown } 2809ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 2810ab54825eSJed 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); 2811ab54825eSJed Brown snes->rtol = rtol; 2812ab54825eSJed Brown } 2813ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 2814ab54825eSJed Brown if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol); 2815c60f73f4SPeter Brune snes->stol = stol; 2816ab54825eSJed Brown } 2817ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 2818ab54825eSJed Brown if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit); 2819ab54825eSJed Brown snes->max_its = maxit; 2820ab54825eSJed Brown } 2821ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 2822ab54825eSJed Brown if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf); 2823ab54825eSJed Brown snes->max_funcs = maxf; 2824ab54825eSJed Brown } 282588976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 28263a40ed3dSBarry Smith PetscFunctionReturn(0); 28279b94acceSBarry Smith } 28289b94acceSBarry Smith 28294a2ae208SSatish Balay #undef __FUNCT__ 28304a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances" 28319b94acceSBarry Smith /*@ 283233174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 283333174efeSLois Curfman McInnes 2834c7afd0dbSLois Curfman McInnes Not Collective 2835c7afd0dbSLois Curfman McInnes 283633174efeSLois Curfman McInnes Input Parameters: 2837c7afd0dbSLois Curfman McInnes + snes - the SNES context 283885385478SLisandro Dalcin . atol - absolute convergence tolerance 283933174efeSLois Curfman McInnes . rtol - relative convergence tolerance 284033174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 284133174efeSLois Curfman McInnes of the change in the solution between steps 284233174efeSLois Curfman McInnes . maxit - maximum number of iterations 2843c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 2844fee21e36SBarry Smith 284533174efeSLois Curfman McInnes Notes: 284633174efeSLois Curfman McInnes The user can specify PETSC_NULL for any parameter that is not needed. 284733174efeSLois Curfman McInnes 284836851e7fSLois Curfman McInnes Level: intermediate 284936851e7fSLois Curfman McInnes 285033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances 285133174efeSLois Curfman McInnes 285233174efeSLois Curfman McInnes .seealso: SNESSetTolerances() 285333174efeSLois Curfman McInnes @*/ 28547087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 285533174efeSLois Curfman McInnes { 28563a40ed3dSBarry Smith PetscFunctionBegin; 28570700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 285885385478SLisandro Dalcin if (atol) *atol = snes->abstol; 285933174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 2860c60f73f4SPeter Brune if (stol) *stol = snes->stol; 286133174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 286233174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 28633a40ed3dSBarry Smith PetscFunctionReturn(0); 286433174efeSLois Curfman McInnes } 286533174efeSLois Curfman McInnes 28664a2ae208SSatish Balay #undef __FUNCT__ 28674a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance" 286833174efeSLois Curfman McInnes /*@ 28699b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 28709b94acceSBarry Smith 28713f9fe445SBarry Smith Logically Collective on SNES 2872fee21e36SBarry Smith 2873c7afd0dbSLois Curfman McInnes Input Parameters: 2874c7afd0dbSLois Curfman McInnes + snes - the SNES context 2875c7afd0dbSLois Curfman McInnes - tol - tolerance 2876c7afd0dbSLois Curfman McInnes 28779b94acceSBarry Smith Options Database Key: 2878c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 28799b94acceSBarry Smith 288036851e7fSLois Curfman McInnes Level: intermediate 288136851e7fSLois Curfman McInnes 28829b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance 28839b94acceSBarry Smith 28842492ecdbSBarry Smith .seealso: SNESSetTolerances() 28859b94acceSBarry Smith @*/ 28867087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 28879b94acceSBarry Smith { 28883a40ed3dSBarry Smith PetscFunctionBegin; 28890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2890c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 28919b94acceSBarry Smith snes->deltatol = tol; 28923a40ed3dSBarry Smith PetscFunctionReturn(0); 28939b94acceSBarry Smith } 28949b94acceSBarry Smith 2895df9fa365SBarry Smith /* 2896df9fa365SBarry Smith Duplicate the lg monitors for SNES from KSP; for some reason with 2897df9fa365SBarry Smith dynamic libraries things don't work under Sun4 if we just use 2898df9fa365SBarry Smith macros instead of functions 2899df9fa365SBarry Smith */ 29004a2ae208SSatish Balay #undef __FUNCT__ 2901a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG" 29027087cfbeSBarry Smith PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx) 2903ce1608b8SBarry Smith { 2904dfbe8321SBarry Smith PetscErrorCode ierr; 2905ce1608b8SBarry Smith 2906ce1608b8SBarry Smith PetscFunctionBegin; 29070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2908a6570f20SBarry Smith ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr); 2909ce1608b8SBarry Smith PetscFunctionReturn(0); 2910ce1608b8SBarry Smith } 2911ce1608b8SBarry Smith 29124a2ae208SSatish Balay #undef __FUNCT__ 2913a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate" 29147087cfbeSBarry Smith PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 2915df9fa365SBarry Smith { 2916dfbe8321SBarry Smith PetscErrorCode ierr; 2917df9fa365SBarry Smith 2918df9fa365SBarry Smith PetscFunctionBegin; 2919a6570f20SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 2920df9fa365SBarry Smith PetscFunctionReturn(0); 2921df9fa365SBarry Smith } 2922df9fa365SBarry Smith 29234a2ae208SSatish Balay #undef __FUNCT__ 2924a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy" 29256bf464f9SBarry Smith PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw) 2926df9fa365SBarry Smith { 2927dfbe8321SBarry Smith PetscErrorCode ierr; 2928df9fa365SBarry Smith 2929df9fa365SBarry Smith PetscFunctionBegin; 2930a6570f20SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 2931df9fa365SBarry Smith PetscFunctionReturn(0); 2932df9fa365SBarry Smith } 2933df9fa365SBarry Smith 29347087cfbeSBarry Smith extern PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 2935b271bb04SBarry Smith #undef __FUNCT__ 2936b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange" 29377087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 2938b271bb04SBarry Smith { 2939b271bb04SBarry Smith PetscDrawLG lg; 2940b271bb04SBarry Smith PetscErrorCode ierr; 2941b271bb04SBarry Smith PetscReal x,y,per; 2942b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 2943b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 2944b271bb04SBarry Smith PetscDraw draw; 2945b271bb04SBarry Smith PetscFunctionBegin; 2946b271bb04SBarry Smith if (!monctx) { 2947b271bb04SBarry Smith MPI_Comm comm; 2948b271bb04SBarry Smith 2949b271bb04SBarry Smith ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr); 2950b271bb04SBarry Smith v = PETSC_VIEWER_DRAW_(comm); 2951b271bb04SBarry Smith } 2952b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr); 2953b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2954b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2955b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr); 2956b271bb04SBarry Smith x = (PetscReal) n; 2957b271bb04SBarry Smith if (rnorm > 0.0) y = log10(rnorm); else y = -15.0; 2958b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2959b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2960b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2961b271bb04SBarry Smith } 2962b271bb04SBarry Smith 2963b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr); 2964b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2965b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2966b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr); 2967b271bb04SBarry Smith ierr = SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr); 2968b271bb04SBarry Smith x = (PetscReal) n; 2969b271bb04SBarry Smith y = 100.0*per; 2970b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2971b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2972b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2973b271bb04SBarry Smith } 2974b271bb04SBarry Smith 2975b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr); 2976b271bb04SBarry Smith if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2977b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2978b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr); 2979b271bb04SBarry Smith x = (PetscReal) n; 2980b271bb04SBarry Smith y = (prev - rnorm)/prev; 2981b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2982b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2983b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2984b271bb04SBarry Smith } 2985b271bb04SBarry Smith 2986b271bb04SBarry Smith ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr); 2987b271bb04SBarry Smith if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);} 2988b271bb04SBarry Smith ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr); 2989b271bb04SBarry Smith ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr); 2990b271bb04SBarry Smith x = (PetscReal) n; 2991b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 2992b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 2993b271bb04SBarry Smith ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr); 2994b271bb04SBarry Smith } 2995b271bb04SBarry Smith if (n < 20 || !(n % 5)) { 2996b271bb04SBarry Smith ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr); 2997b271bb04SBarry Smith } 2998b271bb04SBarry Smith prev = rnorm; 2999b271bb04SBarry Smith PetscFunctionReturn(0); 3000b271bb04SBarry Smith } 3001b271bb04SBarry Smith 3002b271bb04SBarry Smith #undef __FUNCT__ 3003b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate" 30047087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw) 3005b271bb04SBarry Smith { 3006b271bb04SBarry Smith PetscErrorCode ierr; 3007b271bb04SBarry Smith 3008b271bb04SBarry Smith PetscFunctionBegin; 3009b271bb04SBarry Smith ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr); 3010b271bb04SBarry Smith PetscFunctionReturn(0); 3011b271bb04SBarry Smith } 3012b271bb04SBarry Smith 3013b271bb04SBarry Smith #undef __FUNCT__ 3014b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy" 30156bf464f9SBarry Smith PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw) 3016b271bb04SBarry Smith { 3017b271bb04SBarry Smith PetscErrorCode ierr; 3018b271bb04SBarry Smith 3019b271bb04SBarry Smith PetscFunctionBegin; 3020b271bb04SBarry Smith ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr); 3021b271bb04SBarry Smith PetscFunctionReturn(0); 3022b271bb04SBarry Smith } 3023b271bb04SBarry Smith 30247a03ce2fSLisandro Dalcin #undef __FUNCT__ 30257a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor" 3026228d79bcSJed Brown /*@ 3027228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3028228d79bcSJed Brown 3029228d79bcSJed Brown Collective on SNES 3030228d79bcSJed Brown 3031228d79bcSJed Brown Input Parameters: 3032228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 3033228d79bcSJed Brown . iter - iteration number 3034228d79bcSJed Brown - rnorm - relative norm of the residual 3035228d79bcSJed Brown 3036228d79bcSJed Brown Notes: 3037228d79bcSJed Brown This routine is called by the SNES implementations. 3038228d79bcSJed Brown It does not typically need to be called by the user. 3039228d79bcSJed Brown 3040228d79bcSJed Brown Level: developer 3041228d79bcSJed Brown 3042228d79bcSJed Brown .seealso: SNESMonitorSet() 3043228d79bcSJed Brown @*/ 30447a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 30457a03ce2fSLisandro Dalcin { 30467a03ce2fSLisandro Dalcin PetscErrorCode ierr; 30477a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 30487a03ce2fSLisandro Dalcin 30497a03ce2fSLisandro Dalcin PetscFunctionBegin; 30507a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 30517a03ce2fSLisandro Dalcin ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr); 30527a03ce2fSLisandro Dalcin } 30537a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 30547a03ce2fSLisandro Dalcin } 30557a03ce2fSLisandro Dalcin 30569b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 30579b94acceSBarry Smith 30584a2ae208SSatish Balay #undef __FUNCT__ 3059a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet" 30609b94acceSBarry Smith /*@C 3061a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 30629b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 30639b94acceSBarry Smith progress. 30649b94acceSBarry Smith 30653f9fe445SBarry Smith Logically Collective on SNES 3066fee21e36SBarry Smith 3067c7afd0dbSLois Curfman McInnes Input Parameters: 3068c7afd0dbSLois Curfman McInnes + snes - the SNES context 3069c7afd0dbSLois Curfman McInnes . func - monitoring routine 3070b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 3071e8105e01SRichard Katz monitor routine (use PETSC_NULL if no context is desired) 3072b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 3073b3006f0bSLois Curfman McInnes (may be PETSC_NULL) 30749b94acceSBarry Smith 3075c7afd0dbSLois Curfman McInnes Calling sequence of func: 3076a7cc72afSBarry Smith $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3077c7afd0dbSLois Curfman McInnes 3078c7afd0dbSLois Curfman McInnes + snes - the SNES context 3079c7afd0dbSLois Curfman McInnes . its - iteration number 3080c7afd0dbSLois Curfman McInnes . norm - 2-norm function value (may be estimated) 308140a0c1c6SLois Curfman McInnes - mctx - [optional] monitoring context 30829b94acceSBarry Smith 30839665c990SLois Curfman McInnes Options Database Keys: 3084a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 3085a6570f20SBarry Smith . -snes_monitor_draw - sets line graph monitor, 3086a6570f20SBarry Smith uses SNESMonitorLGCreate() 3087cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3088c7afd0dbSLois Curfman McInnes been hardwired into a code by 3089a6570f20SBarry Smith calls to SNESMonitorSet(), but 3090c7afd0dbSLois Curfman McInnes does not cancel those set via 3091c7afd0dbSLois Curfman McInnes the options database. 30929665c990SLois Curfman McInnes 3093639f9d9dSBarry Smith Notes: 30946bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3095a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 30966bc08f3fSLois Curfman McInnes order in which they were set. 3097639f9d9dSBarry Smith 3098025f1a04SBarry Smith Fortran notes: Only a single monitor function can be set for each SNES object 3099025f1a04SBarry Smith 310036851e7fSLois Curfman McInnes Level: intermediate 310136851e7fSLois Curfman McInnes 31029b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor 31039b94acceSBarry Smith 3104a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel() 31059b94acceSBarry Smith @*/ 3106c2efdce3SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 31079b94acceSBarry Smith { 3108b90d0a6eSBarry Smith PetscInt i; 3109649052a6SBarry Smith PetscErrorCode ierr; 3110b90d0a6eSBarry Smith 31113a40ed3dSBarry Smith PetscFunctionBegin; 31120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 311317186662SBarry Smith if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 3114b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 3115649052a6SBarry Smith if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) { 3116649052a6SBarry Smith if (monitordestroy) { 3117c2efdce3SBarry Smith ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr); 3118649052a6SBarry Smith } 3119b90d0a6eSBarry Smith PetscFunctionReturn(0); 3120b90d0a6eSBarry Smith } 3121b90d0a6eSBarry Smith } 3122b90d0a6eSBarry Smith snes->monitor[snes->numbermonitors] = monitor; 3123b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3124639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 31253a40ed3dSBarry Smith PetscFunctionReturn(0); 31269b94acceSBarry Smith } 31279b94acceSBarry Smith 31284a2ae208SSatish Balay #undef __FUNCT__ 3129a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel" 31305cd90555SBarry Smith /*@C 3131a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 31325cd90555SBarry Smith 31333f9fe445SBarry Smith Logically Collective on SNES 3134c7afd0dbSLois Curfman McInnes 31355cd90555SBarry Smith Input Parameters: 31365cd90555SBarry Smith . snes - the SNES context 31375cd90555SBarry Smith 31381a480d89SAdministrator Options Database Key: 3139a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3140a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3141c7afd0dbSLois Curfman McInnes set via the options database 31425cd90555SBarry Smith 31435cd90555SBarry Smith Notes: 31445cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 31455cd90555SBarry Smith 314636851e7fSLois Curfman McInnes Level: intermediate 314736851e7fSLois Curfman McInnes 31485cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor 31495cd90555SBarry Smith 3150a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet() 31515cd90555SBarry Smith @*/ 31527087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 31535cd90555SBarry Smith { 3154d952e501SBarry Smith PetscErrorCode ierr; 3155d952e501SBarry Smith PetscInt i; 3156d952e501SBarry Smith 31575cd90555SBarry Smith PetscFunctionBegin; 31580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3159d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 3160d952e501SBarry Smith if (snes->monitordestroy[i]) { 31613c4aec1bSBarry Smith ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr); 3162d952e501SBarry Smith } 3163d952e501SBarry Smith } 31645cd90555SBarry Smith snes->numbermonitors = 0; 31655cd90555SBarry Smith PetscFunctionReturn(0); 31665cd90555SBarry Smith } 31675cd90555SBarry Smith 31684a2ae208SSatish Balay #undef __FUNCT__ 31694a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest" 31709b94acceSBarry Smith /*@C 31719b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 31729b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 31739b94acceSBarry Smith 31743f9fe445SBarry Smith Logically Collective on SNES 3175fee21e36SBarry Smith 3176c7afd0dbSLois Curfman McInnes Input Parameters: 3177c7afd0dbSLois Curfman McInnes + snes - the SNES context 3178c7afd0dbSLois Curfman McInnes . func - routine to test for convergence 31797f7931b9SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL) 31807f7931b9SBarry Smith - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran) 31819b94acceSBarry Smith 3182c7afd0dbSLois Curfman McInnes Calling sequence of func: 318306ee9f85SBarry Smith $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3184c7afd0dbSLois Curfman McInnes 3185c7afd0dbSLois Curfman McInnes + snes - the SNES context 318606ee9f85SBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3187c7afd0dbSLois Curfman McInnes . cctx - [optional] convergence context 3188184914b5SBarry Smith . reason - reason for convergence/divergence 3189c7afd0dbSLois Curfman McInnes . xnorm - 2-norm of current iterate 31904b27c08aSLois Curfman McInnes . gnorm - 2-norm of current step 31914b27c08aSLois Curfman McInnes - f - 2-norm of function 31929b94acceSBarry Smith 319336851e7fSLois Curfman McInnes Level: advanced 319436851e7fSLois Curfman McInnes 31959b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test 31969b94acceSBarry Smith 319785385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged() 31989b94acceSBarry Smith @*/ 31997087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 32009b94acceSBarry Smith { 32017f7931b9SBarry Smith PetscErrorCode ierr; 32027f7931b9SBarry Smith 32033a40ed3dSBarry Smith PetscFunctionBegin; 32040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 320585385478SLisandro Dalcin if (!func) func = SNESSkipConverged; 32067f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 32077f7931b9SBarry Smith ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr); 32087f7931b9SBarry Smith } 320985385478SLisandro Dalcin snes->ops->converged = func; 32107f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 321185385478SLisandro Dalcin snes->cnvP = cctx; 32123a40ed3dSBarry Smith PetscFunctionReturn(0); 32139b94acceSBarry Smith } 32149b94acceSBarry Smith 32154a2ae208SSatish Balay #undef __FUNCT__ 32164a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason" 321752baeb72SSatish Balay /*@ 3218184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 3219184914b5SBarry Smith 3220184914b5SBarry Smith Not Collective 3221184914b5SBarry Smith 3222184914b5SBarry Smith Input Parameter: 3223184914b5SBarry Smith . snes - the SNES context 3224184914b5SBarry Smith 3225184914b5SBarry Smith Output Parameter: 32264d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 3227184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 3228184914b5SBarry Smith 3229184914b5SBarry Smith Level: intermediate 3230184914b5SBarry Smith 3231184914b5SBarry Smith Notes: Can only be called after the call the SNESSolve() is complete. 3232184914b5SBarry Smith 3233184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test 3234184914b5SBarry Smith 323585385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason 3236184914b5SBarry Smith @*/ 32377087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 3238184914b5SBarry Smith { 3239184914b5SBarry Smith PetscFunctionBegin; 32400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32414482741eSBarry Smith PetscValidPointer(reason,2); 3242184914b5SBarry Smith *reason = snes->reason; 3243184914b5SBarry Smith PetscFunctionReturn(0); 3244184914b5SBarry Smith } 3245184914b5SBarry Smith 32464a2ae208SSatish Balay #undef __FUNCT__ 32474a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory" 3248c9005455SLois Curfman McInnes /*@ 3249c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 3250c9005455SLois Curfman McInnes 32513f9fe445SBarry Smith Logically Collective on SNES 3252fee21e36SBarry Smith 3253c7afd0dbSLois Curfman McInnes Input Parameters: 3254c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 32558c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 3256cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 3257758f92a0SBarry Smith . na - size of a and its 325864731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 3259758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 3260c7afd0dbSLois Curfman McInnes 3261308dcc3eSBarry Smith Notes: 3262308dcc3eSBarry Smith If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 3263308dcc3eSBarry Smith default array of length 10000 is allocated. 3264308dcc3eSBarry Smith 3265c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 3266c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 3267c9005455SLois Curfman McInnes during the section of code that is being timed. 3268c9005455SLois Curfman McInnes 326936851e7fSLois Curfman McInnes Level: intermediate 327036851e7fSLois Curfman McInnes 3271c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history 3272758f92a0SBarry Smith 327308405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory() 3274758f92a0SBarry Smith 3275c9005455SLois Curfman McInnes @*/ 32767087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 3277c9005455SLois Curfman McInnes { 3278308dcc3eSBarry Smith PetscErrorCode ierr; 3279308dcc3eSBarry Smith 32803a40ed3dSBarry Smith PetscFunctionBegin; 32810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32824482741eSBarry Smith if (na) PetscValidScalarPointer(a,2); 3283a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 3284308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) { 3285308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 3286308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr); 3287308dcc3eSBarry Smith ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr); 3288308dcc3eSBarry Smith snes->conv_malloc = PETSC_TRUE; 3289308dcc3eSBarry Smith } 3290c9005455SLois Curfman McInnes snes->conv_hist = a; 3291758f92a0SBarry Smith snes->conv_hist_its = its; 3292758f92a0SBarry Smith snes->conv_hist_max = na; 3293a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 3294758f92a0SBarry Smith snes->conv_hist_reset = reset; 3295758f92a0SBarry Smith PetscFunctionReturn(0); 3296758f92a0SBarry Smith } 3297758f92a0SBarry Smith 3298308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3299c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 3300c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 3301308dcc3eSBarry Smith EXTERN_C_BEGIN 3302308dcc3eSBarry Smith #undef __FUNCT__ 3303308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab" 3304308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 3305308dcc3eSBarry Smith { 3306308dcc3eSBarry Smith mxArray *mat; 3307308dcc3eSBarry Smith PetscInt i; 3308308dcc3eSBarry Smith PetscReal *ar; 3309308dcc3eSBarry Smith 3310308dcc3eSBarry Smith PetscFunctionBegin; 3311308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 3312308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 3313308dcc3eSBarry Smith for (i=0; i<snes->conv_hist_len; i++) { 3314308dcc3eSBarry Smith ar[i] = snes->conv_hist[i]; 3315308dcc3eSBarry Smith } 3316308dcc3eSBarry Smith PetscFunctionReturn(mat); 3317308dcc3eSBarry Smith } 3318308dcc3eSBarry Smith EXTERN_C_END 3319308dcc3eSBarry Smith #endif 3320308dcc3eSBarry Smith 3321308dcc3eSBarry Smith 33224a2ae208SSatish Balay #undef __FUNCT__ 33234a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory" 33240c4c9dddSBarry Smith /*@C 3325758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 3326758f92a0SBarry Smith 33273f9fe445SBarry Smith Not Collective 3328758f92a0SBarry Smith 3329758f92a0SBarry Smith Input Parameter: 3330758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 3331758f92a0SBarry Smith 3332758f92a0SBarry Smith Output Parameters: 3333758f92a0SBarry Smith . a - array to hold history 3334758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 3335758f92a0SBarry Smith negative if not converged) for each solve. 3336758f92a0SBarry Smith - na - size of a and its 3337758f92a0SBarry Smith 3338758f92a0SBarry Smith Notes: 3339758f92a0SBarry Smith The calling sequence for this routine in Fortran is 3340758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 3341758f92a0SBarry Smith 3342758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 3343758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 3344758f92a0SBarry Smith during the section of code that is being timed. 3345758f92a0SBarry Smith 3346758f92a0SBarry Smith Level: intermediate 3347758f92a0SBarry Smith 3348758f92a0SBarry Smith .keywords: SNES, get, convergence, history 3349758f92a0SBarry Smith 3350758f92a0SBarry Smith .seealso: SNESSetConvergencHistory() 3351758f92a0SBarry Smith 3352758f92a0SBarry Smith @*/ 33537087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 3354758f92a0SBarry Smith { 3355758f92a0SBarry Smith PetscFunctionBegin; 33560700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3357758f92a0SBarry Smith if (a) *a = snes->conv_hist; 3358758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 3359758f92a0SBarry Smith if (na) *na = snes->conv_hist_len; 33603a40ed3dSBarry Smith PetscFunctionReturn(0); 3361c9005455SLois Curfman McInnes } 3362c9005455SLois Curfman McInnes 3363e74ef692SMatthew Knepley #undef __FUNCT__ 3364e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate" 3365ac226902SBarry Smith /*@C 336676b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 3367eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 33687e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 336976b2cf59SMatthew Knepley 33703f9fe445SBarry Smith Logically Collective on SNES 337176b2cf59SMatthew Knepley 337276b2cf59SMatthew Knepley Input Parameters: 337376b2cf59SMatthew Knepley . snes - The nonlinear solver context 337476b2cf59SMatthew Knepley . func - The function 337576b2cf59SMatthew Knepley 337676b2cf59SMatthew Knepley Calling sequence of func: 3377b5d30489SBarry Smith . func (SNES snes, PetscInt step); 337876b2cf59SMatthew Knepley 337976b2cf59SMatthew Knepley . step - The current step of the iteration 338076b2cf59SMatthew Knepley 3381fe97e370SBarry Smith Level: advanced 3382fe97e370SBarry Smith 3383fe97e370SBarry 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() 3384fe97e370SBarry Smith This is not used by most users. 338576b2cf59SMatthew Knepley 338676b2cf59SMatthew Knepley .keywords: SNES, update 3387b5d30489SBarry Smith 338885385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve() 338976b2cf59SMatthew Knepley @*/ 33907087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 339176b2cf59SMatthew Knepley { 339276b2cf59SMatthew Knepley PetscFunctionBegin; 33930700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 3394e7788613SBarry Smith snes->ops->update = func; 339576b2cf59SMatthew Knepley PetscFunctionReturn(0); 339676b2cf59SMatthew Knepley } 339776b2cf59SMatthew Knepley 3398e74ef692SMatthew Knepley #undef __FUNCT__ 3399e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate" 340076b2cf59SMatthew Knepley /*@ 340176b2cf59SMatthew Knepley SNESDefaultUpdate - The default update function which does nothing. 340276b2cf59SMatthew Knepley 340376b2cf59SMatthew Knepley Not collective 340476b2cf59SMatthew Knepley 340576b2cf59SMatthew Knepley Input Parameters: 340676b2cf59SMatthew Knepley . snes - The nonlinear solver context 340776b2cf59SMatthew Knepley . step - The current step of the iteration 340876b2cf59SMatthew Knepley 3409205452f4SMatthew Knepley Level: intermediate 3410205452f4SMatthew Knepley 341176b2cf59SMatthew Knepley .keywords: SNES, update 3412a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC() 341376b2cf59SMatthew Knepley @*/ 34147087cfbeSBarry Smith PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step) 341576b2cf59SMatthew Knepley { 341676b2cf59SMatthew Knepley PetscFunctionBegin; 341776b2cf59SMatthew Knepley PetscFunctionReturn(0); 341876b2cf59SMatthew Knepley } 341976b2cf59SMatthew Knepley 34204a2ae208SSatish Balay #undef __FUNCT__ 34214a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private" 34229b94acceSBarry Smith /* 34239b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 34249b94acceSBarry Smith positive parameter delta. 34259b94acceSBarry Smith 34269b94acceSBarry Smith Input Parameters: 3427c7afd0dbSLois Curfman McInnes + snes - the SNES context 34289b94acceSBarry Smith . y - approximate solution of linear system 34299b94acceSBarry Smith . fnorm - 2-norm of current function 3430c7afd0dbSLois Curfman McInnes - delta - trust region size 34319b94acceSBarry Smith 34329b94acceSBarry Smith Output Parameters: 3433c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 34349b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 34359b94acceSBarry Smith region, and exceeds zero otherwise. 3436c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 34379b94acceSBarry Smith 34389b94acceSBarry Smith Note: 34394b27c08aSLois Curfman McInnes For non-trust region methods such as SNESLS, the parameter delta 34409b94acceSBarry Smith is set to be the maximum allowable step size. 34419b94acceSBarry Smith 34429b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step 34439b94acceSBarry Smith */ 3444dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 34459b94acceSBarry Smith { 3446064f8208SBarry Smith PetscReal nrm; 3447ea709b57SSatish Balay PetscScalar cnorm; 3448dfbe8321SBarry Smith PetscErrorCode ierr; 34493a40ed3dSBarry Smith 34503a40ed3dSBarry Smith PetscFunctionBegin; 34510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34520700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3453c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 3454184914b5SBarry Smith 3455064f8208SBarry Smith ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr); 3456064f8208SBarry Smith if (nrm > *delta) { 3457064f8208SBarry Smith nrm = *delta/nrm; 3458064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 3459064f8208SBarry Smith cnorm = nrm; 34602dcb1b2aSMatthew Knepley ierr = VecScale(y,cnorm);CHKERRQ(ierr); 34619b94acceSBarry Smith *ynorm = *delta; 34629b94acceSBarry Smith } else { 34639b94acceSBarry Smith *gpnorm = 0.0; 3464064f8208SBarry Smith *ynorm = nrm; 34659b94acceSBarry Smith } 34663a40ed3dSBarry Smith PetscFunctionReturn(0); 34679b94acceSBarry Smith } 34689b94acceSBarry Smith 34694a2ae208SSatish Balay #undef __FUNCT__ 34704a2ae208SSatish Balay #define __FUNCT__ "SNESSolve" 34716ce558aeSBarry Smith /*@C 3472f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 3473f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 34749b94acceSBarry Smith 3475c7afd0dbSLois Curfman McInnes Collective on SNES 3476c7afd0dbSLois Curfman McInnes 3477b2002411SLois Curfman McInnes Input Parameters: 3478c7afd0dbSLois Curfman McInnes + snes - the SNES context 34793cebf274SJed Brown . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero. 348085385478SLisandro Dalcin - x - the solution vector. 34819b94acceSBarry Smith 3482b2002411SLois Curfman McInnes Notes: 34838ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 34848ddd3da0SLois Curfman McInnes for the nonlinear solve prior to calling SNESSolve. In particular, 34858ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 34868ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 34878ddd3da0SLois Curfman McInnes 348836851e7fSLois Curfman McInnes Level: beginner 348936851e7fSLois Curfman McInnes 34909b94acceSBarry Smith .keywords: SNES, nonlinear, solve 34919b94acceSBarry Smith 3492c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution() 34939b94acceSBarry Smith @*/ 34947087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 34959b94acceSBarry Smith { 3496dfbe8321SBarry Smith PetscErrorCode ierr; 3497ace3abfcSBarry Smith PetscBool flg; 3498eabae89aSBarry Smith char filename[PETSC_MAX_PATH_LEN]; 3499eabae89aSBarry Smith PetscViewer viewer; 3500efd51863SBarry Smith PetscInt grid; 3501a69afd8bSBarry Smith Vec xcreated = PETSC_NULL; 3502caa4e7f2SJed Brown DM dm; 3503052efed2SBarry Smith 35043a40ed3dSBarry Smith PetscFunctionBegin; 35050700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3506a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3507a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 35080700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 350985385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 351085385478SLisandro Dalcin 3511caa4e7f2SJed Brown if (!x) { 3512caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3513caa4e7f2SJed Brown ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr); 3514a69afd8bSBarry Smith x = xcreated; 3515a69afd8bSBarry Smith } 3516a69afd8bSBarry Smith 3517a8248277SBarry Smith for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);} 3518efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 3519efd51863SBarry Smith 352085385478SLisandro Dalcin /* set solution vector */ 3521efd51863SBarry Smith if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);} 35226bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr); 352385385478SLisandro Dalcin snes->vec_sol = x; 3524caa4e7f2SJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 3525caa4e7f2SJed Brown 3526caa4e7f2SJed Brown /* set affine vector if provided */ 352785385478SLisandro Dalcin if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); } 35286bf464f9SBarry Smith ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr); 352985385478SLisandro Dalcin snes->vec_rhs = b; 353085385478SLisandro Dalcin 353170e92668SMatthew Knepley ierr = SNESSetUp(snes);CHKERRQ(ierr); 35323f149594SLisandro Dalcin 35337eee914bSBarry Smith if (!grid) { 35347eee914bSBarry Smith if (snes->ops->computeinitialguess) { 3535d25893d9SBarry Smith ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr); 3536dd568438SSatish Balay } else if (snes->dm) { 3537dd568438SSatish Balay PetscBool ig; 3538dd568438SSatish Balay ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr); 3539dd568438SSatish Balay if (ig) { 35407eee914bSBarry Smith ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr); 35417eee914bSBarry Smith } 3542d25893d9SBarry Smith } 3543dd568438SSatish Balay } 3544d25893d9SBarry Smith 3545abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 354650ffb88aSMatthew Knepley snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0; 3547d5e45103SBarry Smith 35483f149594SLisandro Dalcin ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 35494936397dSBarry Smith ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr); 355085385478SLisandro Dalcin ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr); 35514936397dSBarry Smith if (snes->domainerror){ 35524936397dSBarry Smith snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN; 35534936397dSBarry Smith snes->domainerror = PETSC_FALSE; 35544936397dSBarry Smith } 355517186662SBarry Smith if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 35563f149594SLisandro Dalcin 355790d69ab7SBarry Smith flg = PETSC_FALSE; 3558acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr); 3559da9b6338SBarry Smith if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); } 35605968eb51SBarry Smith if (snes->printreason) { 3561a8248277SBarry Smith ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 35625968eb51SBarry Smith if (snes->reason > 0) { 3563c7e7b494SJed 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); 35645968eb51SBarry Smith } else { 3565c7e7b494SJed 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); 35665968eb51SBarry Smith } 3567a8248277SBarry Smith ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr); 35685968eb51SBarry Smith } 35695968eb51SBarry Smith 3570e113a28aSBarry Smith if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 3571efd51863SBarry Smith if (grid < snes->gridsequence) { 3572efd51863SBarry Smith DM fine; 3573efd51863SBarry Smith Vec xnew; 3574efd51863SBarry Smith Mat interp; 3575efd51863SBarry Smith 3576efd51863SBarry Smith ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr); 3577c5c77316SJed Brown if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 3578e727c939SJed Brown ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr); 3579efd51863SBarry Smith ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr); 3580efd51863SBarry Smith ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr); 3581c833c3b5SJed Brown ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr); 3582efd51863SBarry Smith ierr = MatDestroy(&interp);CHKERRQ(ierr); 3583efd51863SBarry Smith x = xnew; 3584efd51863SBarry Smith 3585efd51863SBarry Smith ierr = SNESReset(snes);CHKERRQ(ierr); 3586efd51863SBarry Smith ierr = SNESSetDM(snes,fine);CHKERRQ(ierr); 3587efd51863SBarry Smith ierr = DMDestroy(&fine);CHKERRQ(ierr); 3588a8248277SBarry Smith ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr); 3589efd51863SBarry Smith } 3590efd51863SBarry Smith } 35913f7e2da0SPeter Brune /* monitoring and viewing */ 35923f7e2da0SPeter Brune flg = PETSC_FALSE; 35933f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 35943f7e2da0SPeter Brune if (flg && !PetscPreLoadingOn) { 35953f7e2da0SPeter Brune ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr); 35963f7e2da0SPeter Brune ierr = SNESView(snes,viewer);CHKERRQ(ierr); 35973f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 35983f7e2da0SPeter Brune } 35993f7e2da0SPeter Brune 36003f7e2da0SPeter Brune flg = PETSC_FALSE; 36013f7e2da0SPeter Brune ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); 36023f7e2da0SPeter Brune if (flg) { 36033f7e2da0SPeter Brune PetscViewer viewer; 36043f7e2da0SPeter Brune ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr); 36053f7e2da0SPeter Brune ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr); 36063f7e2da0SPeter Brune ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr); 36073f7e2da0SPeter Brune ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr); 36083f7e2da0SPeter Brune ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 36093f7e2da0SPeter Brune } 36103f7e2da0SPeter Brune 3611a69afd8bSBarry Smith ierr = VecDestroy(&xcreated);CHKERRQ(ierr); 36123a40ed3dSBarry Smith PetscFunctionReturn(0); 36139b94acceSBarry Smith } 36149b94acceSBarry Smith 36159b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 36169b94acceSBarry Smith 36174a2ae208SSatish Balay #undef __FUNCT__ 36184a2ae208SSatish Balay #define __FUNCT__ "SNESSetType" 361982bf6240SBarry Smith /*@C 36204b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 36219b94acceSBarry Smith 3622fee21e36SBarry Smith Collective on SNES 3623fee21e36SBarry Smith 3624c7afd0dbSLois Curfman McInnes Input Parameters: 3625c7afd0dbSLois Curfman McInnes + snes - the SNES context 3626454a90a3SBarry Smith - type - a known method 3627c7afd0dbSLois Curfman McInnes 3628c7afd0dbSLois Curfman McInnes Options Database Key: 3629454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 3630c7afd0dbSLois Curfman McInnes of available methods (for instance, ls or tr) 3631ae12b187SLois Curfman McInnes 36329b94acceSBarry Smith Notes: 3633e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 36344b27c08aSLois Curfman McInnes + SNESLS - Newton's method with line search 3635c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 36364b27c08aSLois Curfman McInnes . SNESTR - Newton's method with trust region 3637c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 36389b94acceSBarry Smith 3639ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 3640ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 3641ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 3642ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 3643ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 3644ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 3645ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 3646ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 3647ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 3648b0a32e0cSBarry Smith appropriate method. 364936851e7fSLois Curfman McInnes 365036851e7fSLois Curfman McInnes Level: intermediate 3651a703fe33SLois Curfman McInnes 3652454a90a3SBarry Smith .keywords: SNES, set, type 3653435da068SBarry Smith 3654435da068SBarry Smith .seealso: SNESType, SNESCreate() 3655435da068SBarry Smith 36569b94acceSBarry Smith @*/ 36577087cfbeSBarry Smith PetscErrorCode SNESSetType(SNES snes,const SNESType type) 36589b94acceSBarry Smith { 3659dfbe8321SBarry Smith PetscErrorCode ierr,(*r)(SNES); 3660ace3abfcSBarry Smith PetscBool match; 36613a40ed3dSBarry Smith 36623a40ed3dSBarry Smith PetscFunctionBegin; 36630700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36644482741eSBarry Smith PetscValidCharPointer(type,2); 366582bf6240SBarry Smith 3666251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr); 36670f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 366892ff6ae8SBarry Smith 36694b91b6eaSBarry Smith ierr = PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 3670e32f2f54SBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 367175396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 3672b5c23020SJed Brown if (snes->ops->destroy) { 3673b5c23020SJed Brown ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr); 3674b5c23020SJed Brown snes->ops->destroy = PETSC_NULL; 3675b5c23020SJed Brown } 367675396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 367775396ef9SLisandro Dalcin snes->ops->setup = 0; 367875396ef9SLisandro Dalcin snes->ops->solve = 0; 367975396ef9SLisandro Dalcin snes->ops->view = 0; 368075396ef9SLisandro Dalcin snes->ops->setfromoptions = 0; 368175396ef9SLisandro Dalcin snes->ops->destroy = 0; 368275396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 368375396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 3684454a90a3SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr); 368503bfa161SLisandro Dalcin ierr = (*r)(snes);CHKERRQ(ierr); 36869fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS) 36879fb22e1aSBarry Smith if (PetscAMSPublishAll) { 36889fb22e1aSBarry Smith ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr); 36899fb22e1aSBarry Smith } 36909fb22e1aSBarry Smith #endif 36913a40ed3dSBarry Smith PetscFunctionReturn(0); 36929b94acceSBarry Smith } 36939b94acceSBarry Smith 3694a847f771SSatish Balay 36959b94acceSBarry Smith /* --------------------------------------------------------------------- */ 36964a2ae208SSatish Balay #undef __FUNCT__ 36974a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy" 369852baeb72SSatish Balay /*@ 36999b94acceSBarry Smith SNESRegisterDestroy - Frees the list of nonlinear solvers that were 3700f1af5d2fSBarry Smith registered by SNESRegisterDynamic(). 37019b94acceSBarry Smith 3702fee21e36SBarry Smith Not Collective 3703fee21e36SBarry Smith 370436851e7fSLois Curfman McInnes Level: advanced 370536851e7fSLois Curfman McInnes 37069b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy 37079b94acceSBarry Smith 37089b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll() 37099b94acceSBarry Smith @*/ 37107087cfbeSBarry Smith PetscErrorCode SNESRegisterDestroy(void) 37119b94acceSBarry Smith { 3712dfbe8321SBarry Smith PetscErrorCode ierr; 371382bf6240SBarry Smith 37143a40ed3dSBarry Smith PetscFunctionBegin; 37151441b1d3SBarry Smith ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr); 37164c49b128SBarry Smith SNESRegisterAllCalled = PETSC_FALSE; 37173a40ed3dSBarry Smith PetscFunctionReturn(0); 37189b94acceSBarry Smith } 37199b94acceSBarry Smith 37204a2ae208SSatish Balay #undef __FUNCT__ 37214a2ae208SSatish Balay #define __FUNCT__ "SNESGetType" 37229b94acceSBarry Smith /*@C 37239a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 37249b94acceSBarry Smith 3725c7afd0dbSLois Curfman McInnes Not Collective 3726c7afd0dbSLois Curfman McInnes 37279b94acceSBarry Smith Input Parameter: 37284b0e389bSBarry Smith . snes - nonlinear solver context 37299b94acceSBarry Smith 37309b94acceSBarry Smith Output Parameter: 37313a7fca6bSBarry Smith . type - SNES method (a character string) 37329b94acceSBarry Smith 373336851e7fSLois Curfman McInnes Level: intermediate 373436851e7fSLois Curfman McInnes 3735454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name 37369b94acceSBarry Smith @*/ 37377087cfbeSBarry Smith PetscErrorCode SNESGetType(SNES snes,const SNESType *type) 37389b94acceSBarry Smith { 37393a40ed3dSBarry Smith PetscFunctionBegin; 37400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37414482741eSBarry Smith PetscValidPointer(type,2); 37427adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 37433a40ed3dSBarry Smith PetscFunctionReturn(0); 37449b94acceSBarry Smith } 37459b94acceSBarry Smith 37464a2ae208SSatish Balay #undef __FUNCT__ 37474a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution" 374852baeb72SSatish Balay /*@ 37499b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 3750c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 37519b94acceSBarry Smith 3752c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3753c7afd0dbSLois Curfman McInnes 37549b94acceSBarry Smith Input Parameter: 37559b94acceSBarry Smith . snes - the SNES context 37569b94acceSBarry Smith 37579b94acceSBarry Smith Output Parameter: 37589b94acceSBarry Smith . x - the solution 37599b94acceSBarry Smith 376070e92668SMatthew Knepley Level: intermediate 376136851e7fSLois Curfman McInnes 37629b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution 37639b94acceSBarry Smith 376485385478SLisandro Dalcin .seealso: SNESGetSolutionUpdate(), SNESGetFunction() 37659b94acceSBarry Smith @*/ 37667087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 37679b94acceSBarry Smith { 37683a40ed3dSBarry Smith PetscFunctionBegin; 37690700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37704482741eSBarry Smith PetscValidPointer(x,2); 377185385478SLisandro Dalcin *x = snes->vec_sol; 377270e92668SMatthew Knepley PetscFunctionReturn(0); 377370e92668SMatthew Knepley } 377470e92668SMatthew Knepley 377570e92668SMatthew Knepley #undef __FUNCT__ 37764a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate" 377752baeb72SSatish Balay /*@ 37789b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 37799b94acceSBarry Smith stored. 37809b94acceSBarry Smith 3781c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 3782c7afd0dbSLois Curfman McInnes 37839b94acceSBarry Smith Input Parameter: 37849b94acceSBarry Smith . snes - the SNES context 37859b94acceSBarry Smith 37869b94acceSBarry Smith Output Parameter: 37879b94acceSBarry Smith . x - the solution update 37889b94acceSBarry Smith 378936851e7fSLois Curfman McInnes Level: advanced 379036851e7fSLois Curfman McInnes 37919b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update 37929b94acceSBarry Smith 379385385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction() 37949b94acceSBarry Smith @*/ 37957087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 37969b94acceSBarry Smith { 37973a40ed3dSBarry Smith PetscFunctionBegin; 37980700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 37994482741eSBarry Smith PetscValidPointer(x,2); 380085385478SLisandro Dalcin *x = snes->vec_sol_update; 38013a40ed3dSBarry Smith PetscFunctionReturn(0); 38029b94acceSBarry Smith } 38039b94acceSBarry Smith 38044a2ae208SSatish Balay #undef __FUNCT__ 38054a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction" 38069b94acceSBarry Smith /*@C 38073638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 38089b94acceSBarry Smith 3809a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 3810c7afd0dbSLois Curfman McInnes 38119b94acceSBarry Smith Input Parameter: 38129b94acceSBarry Smith . snes - the SNES context 38139b94acceSBarry Smith 38149b94acceSBarry Smith Output Parameter: 38157bf4e008SBarry Smith + r - the function (or PETSC_NULL) 381670e92668SMatthew Knepley . func - the function (or PETSC_NULL) 381770e92668SMatthew Knepley - ctx - the function context (or PETSC_NULL) 38189b94acceSBarry Smith 381936851e7fSLois Curfman McInnes Level: advanced 382036851e7fSLois Curfman McInnes 3821a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function 38229b94acceSBarry Smith 38234b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution() 38249b94acceSBarry Smith @*/ 38257087cfbeSBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx) 38269b94acceSBarry Smith { 3827a63bb30eSJed Brown PetscErrorCode ierr; 38286cab3a1bSJed Brown DM dm; 3829a63bb30eSJed Brown 38303a40ed3dSBarry Smith PetscFunctionBegin; 38310700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3832a63bb30eSJed Brown if (r) { 3833a63bb30eSJed Brown if (!snes->vec_func) { 3834a63bb30eSJed Brown if (snes->vec_rhs) { 3835a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr); 3836a63bb30eSJed Brown } else if (snes->vec_sol) { 3837a63bb30eSJed Brown ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr); 3838a63bb30eSJed Brown } else if (snes->dm) { 3839a63bb30eSJed Brown ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr); 3840a63bb30eSJed Brown } 3841a63bb30eSJed Brown } 3842a63bb30eSJed Brown *r = snes->vec_func; 3843a63bb30eSJed Brown } 38446cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 38456cab3a1bSJed Brown ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr); 38463a40ed3dSBarry Smith PetscFunctionReturn(0); 38479b94acceSBarry Smith } 38489b94acceSBarry Smith 3849c79ef259SPeter Brune /*@C 3850c79ef259SPeter Brune SNESGetGS - Returns the GS function and context. 3851c79ef259SPeter Brune 3852c79ef259SPeter Brune Input Parameter: 3853c79ef259SPeter Brune . snes - the SNES context 3854c79ef259SPeter Brune 3855c79ef259SPeter Brune Output Parameter: 3856c79ef259SPeter Brune + gsfunc - the function (or PETSC_NULL) 3857c79ef259SPeter Brune - ctx - the function context (or PETSC_NULL) 3858c79ef259SPeter Brune 3859c79ef259SPeter Brune Level: advanced 3860c79ef259SPeter Brune 3861c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function 3862c79ef259SPeter Brune 3863c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction() 3864c79ef259SPeter Brune @*/ 3865c79ef259SPeter Brune 38664a2ae208SSatish Balay #undef __FUNCT__ 3867646217ecSPeter Brune #define __FUNCT__ "SNESGetGS" 3868646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx) 3869646217ecSPeter Brune { 38706cab3a1bSJed Brown PetscErrorCode ierr; 38716cab3a1bSJed Brown DM dm; 38726cab3a1bSJed Brown 3873646217ecSPeter Brune PetscFunctionBegin; 3874646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 38756cab3a1bSJed Brown ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr); 38766cab3a1bSJed Brown ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr); 3877646217ecSPeter Brune PetscFunctionReturn(0); 3878646217ecSPeter Brune } 3879646217ecSPeter Brune 38804a2ae208SSatish Balay #undef __FUNCT__ 38814a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix" 38823c7409f5SSatish Balay /*@C 38833c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 3884d850072dSLois Curfman McInnes SNES options in the database. 38853c7409f5SSatish Balay 38863f9fe445SBarry Smith Logically Collective on SNES 3887fee21e36SBarry Smith 3888c7afd0dbSLois Curfman McInnes Input Parameter: 3889c7afd0dbSLois Curfman McInnes + snes - the SNES context 3890c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3891c7afd0dbSLois Curfman McInnes 3892d850072dSLois Curfman McInnes Notes: 3893a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3894c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3895d850072dSLois Curfman McInnes 389636851e7fSLois Curfman McInnes Level: advanced 389736851e7fSLois Curfman McInnes 38983c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database 3899a86d99e1SLois Curfman McInnes 3900a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions() 39013c7409f5SSatish Balay @*/ 39027087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 39033c7409f5SSatish Balay { 3904dfbe8321SBarry Smith PetscErrorCode ierr; 39053c7409f5SSatish Balay 39063a40ed3dSBarry Smith PetscFunctionBegin; 39070700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3908639f9d9dSBarry Smith ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 39091cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 391094b7f48cSBarry Smith ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 39113a40ed3dSBarry Smith PetscFunctionReturn(0); 39123c7409f5SSatish Balay } 39133c7409f5SSatish Balay 39144a2ae208SSatish Balay #undef __FUNCT__ 39154a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix" 39163c7409f5SSatish Balay /*@C 3917f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 3918d850072dSLois Curfman McInnes SNES options in the database. 39193c7409f5SSatish Balay 39203f9fe445SBarry Smith Logically Collective on SNES 3921fee21e36SBarry Smith 3922c7afd0dbSLois Curfman McInnes Input Parameters: 3923c7afd0dbSLois Curfman McInnes + snes - the SNES context 3924c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 3925c7afd0dbSLois Curfman McInnes 3926d850072dSLois Curfman McInnes Notes: 3927a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 3928c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 3929d850072dSLois Curfman McInnes 393036851e7fSLois Curfman McInnes Level: advanced 393136851e7fSLois Curfman McInnes 39323c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database 3933a86d99e1SLois Curfman McInnes 3934a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix() 39353c7409f5SSatish Balay @*/ 39367087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 39373c7409f5SSatish Balay { 3938dfbe8321SBarry Smith PetscErrorCode ierr; 39393c7409f5SSatish Balay 39403a40ed3dSBarry Smith PetscFunctionBegin; 39410700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3942639f9d9dSBarry Smith ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 39431cee3971SBarry Smith if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);} 394494b7f48cSBarry Smith ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr); 39453a40ed3dSBarry Smith PetscFunctionReturn(0); 39463c7409f5SSatish Balay } 39473c7409f5SSatish Balay 39484a2ae208SSatish Balay #undef __FUNCT__ 39494a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix" 39509ab63eb5SSatish Balay /*@C 39513c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 39523c7409f5SSatish Balay SNES options in the database. 39533c7409f5SSatish Balay 3954c7afd0dbSLois Curfman McInnes Not Collective 3955c7afd0dbSLois Curfman McInnes 39563c7409f5SSatish Balay Input Parameter: 39573c7409f5SSatish Balay . snes - the SNES context 39583c7409f5SSatish Balay 39593c7409f5SSatish Balay Output Parameter: 39603c7409f5SSatish Balay . prefix - pointer to the prefix string used 39613c7409f5SSatish Balay 39624ef407dbSRichard Tran Mills Notes: On the fortran side, the user should pass in a string 'prefix' of 39639ab63eb5SSatish Balay sufficient length to hold the prefix. 39649ab63eb5SSatish Balay 396536851e7fSLois Curfman McInnes Level: advanced 396636851e7fSLois Curfman McInnes 39673c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database 3968a86d99e1SLois Curfman McInnes 3969a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix() 39703c7409f5SSatish Balay @*/ 39717087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 39723c7409f5SSatish Balay { 3973dfbe8321SBarry Smith PetscErrorCode ierr; 39743c7409f5SSatish Balay 39753a40ed3dSBarry Smith PetscFunctionBegin; 39760700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3977639f9d9dSBarry Smith ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr); 39783a40ed3dSBarry Smith PetscFunctionReturn(0); 39793c7409f5SSatish Balay } 39803c7409f5SSatish Balay 3981b2002411SLois Curfman McInnes 39824a2ae208SSatish Balay #undef __FUNCT__ 39834a2ae208SSatish Balay #define __FUNCT__ "SNESRegister" 39843cea93caSBarry Smith /*@C 39853cea93caSBarry Smith SNESRegister - See SNESRegisterDynamic() 39863cea93caSBarry Smith 39877f6c08e0SMatthew Knepley Level: advanced 39883cea93caSBarry Smith @*/ 39897087cfbeSBarry Smith PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES)) 3990b2002411SLois Curfman McInnes { 3991e2d1d2b7SBarry Smith char fullname[PETSC_MAX_PATH_LEN]; 3992dfbe8321SBarry Smith PetscErrorCode ierr; 3993b2002411SLois Curfman McInnes 3994b2002411SLois Curfman McInnes PetscFunctionBegin; 3995b0a32e0cSBarry Smith ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr); 3996c134de8dSSatish Balay ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr); 3997b2002411SLois Curfman McInnes PetscFunctionReturn(0); 3998b2002411SLois Curfman McInnes } 3999da9b6338SBarry Smith 4000da9b6338SBarry Smith #undef __FUNCT__ 4001da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin" 40027087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 4003da9b6338SBarry Smith { 4004dfbe8321SBarry Smith PetscErrorCode ierr; 400577431f27SBarry Smith PetscInt N,i,j; 4006da9b6338SBarry Smith Vec u,uh,fh; 4007da9b6338SBarry Smith PetscScalar value; 4008da9b6338SBarry Smith PetscReal norm; 4009da9b6338SBarry Smith 4010da9b6338SBarry Smith PetscFunctionBegin; 4011da9b6338SBarry Smith ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr); 4012da9b6338SBarry Smith ierr = VecDuplicate(u,&uh);CHKERRQ(ierr); 4013da9b6338SBarry Smith ierr = VecDuplicate(u,&fh);CHKERRQ(ierr); 4014da9b6338SBarry Smith 4015da9b6338SBarry Smith /* currently only works for sequential */ 4016da9b6338SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n"); 4017da9b6338SBarry Smith ierr = VecGetSize(u,&N);CHKERRQ(ierr); 4018da9b6338SBarry Smith for (i=0; i<N; i++) { 4019da9b6338SBarry Smith ierr = VecCopy(u,uh);CHKERRQ(ierr); 402077431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr); 4021da9b6338SBarry Smith for (j=-10; j<11; j++) { 4022ccae9161SBarry Smith value = PetscSign(j)*exp(PetscAbs(j)-10.0); 4023da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 40243ab0aad5SBarry Smith ierr = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr); 4025da9b6338SBarry Smith ierr = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr); 402677431f27SBarry Smith ierr = PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);CHKERRQ(ierr); 4027da9b6338SBarry Smith value = -value; 4028da9b6338SBarry Smith ierr = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr); 4029da9b6338SBarry Smith } 4030da9b6338SBarry Smith } 40316bf464f9SBarry Smith ierr = VecDestroy(&uh);CHKERRQ(ierr); 40326bf464f9SBarry Smith ierr = VecDestroy(&fh);CHKERRQ(ierr); 4033da9b6338SBarry Smith PetscFunctionReturn(0); 4034da9b6338SBarry Smith } 403571f87433Sdalcinl 403671f87433Sdalcinl #undef __FUNCT__ 4037fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW" 403871f87433Sdalcinl /*@ 4039fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 404071f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 404171f87433Sdalcinl Newton method. 404271f87433Sdalcinl 40433f9fe445SBarry Smith Logically Collective on SNES 404471f87433Sdalcinl 404571f87433Sdalcinl Input Parameters: 404671f87433Sdalcinl + snes - SNES context 404771f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 404871f87433Sdalcinl 404964ba62caSBarry Smith Options Database: 405064ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 405164ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 405264ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 405364ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 405464ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 405564ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 405664ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 405764ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 405864ba62caSBarry Smith 405971f87433Sdalcinl Notes: 406071f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 406171f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 406271f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 406371f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 406471f87433Sdalcinl solver. 406571f87433Sdalcinl 406671f87433Sdalcinl Level: advanced 406771f87433Sdalcinl 406871f87433Sdalcinl Reference: 406971f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 407071f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 407171f87433Sdalcinl 407271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 407371f87433Sdalcinl 4074fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 407571f87433Sdalcinl @*/ 40767087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 407771f87433Sdalcinl { 407871f87433Sdalcinl PetscFunctionBegin; 40790700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4080acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 408171f87433Sdalcinl snes->ksp_ewconv = flag; 408271f87433Sdalcinl PetscFunctionReturn(0); 408371f87433Sdalcinl } 408471f87433Sdalcinl 408571f87433Sdalcinl #undef __FUNCT__ 4086fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW" 408771f87433Sdalcinl /*@ 4088fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 408971f87433Sdalcinl for computing relative tolerance for linear solvers within an 409071f87433Sdalcinl inexact Newton method. 409171f87433Sdalcinl 409271f87433Sdalcinl Not Collective 409371f87433Sdalcinl 409471f87433Sdalcinl Input Parameter: 409571f87433Sdalcinl . snes - SNES context 409671f87433Sdalcinl 409771f87433Sdalcinl Output Parameter: 409871f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 409971f87433Sdalcinl 410071f87433Sdalcinl Notes: 410171f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 410271f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 410371f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 410471f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 410571f87433Sdalcinl solver. 410671f87433Sdalcinl 410771f87433Sdalcinl Level: advanced 410871f87433Sdalcinl 410971f87433Sdalcinl Reference: 411071f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 411171f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 411271f87433Sdalcinl 411371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton 411471f87433Sdalcinl 4115fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW() 411671f87433Sdalcinl @*/ 41177087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 411871f87433Sdalcinl { 411971f87433Sdalcinl PetscFunctionBegin; 41200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 412171f87433Sdalcinl PetscValidPointer(flag,2); 412271f87433Sdalcinl *flag = snes->ksp_ewconv; 412371f87433Sdalcinl PetscFunctionReturn(0); 412471f87433Sdalcinl } 412571f87433Sdalcinl 412671f87433Sdalcinl #undef __FUNCT__ 4127fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW" 412871f87433Sdalcinl /*@ 4129fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 413071f87433Sdalcinl convergence criteria for the linear solvers within an inexact 413171f87433Sdalcinl Newton method. 413271f87433Sdalcinl 41333f9fe445SBarry Smith Logically Collective on SNES 413471f87433Sdalcinl 413571f87433Sdalcinl Input Parameters: 413671f87433Sdalcinl + snes - SNES context 413771f87433Sdalcinl . version - version 1, 2 (default is 2) or 3 413871f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 413971f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 414071f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 414171f87433Sdalcinl (0 <= gamma2 <= 1) 414271f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 414371f87433Sdalcinl . alpha2 - power for safeguard 414471f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 414571f87433Sdalcinl 414671f87433Sdalcinl Note: 414771f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 414871f87433Sdalcinl 414971f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 415071f87433Sdalcinl 415171f87433Sdalcinl Level: advanced 415271f87433Sdalcinl 415371f87433Sdalcinl Reference: 415471f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 415571f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 415671f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 415771f87433Sdalcinl 415871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters 415971f87433Sdalcinl 4160fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW() 416171f87433Sdalcinl @*/ 41627087cfbeSBarry Smith PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max, 416371f87433Sdalcinl PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 416471f87433Sdalcinl { 4165fa9f3622SBarry Smith SNESKSPEW *kctx; 416671f87433Sdalcinl PetscFunctionBegin; 41670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4168fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4169e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 4170c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 4171c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 4172c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 4173c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 4174c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 4175c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 4176c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 417771f87433Sdalcinl 417871f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 417971f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 418071f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 418171f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 418271f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 418371f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 418471f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 418571f87433Sdalcinl 418671f87433Sdalcinl if (kctx->version < 1 || kctx->version > 3) { 4187e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version); 418871f87433Sdalcinl } 418971f87433Sdalcinl if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) { 4190e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0); 419171f87433Sdalcinl } 419271f87433Sdalcinl if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) { 4193e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max); 419471f87433Sdalcinl } 419571f87433Sdalcinl if (kctx->gamma < 0.0 || kctx->gamma > 1.0) { 4196e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma); 419771f87433Sdalcinl } 419871f87433Sdalcinl if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) { 4199e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha); 420071f87433Sdalcinl } 420171f87433Sdalcinl if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) { 4202e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold); 420371f87433Sdalcinl } 420471f87433Sdalcinl PetscFunctionReturn(0); 420571f87433Sdalcinl } 420671f87433Sdalcinl 420771f87433Sdalcinl #undef __FUNCT__ 4208fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW" 420971f87433Sdalcinl /*@ 4210fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 421171f87433Sdalcinl convergence criteria for the linear solvers within an inexact 421271f87433Sdalcinl Newton method. 421371f87433Sdalcinl 421471f87433Sdalcinl Not Collective 421571f87433Sdalcinl 421671f87433Sdalcinl Input Parameters: 421771f87433Sdalcinl snes - SNES context 421871f87433Sdalcinl 421971f87433Sdalcinl Output Parameters: 422071f87433Sdalcinl + version - version 1, 2 (default is 2) or 3 422171f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 422271f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 422371f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 422471f87433Sdalcinl (0 <= gamma2 <= 1) 422571f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 422671f87433Sdalcinl . alpha2 - power for safeguard 422771f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 422871f87433Sdalcinl 422971f87433Sdalcinl Level: advanced 423071f87433Sdalcinl 423171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters 423271f87433Sdalcinl 4233fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW() 423471f87433Sdalcinl @*/ 42357087cfbeSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max, 423671f87433Sdalcinl PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 423771f87433Sdalcinl { 4238fa9f3622SBarry Smith SNESKSPEW *kctx; 423971f87433Sdalcinl PetscFunctionBegin; 42400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4241fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4242e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 424371f87433Sdalcinl if(version) *version = kctx->version; 424471f87433Sdalcinl if(rtol_0) *rtol_0 = kctx->rtol_0; 424571f87433Sdalcinl if(rtol_max) *rtol_max = kctx->rtol_max; 424671f87433Sdalcinl if(gamma) *gamma = kctx->gamma; 424771f87433Sdalcinl if(alpha) *alpha = kctx->alpha; 424871f87433Sdalcinl if(alpha2) *alpha2 = kctx->alpha2; 424971f87433Sdalcinl if(threshold) *threshold = kctx->threshold; 425071f87433Sdalcinl PetscFunctionReturn(0); 425171f87433Sdalcinl } 425271f87433Sdalcinl 425371f87433Sdalcinl #undef __FUNCT__ 4254fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve" 4255fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x) 425671f87433Sdalcinl { 425771f87433Sdalcinl PetscErrorCode ierr; 4258fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 425971f87433Sdalcinl PetscReal rtol=PETSC_DEFAULT,stol; 426071f87433Sdalcinl 426171f87433Sdalcinl PetscFunctionBegin; 4262e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 426371f87433Sdalcinl if (!snes->iter) { /* first time in, so use the original user rtol */ 426471f87433Sdalcinl rtol = kctx->rtol_0; 426571f87433Sdalcinl } else { 426671f87433Sdalcinl if (kctx->version == 1) { 426771f87433Sdalcinl rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last; 426871f87433Sdalcinl if (rtol < 0.0) rtol = -rtol; 426971f87433Sdalcinl stol = pow(kctx->rtol_last,kctx->alpha2); 427071f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 427171f87433Sdalcinl } else if (kctx->version == 2) { 427271f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 427371f87433Sdalcinl stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha); 427471f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 427571f87433Sdalcinl } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */ 427671f87433Sdalcinl rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha); 427771f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 427871f87433Sdalcinl stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha); 427971f87433Sdalcinl stol = PetscMax(rtol,stol); 428071f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 428171f87433Sdalcinl /* safeguard: avoid oversolving */ 428271f87433Sdalcinl stol = kctx->gamma*(snes->ttol)/snes->norm; 428371f87433Sdalcinl stol = PetscMax(rtol,stol); 428471f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 4285e32f2f54SBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version); 428671f87433Sdalcinl } 428771f87433Sdalcinl /* safeguard: avoid rtol greater than one */ 428871f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 428971f87433Sdalcinl ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); 429071f87433Sdalcinl ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr); 429171f87433Sdalcinl PetscFunctionReturn(0); 429271f87433Sdalcinl } 429371f87433Sdalcinl 429471f87433Sdalcinl #undef __FUNCT__ 4295fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve" 4296fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x) 429771f87433Sdalcinl { 429871f87433Sdalcinl PetscErrorCode ierr; 4299fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 430071f87433Sdalcinl PCSide pcside; 430171f87433Sdalcinl Vec lres; 430271f87433Sdalcinl 430371f87433Sdalcinl PetscFunctionBegin; 4304e32f2f54SBarry Smith if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists"); 430571f87433Sdalcinl ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr); 430671f87433Sdalcinl ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr); 430771f87433Sdalcinl if (kctx->version == 1) { 4308b037da10SBarry Smith ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr); 430971f87433Sdalcinl if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */ 431071f87433Sdalcinl /* KSP residual is true linear residual */ 431171f87433Sdalcinl ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr); 431271f87433Sdalcinl } else { 431371f87433Sdalcinl /* KSP residual is preconditioned residual */ 431471f87433Sdalcinl /* compute true linear residual norm */ 431571f87433Sdalcinl ierr = VecDuplicate(b,&lres);CHKERRQ(ierr); 431671f87433Sdalcinl ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr); 431771f87433Sdalcinl ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr); 431871f87433Sdalcinl ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr); 43196bf464f9SBarry Smith ierr = VecDestroy(&lres);CHKERRQ(ierr); 432071f87433Sdalcinl } 432171f87433Sdalcinl } 432271f87433Sdalcinl PetscFunctionReturn(0); 432371f87433Sdalcinl } 432471f87433Sdalcinl 432571f87433Sdalcinl #undef __FUNCT__ 432671f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve" 432771f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x) 432871f87433Sdalcinl { 432971f87433Sdalcinl PetscErrorCode ierr; 433071f87433Sdalcinl 433171f87433Sdalcinl PetscFunctionBegin; 4332fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr); } 433371f87433Sdalcinl ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); 4334fa9f3622SBarry Smith if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); } 433571f87433Sdalcinl PetscFunctionReturn(0); 433671f87433Sdalcinl } 43376c699258SBarry Smith 43386c699258SBarry Smith #undef __FUNCT__ 43396c699258SBarry Smith #define __FUNCT__ "SNESSetDM" 43406c699258SBarry Smith /*@ 43416c699258SBarry Smith SNESSetDM - Sets the DM that may be used by some preconditioners 43426c699258SBarry Smith 43433f9fe445SBarry Smith Logically Collective on SNES 43446c699258SBarry Smith 43456c699258SBarry Smith Input Parameters: 43466c699258SBarry Smith + snes - the preconditioner context 43476c699258SBarry Smith - dm - the dm 43486c699258SBarry Smith 43496c699258SBarry Smith Level: intermediate 43506c699258SBarry Smith 43516c699258SBarry Smith 43526c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM() 43536c699258SBarry Smith @*/ 43547087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 43556c699258SBarry Smith { 43566c699258SBarry Smith PetscErrorCode ierr; 4357345fed2cSBarry Smith KSP ksp; 43586cab3a1bSJed Brown SNESDM sdm; 43596c699258SBarry Smith 43606c699258SBarry Smith PetscFunctionBegin; 43610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4362d0660788SBarry Smith if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 43636cab3a1bSJed Brown if (snes->dm) { /* Move the SNESDM context over to the new DM unless the new DM already has one */ 43646cab3a1bSJed Brown PetscContainer oldcontainer,container; 43656cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr); 43666cab3a1bSJed Brown ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr); 43676cab3a1bSJed Brown if (oldcontainer && !container) { 43686cab3a1bSJed Brown ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr); 43696cab3a1bSJed Brown ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr); 43706cab3a1bSJed Brown if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */ 43716cab3a1bSJed Brown sdm->originaldm = dm; 43726cab3a1bSJed Brown } 43736cab3a1bSJed Brown } 43746bf464f9SBarry Smith ierr = DMDestroy(&snes->dm);CHKERRQ(ierr); 43756cab3a1bSJed Brown } 43766c699258SBarry Smith snes->dm = dm; 4377345fed2cSBarry Smith ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr); 4378345fed2cSBarry Smith ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr); 4379f22f69f0SBarry Smith ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr); 43802c155ee1SBarry Smith if (snes->pc) { 43812c155ee1SBarry Smith ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr); 43822c155ee1SBarry Smith } 43836c699258SBarry Smith PetscFunctionReturn(0); 43846c699258SBarry Smith } 43856c699258SBarry Smith 43866c699258SBarry Smith #undef __FUNCT__ 43876c699258SBarry Smith #define __FUNCT__ "SNESGetDM" 43886c699258SBarry Smith /*@ 43896c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 43906c699258SBarry Smith 43913f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 43926c699258SBarry Smith 43936c699258SBarry Smith Input Parameter: 43946c699258SBarry Smith . snes - the preconditioner context 43956c699258SBarry Smith 43966c699258SBarry Smith Output Parameter: 43976c699258SBarry Smith . dm - the dm 43986c699258SBarry Smith 43996c699258SBarry Smith Level: intermediate 44006c699258SBarry Smith 44016c699258SBarry Smith 44026c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM() 44036c699258SBarry Smith @*/ 44047087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 44056c699258SBarry Smith { 44066cab3a1bSJed Brown PetscErrorCode ierr; 44076cab3a1bSJed Brown 44086c699258SBarry Smith PetscFunctionBegin; 44090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 44106cab3a1bSJed Brown if (!snes->dm) { 44116cab3a1bSJed Brown ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr); 44126cab3a1bSJed Brown } 44136c699258SBarry Smith *dm = snes->dm; 44146c699258SBarry Smith PetscFunctionReturn(0); 44156c699258SBarry Smith } 44160807856dSBarry Smith 441731823bd8SMatthew G Knepley #undef __FUNCT__ 441831823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC" 441931823bd8SMatthew G Knepley /*@ 4420fd4b34e9SJed Brown SNESSetPC - Sets the nonlinear preconditioner to be used. 442131823bd8SMatthew G Knepley 442231823bd8SMatthew G Knepley Collective on SNES 442331823bd8SMatthew G Knepley 442431823bd8SMatthew G Knepley Input Parameters: 442531823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 442631823bd8SMatthew G Knepley - pc - the preconditioner object 442731823bd8SMatthew G Knepley 442831823bd8SMatthew G Knepley Notes: 442931823bd8SMatthew G Knepley Use SNESGetPC() to retrieve the preconditioner context (for example, 443031823bd8SMatthew G Knepley to configure it using the API). 443131823bd8SMatthew G Knepley 443231823bd8SMatthew G Knepley Level: developer 443331823bd8SMatthew G Knepley 443431823bd8SMatthew G Knepley .keywords: SNES, set, precondition 443531823bd8SMatthew G Knepley .seealso: SNESGetPC() 443631823bd8SMatthew G Knepley @*/ 443731823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc) 443831823bd8SMatthew G Knepley { 443931823bd8SMatthew G Knepley PetscErrorCode ierr; 444031823bd8SMatthew G Knepley 444131823bd8SMatthew G Knepley PetscFunctionBegin; 444231823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 444331823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 444431823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 444531823bd8SMatthew G Knepley ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr); 4446bf11d3b6SBarry Smith ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr); 444731823bd8SMatthew G Knepley snes->pc = pc; 444831823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr); 444931823bd8SMatthew G Knepley PetscFunctionReturn(0); 445031823bd8SMatthew G Knepley } 445131823bd8SMatthew G Knepley 445231823bd8SMatthew G Knepley #undef __FUNCT__ 445331823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC" 445431823bd8SMatthew G Knepley /*@ 4455fd4b34e9SJed Brown SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC(). 445631823bd8SMatthew G Knepley 445731823bd8SMatthew G Knepley Not Collective 445831823bd8SMatthew G Knepley 445931823bd8SMatthew G Knepley Input Parameter: 446031823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 446131823bd8SMatthew G Knepley 446231823bd8SMatthew G Knepley Output Parameter: 446331823bd8SMatthew G Knepley . pc - preconditioner context 446431823bd8SMatthew G Knepley 446531823bd8SMatthew G Knepley Level: developer 446631823bd8SMatthew G Knepley 446731823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner 446831823bd8SMatthew G Knepley .seealso: SNESSetPC() 446931823bd8SMatthew G Knepley @*/ 447031823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc) 447131823bd8SMatthew G Knepley { 447231823bd8SMatthew G Knepley PetscErrorCode ierr; 4473a64e098fSPeter Brune const char *optionsprefix; 447431823bd8SMatthew G Knepley 447531823bd8SMatthew G Knepley PetscFunctionBegin; 447631823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 447731823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 447831823bd8SMatthew G Knepley if (!snes->pc) { 447931823bd8SMatthew G Knepley ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr); 44804a0c5b0cSMatthew G Knepley ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr); 448131823bd8SMatthew G Knepley ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr); 4482a64e098fSPeter Brune ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr); 4483a64e098fSPeter Brune ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr); 4484a64e098fSPeter Brune ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr); 448531823bd8SMatthew G Knepley } 448631823bd8SMatthew G Knepley *pc = snes->pc; 448731823bd8SMatthew G Knepley PetscFunctionReturn(0); 448831823bd8SMatthew G Knepley } 448931823bd8SMatthew G Knepley 44909e764e56SPeter Brune #undef __FUNCT__ 4491f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch" 44929e764e56SPeter Brune /*@ 44938141a3b9SPeter Brune SNESSetSNESLineSearch - Sets the linesearch on the SNES instance. 44949e764e56SPeter Brune 44959e764e56SPeter Brune Collective on SNES 44969e764e56SPeter Brune 44979e764e56SPeter Brune Input Parameters: 44989e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 44999e764e56SPeter Brune - linesearch - the linesearch object 45009e764e56SPeter Brune 45019e764e56SPeter Brune Notes: 4502f1c6b773SPeter Brune Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example, 45039e764e56SPeter Brune to configure it using the API). 45049e764e56SPeter Brune 45059e764e56SPeter Brune Level: developer 45069e764e56SPeter Brune 45079e764e56SPeter Brune .keywords: SNES, set, linesearch 4508f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch() 45099e764e56SPeter Brune @*/ 4510f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch) 45119e764e56SPeter Brune { 45129e764e56SPeter Brune PetscErrorCode ierr; 45139e764e56SPeter Brune 45149e764e56SPeter Brune PetscFunctionBegin; 45159e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4516f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 45179e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 45189e764e56SPeter Brune ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr); 4519f1c6b773SPeter Brune ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr); 45209e764e56SPeter Brune snes->linesearch = linesearch; 45219e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 45229e764e56SPeter Brune PetscFunctionReturn(0); 45239e764e56SPeter Brune } 45249e764e56SPeter Brune 45259e764e56SPeter Brune #undef __FUNCT__ 4526f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch" 4527ea5d4fccSPeter Brune /*@C 45288141a3b9SPeter Brune SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 45298141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 45309e764e56SPeter Brune 45319e764e56SPeter Brune Not Collective 45329e764e56SPeter Brune 45339e764e56SPeter Brune Input Parameter: 45349e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 45359e764e56SPeter Brune 45369e764e56SPeter Brune Output Parameter: 45379e764e56SPeter Brune . linesearch - linesearch context 45389e764e56SPeter Brune 45399e764e56SPeter Brune Level: developer 45409e764e56SPeter Brune 45419e764e56SPeter Brune .keywords: SNES, get, linesearch 4542f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch() 45439e764e56SPeter Brune @*/ 4544f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch) 45459e764e56SPeter Brune { 45469e764e56SPeter Brune PetscErrorCode ierr; 45479e764e56SPeter Brune const char *optionsprefix; 45489e764e56SPeter Brune 45499e764e56SPeter Brune PetscFunctionBegin; 45509e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 45519e764e56SPeter Brune PetscValidPointer(linesearch, 2); 45529e764e56SPeter Brune if (!snes->linesearch) { 45539e764e56SPeter Brune ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr); 4554f1c6b773SPeter Brune ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr); 4555f1c6b773SPeter Brune ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr); 4556b1dca40bSPeter Brune ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr); 45579e764e56SPeter Brune ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr); 45589e764e56SPeter Brune ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr); 45599e764e56SPeter Brune } 45609e764e56SPeter Brune *linesearch = snes->linesearch; 45619e764e56SPeter Brune PetscFunctionReturn(0); 45629e764e56SPeter Brune } 45639e764e56SPeter Brune 456469b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4565c6db04a5SJed Brown #include <mex.h> 456669b4f73cSBarry Smith 45678f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext; 45688f6e6473SBarry Smith 45690807856dSBarry Smith #undef __FUNCT__ 45700807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab" 45710807856dSBarry Smith /* 45720807856dSBarry Smith SNESComputeFunction_Matlab - Calls the function that has been set with 45730807856dSBarry Smith SNESSetFunctionMatlab(). 45740807856dSBarry Smith 45750807856dSBarry Smith Collective on SNES 45760807856dSBarry Smith 45770807856dSBarry Smith Input Parameters: 45780807856dSBarry Smith + snes - the SNES context 45790807856dSBarry Smith - x - input vector 45800807856dSBarry Smith 45810807856dSBarry Smith Output Parameter: 45820807856dSBarry Smith . y - function vector, as set by SNESSetFunction() 45830807856dSBarry Smith 45840807856dSBarry Smith Notes: 45850807856dSBarry Smith SNESComputeFunction() is typically used within nonlinear solvers 45860807856dSBarry Smith implementations, so most users would not generally call this routine 45870807856dSBarry Smith themselves. 45880807856dSBarry Smith 45890807856dSBarry Smith Level: developer 45900807856dSBarry Smith 45910807856dSBarry Smith .keywords: SNES, nonlinear, compute, function 45920807856dSBarry Smith 45930807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 459461b2408cSBarry Smith */ 45957087cfbeSBarry Smith PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx) 45960807856dSBarry Smith { 4597e650e774SBarry Smith PetscErrorCode ierr; 45988f6e6473SBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 45998f6e6473SBarry Smith int nlhs = 1,nrhs = 5; 46008f6e6473SBarry Smith mxArray *plhs[1],*prhs[5]; 460191621f2eSBarry Smith long long int lx = 0,ly = 0,ls = 0; 4602e650e774SBarry Smith 46030807856dSBarry Smith PetscFunctionBegin; 46040807856dSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 46050807856dSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 46060807856dSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 46070807856dSBarry Smith PetscCheckSameComm(snes,1,x,2); 46080807856dSBarry Smith PetscCheckSameComm(snes,1,y,3); 46090807856dSBarry Smith 46100807856dSBarry Smith /* call Matlab function in ctx with arguments x and y */ 4611e650e774SBarry Smith 461291621f2eSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4613e650e774SBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4614e650e774SBarry Smith ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr); 461591621f2eSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 461691621f2eSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 461791621f2eSBarry Smith prhs[2] = mxCreateDoubleScalar((double)ly); 46188f6e6473SBarry Smith prhs[3] = mxCreateString(sctx->funcname); 46198f6e6473SBarry Smith prhs[4] = sctx->ctx; 4620b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr); 4621e650e774SBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4622e650e774SBarry Smith mxDestroyArray(prhs[0]); 4623e650e774SBarry Smith mxDestroyArray(prhs[1]); 4624e650e774SBarry Smith mxDestroyArray(prhs[2]); 46258f6e6473SBarry Smith mxDestroyArray(prhs[3]); 4626e650e774SBarry Smith mxDestroyArray(plhs[0]); 46270807856dSBarry Smith PetscFunctionReturn(0); 46280807856dSBarry Smith } 46290807856dSBarry Smith 46300807856dSBarry Smith 46310807856dSBarry Smith #undef __FUNCT__ 46320807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab" 463361b2408cSBarry Smith /* 46340807856dSBarry Smith SNESSetFunctionMatlab - Sets the function evaluation routine and function 46350807856dSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4636e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 46370807856dSBarry Smith 46380807856dSBarry Smith Logically Collective on SNES 46390807856dSBarry Smith 46400807856dSBarry Smith Input Parameters: 46410807856dSBarry Smith + snes - the SNES context 46420807856dSBarry Smith . r - vector to store function value 46430807856dSBarry Smith - func - function evaluation routine 46440807856dSBarry Smith 46450807856dSBarry Smith Calling sequence of func: 464661b2408cSBarry Smith $ func (SNES snes,Vec x,Vec f,void *ctx); 46470807856dSBarry Smith 46480807856dSBarry Smith 46490807856dSBarry Smith Notes: 46500807856dSBarry Smith The Newton-like methods typically solve linear systems of the form 46510807856dSBarry Smith $ f'(x) x = -f(x), 46520807856dSBarry Smith where f'(x) denotes the Jacobian matrix and f(x) is the function. 46530807856dSBarry Smith 46540807856dSBarry Smith Level: beginner 46550807856dSBarry Smith 46560807856dSBarry Smith .keywords: SNES, nonlinear, set, function 46570807856dSBarry Smith 46580807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 465961b2408cSBarry Smith */ 46607087cfbeSBarry Smith PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx) 46610807856dSBarry Smith { 46620807856dSBarry Smith PetscErrorCode ierr; 46638f6e6473SBarry Smith SNESMatlabContext *sctx; 46640807856dSBarry Smith 46650807856dSBarry Smith PetscFunctionBegin; 46668f6e6473SBarry Smith /* currently sctx is memory bleed */ 46678f6e6473SBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 46688f6e6473SBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 46698f6e6473SBarry Smith /* 46708f6e6473SBarry Smith This should work, but it doesn't 46718f6e6473SBarry Smith sctx->ctx = ctx; 46728f6e6473SBarry Smith mexMakeArrayPersistent(sctx->ctx); 46738f6e6473SBarry Smith */ 46748f6e6473SBarry Smith sctx->ctx = mxDuplicateArray(ctx); 46758f6e6473SBarry Smith ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr); 46760807856dSBarry Smith PetscFunctionReturn(0); 46770807856dSBarry Smith } 467869b4f73cSBarry Smith 467961b2408cSBarry Smith #undef __FUNCT__ 468061b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab" 468161b2408cSBarry Smith /* 468261b2408cSBarry Smith SNESComputeJacobian_Matlab - Calls the function that has been set with 468361b2408cSBarry Smith SNESSetJacobianMatlab(). 468461b2408cSBarry Smith 468561b2408cSBarry Smith Collective on SNES 468661b2408cSBarry Smith 468761b2408cSBarry Smith Input Parameters: 468861b2408cSBarry Smith + snes - the SNES context 468961b2408cSBarry Smith . x - input vector 469061b2408cSBarry Smith . A, B - the matrices 469161b2408cSBarry Smith - ctx - user context 469261b2408cSBarry Smith 469361b2408cSBarry Smith Output Parameter: 469461b2408cSBarry Smith . flag - structure of the matrix 469561b2408cSBarry Smith 469661b2408cSBarry Smith Level: developer 469761b2408cSBarry Smith 469861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function 469961b2408cSBarry Smith 470061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction() 470161b2408cSBarry Smith @*/ 47027087cfbeSBarry Smith PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx) 470361b2408cSBarry Smith { 470461b2408cSBarry Smith PetscErrorCode ierr; 470561b2408cSBarry Smith SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 470661b2408cSBarry Smith int nlhs = 2,nrhs = 6; 470761b2408cSBarry Smith mxArray *plhs[2],*prhs[6]; 470861b2408cSBarry Smith long long int lx = 0,lA = 0,ls = 0, lB = 0; 470961b2408cSBarry Smith 471061b2408cSBarry Smith PetscFunctionBegin; 471161b2408cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 471261b2408cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 471361b2408cSBarry Smith 471461b2408cSBarry Smith /* call Matlab function in ctx with arguments x and y */ 471561b2408cSBarry Smith 471661b2408cSBarry Smith ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 471761b2408cSBarry Smith ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 471861b2408cSBarry Smith ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr); 471961b2408cSBarry Smith ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr); 472061b2408cSBarry Smith prhs[0] = mxCreateDoubleScalar((double)ls); 472161b2408cSBarry Smith prhs[1] = mxCreateDoubleScalar((double)lx); 472261b2408cSBarry Smith prhs[2] = mxCreateDoubleScalar((double)lA); 472361b2408cSBarry Smith prhs[3] = mxCreateDoubleScalar((double)lB); 472461b2408cSBarry Smith prhs[4] = mxCreateString(sctx->funcname); 472561b2408cSBarry Smith prhs[5] = sctx->ctx; 4726b807a863SBarry Smith ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr); 472761b2408cSBarry Smith ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 472861b2408cSBarry Smith *flag = (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr); 472961b2408cSBarry Smith mxDestroyArray(prhs[0]); 473061b2408cSBarry Smith mxDestroyArray(prhs[1]); 473161b2408cSBarry Smith mxDestroyArray(prhs[2]); 473261b2408cSBarry Smith mxDestroyArray(prhs[3]); 473361b2408cSBarry Smith mxDestroyArray(prhs[4]); 473461b2408cSBarry Smith mxDestroyArray(plhs[0]); 473561b2408cSBarry Smith mxDestroyArray(plhs[1]); 473661b2408cSBarry Smith PetscFunctionReturn(0); 473761b2408cSBarry Smith } 473861b2408cSBarry Smith 473961b2408cSBarry Smith 474061b2408cSBarry Smith #undef __FUNCT__ 474161b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab" 474261b2408cSBarry Smith /* 474361b2408cSBarry Smith SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices 474461b2408cSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 4745e3c5b3baSBarry Smith equations from MATLAB. Here the function is a string containing the name of a MATLAB function 474661b2408cSBarry Smith 474761b2408cSBarry Smith Logically Collective on SNES 474861b2408cSBarry Smith 474961b2408cSBarry Smith Input Parameters: 475061b2408cSBarry Smith + snes - the SNES context 475161b2408cSBarry Smith . A,B - Jacobian matrices 475261b2408cSBarry Smith . func - function evaluation routine 475361b2408cSBarry Smith - ctx - user context 475461b2408cSBarry Smith 475561b2408cSBarry Smith Calling sequence of func: 475661b2408cSBarry Smith $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx); 475761b2408cSBarry Smith 475861b2408cSBarry Smith 475961b2408cSBarry Smith Level: developer 476061b2408cSBarry Smith 476161b2408cSBarry Smith .keywords: SNES, nonlinear, set, function 476261b2408cSBarry Smith 476361b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 476461b2408cSBarry Smith */ 47657087cfbeSBarry Smith PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx) 476661b2408cSBarry Smith { 476761b2408cSBarry Smith PetscErrorCode ierr; 476861b2408cSBarry Smith SNESMatlabContext *sctx; 476961b2408cSBarry Smith 477061b2408cSBarry Smith PetscFunctionBegin; 477161b2408cSBarry Smith /* currently sctx is memory bleed */ 477261b2408cSBarry Smith ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 477361b2408cSBarry Smith ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 477461b2408cSBarry Smith /* 477561b2408cSBarry Smith This should work, but it doesn't 477661b2408cSBarry Smith sctx->ctx = ctx; 477761b2408cSBarry Smith mexMakeArrayPersistent(sctx->ctx); 477861b2408cSBarry Smith */ 477961b2408cSBarry Smith sctx->ctx = mxDuplicateArray(ctx); 478061b2408cSBarry Smith ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr); 478161b2408cSBarry Smith PetscFunctionReturn(0); 478261b2408cSBarry Smith } 478369b4f73cSBarry Smith 4784f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4785f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab" 4786f9eb7ae2SShri Abhyankar /* 4787f9eb7ae2SShri Abhyankar SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab(). 4788f9eb7ae2SShri Abhyankar 4789f9eb7ae2SShri Abhyankar Collective on SNES 4790f9eb7ae2SShri Abhyankar 4791f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction() 4792f9eb7ae2SShri Abhyankar @*/ 47937087cfbeSBarry Smith PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx) 4794f9eb7ae2SShri Abhyankar { 4795f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 479648f37e70SShri Abhyankar SNESMatlabContext *sctx = (SNESMatlabContext *)ctx; 4797f9eb7ae2SShri Abhyankar int nlhs = 1,nrhs = 6; 4798f9eb7ae2SShri Abhyankar mxArray *plhs[1],*prhs[6]; 4799f9eb7ae2SShri Abhyankar long long int lx = 0,ls = 0; 4800f9eb7ae2SShri Abhyankar Vec x=snes->vec_sol; 4801f9eb7ae2SShri Abhyankar 4802f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4803f9eb7ae2SShri Abhyankar PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4804f9eb7ae2SShri Abhyankar 4805f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr); 4806f9eb7ae2SShri Abhyankar ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr); 4807f9eb7ae2SShri Abhyankar prhs[0] = mxCreateDoubleScalar((double)ls); 4808f9eb7ae2SShri Abhyankar prhs[1] = mxCreateDoubleScalar((double)it); 4809f9eb7ae2SShri Abhyankar prhs[2] = mxCreateDoubleScalar((double)fnorm); 4810f9eb7ae2SShri Abhyankar prhs[3] = mxCreateDoubleScalar((double)lx); 4811f9eb7ae2SShri Abhyankar prhs[4] = mxCreateString(sctx->funcname); 4812f9eb7ae2SShri Abhyankar prhs[5] = sctx->ctx; 4813f9eb7ae2SShri Abhyankar ierr = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr); 4814f9eb7ae2SShri Abhyankar ierr = mxGetScalar(plhs[0]);CHKERRQ(ierr); 4815f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[0]); 4816f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[1]); 4817f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[2]); 4818f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[3]); 4819f9eb7ae2SShri Abhyankar mxDestroyArray(prhs[4]); 4820f9eb7ae2SShri Abhyankar mxDestroyArray(plhs[0]); 4821f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4822f9eb7ae2SShri Abhyankar } 4823f9eb7ae2SShri Abhyankar 4824f9eb7ae2SShri Abhyankar 4825f9eb7ae2SShri Abhyankar #undef __FUNCT__ 4826f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab" 4827f9eb7ae2SShri Abhyankar /* 4828e3c5b3baSBarry Smith SNESMonitorSetMatlab - Sets the monitor function from MATLAB 4829f9eb7ae2SShri Abhyankar 4830f9eb7ae2SShri Abhyankar Level: developer 4831f9eb7ae2SShri Abhyankar 4832f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function 4833f9eb7ae2SShri Abhyankar 4834f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction() 4835f9eb7ae2SShri Abhyankar */ 48367087cfbeSBarry Smith PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx) 4837f9eb7ae2SShri Abhyankar { 4838f9eb7ae2SShri Abhyankar PetscErrorCode ierr; 4839f9eb7ae2SShri Abhyankar SNESMatlabContext *sctx; 4840f9eb7ae2SShri Abhyankar 4841f9eb7ae2SShri Abhyankar PetscFunctionBegin; 4842f9eb7ae2SShri Abhyankar /* currently sctx is memory bleed */ 4843f9eb7ae2SShri Abhyankar ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr); 4844f9eb7ae2SShri Abhyankar ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr); 4845f9eb7ae2SShri Abhyankar /* 4846f9eb7ae2SShri Abhyankar This should work, but it doesn't 4847f9eb7ae2SShri Abhyankar sctx->ctx = ctx; 4848f9eb7ae2SShri Abhyankar mexMakeArrayPersistent(sctx->ctx); 4849f9eb7ae2SShri Abhyankar */ 4850f9eb7ae2SShri Abhyankar sctx->ctx = mxDuplicateArray(ctx); 4851f9eb7ae2SShri Abhyankar ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr); 4852f9eb7ae2SShri Abhyankar PetscFunctionReturn(0); 4853f9eb7ae2SShri Abhyankar } 4854f9eb7ae2SShri Abhyankar 485569b4f73cSBarry Smith #endif 4856